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
|
/*
* 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 (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _VNET_GEN_H
#define _VNET_GEN_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/vgen_stats.h>
#define VGEN_SUCCESS (0) /* successful return */
#define VGEN_FAILURE (-1) /* unsuccessful return */
#define VGEN_NUM_VER 1 /* max # of vgen versions */
#define VGEN_LOCAL 1 /* local ldc end-point */
#define VGEN_PEER 2 /* peer ldc end-point */
/* vgen_t flags */
#define VGEN_STOPPED 0x0
#define VGEN_STARTED 0x1
#define KMEM_FREE(_p) kmem_free((_p), sizeof (*(_p)))
#define VGEN_INIT_MCTAB_SIZE 16 /* initial size of multicast table */
#define READ_ENTER(x) rw_enter(x, RW_READER)
#define WRITE_ENTER(x) rw_enter(x, RW_WRITER)
#define RW_EXIT(x) rw_exit(x)
/* channel flags */
#define CHANNEL_ATTACHED 0x1
#define CHANNEL_STARTED 0x2
/* transmit return values */
#define VGEN_TX_SUCCESS 0 /* transmit success */
#define VGEN_TX_FAILURE 1 /* transmit failure */
#define VGEN_TX_NORESOURCES 2 /* out of tbufs/txds */
/* private descriptor flags */
#define VGEN_PRIV_DESC_FREE 0x0 /* desc is available */
#define VGEN_PRIV_DESC_BUSY 0x1 /* desc in use */
#define LDC_TO_VNET(ldcp) ((ldcp)->portp->vgenp->vnetp)
#define LDC_TO_VGEN(ldcp) ((ldcp)->portp->vgenp)
/* receive thread flags */
#define VGEN_WTHR_DATARCVD 0x01 /* data received */
#define VGEN_WTHR_STOP 0x02 /* stop worker thr request */
#define VGEN_WTHR_PROCESSING 0x04 /* worker thr awake & processing */
#define VGEN_LDC_MTU 64 /* ldc pkt transfer mtu */
#define VGEN_LDC_UP_DELAY 100 /* usec delay between ldc_up retries */
#define VGEN_LDC_CLOSE_DELAY 100 /* usec delay between ldc_cl retries */
#define VGEN_LDC_UNINIT_DELAY 100 /* usec delay between uninit retries */
#define VGEN_TXWD_INTERVAL 1000 /* tx watchdog freq in msec */
#define VGEN_TXWD_TIMEOUT 1000 /* tx watchdog timeout in msec */
#define VGEN_NUM_VMPOOLS 3 /* number of vio mblk pools */
#define VGEN_DBLK_SZ_128 128 /* data buffer size 128 bytes */
#define VGEN_DBLK_SZ_256 256 /* data buffer size 256 bytes */
#define VGEN_DBLK_SZ_2048 2048 /* data buffer size 2K bytes */
#define VGEN_NRBUFS 512 /* number of receive bufs */
#define VGEN_TXDBLK_SZ 2048 /* Tx data buffer size */
#define VGEN_NUM_DESCRIPTORS_MIN 128 /* min # of descriptors */
/*
* Number of rcv buffers in RxDringData mode
*/
#define VGEN_RXDRING_NRBUFS (vnet_num_descriptors * vgen_nrbufs_factor)
static struct ether_addr etherbroadcastaddr = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
/*
* MIB II broadcast/multicast packets
*/
#define IS_BROADCAST(ehp) \
(ether_cmp(&ehp->ether_dhost, ðerbroadcastaddr) == 0)
#define IS_MULTICAST(ehp) \
((ehp->ether_dhost.ether_addr_octet[0] & 01) == 1)
/*
* The handshake process consists of 5 phases defined below, with VH_PHASE0
* being the pre-handshake phase and VH_DONE is the phase to indicate
* successful completion of all phases. Each phase may have one to several
* handshake states which are required to complete successfully to move to the
* next phase. See functions vgen_handshake() and vgen_handshake_done() for
* more details.
*/
/* Handshake phases */
enum { VH_PHASE0, VH_PHASE1, VH_PHASE2, VH_PHASE3, VH_PHASE4, VH_DONE = 0x80 };
/* Handshake states */
enum {
VER_INFO_SENT = 0x1,
VER_ACK_RCVD = 0x2,
VER_INFO_RCVD = 0x4,
VER_ACK_SENT = 0x8,
VER_NEGOTIATED = (VER_ACK_RCVD | VER_ACK_SENT),
ATTR_INFO_SENT = 0x10,
ATTR_ACK_RCVD = 0x20,
ATTR_INFO_RCVD = 0x40,
ATTR_ACK_SENT = 0x80,
ATTR_INFO_EXCHANGED = (ATTR_ACK_RCVD | ATTR_ACK_SENT),
DRING_INFO_SENT = 0x100,
DRING_ACK_RCVD = 0x200,
DRING_INFO_RCVD = 0x400,
DRING_ACK_SENT = 0x800,
DRING_INFO_EXCHANGED = (DRING_ACK_RCVD | DRING_ACK_SENT),
RDX_INFO_SENT = 0x1000,
RDX_ACK_RCVD = 0x2000,
RDX_INFO_RCVD = 0x4000,
RDX_ACK_SENT = 0x8000,
RDX_EXCHANGED = (RDX_ACK_RCVD | RDX_ACK_SENT)
};
/* reset flags */
typedef enum {
VGEN_FLAG_EVT_RESET = 0x1, /* channel reset event */
VGEN_FLAG_NEED_LDCRESET = 0x2, /* need channel reset */
VGEN_FLAG_UNINIT = 0x4 /* channel tear down */
} vgen_reset_flags_t;
/* caller information needed in some code paths */
typedef enum {
VGEN_LDC_CB = 0x1, /* ldc callback handler */
VGEN_MSG_THR = 0x2, /* vio message worker thread */
VGEN_OTHER = 0x4 /* other threads - tx etc */
} vgen_caller_t;
/* get the address of next tbuf */
#define NEXTTBUF(ldcp, tbufp) (((tbufp) + 1) == (ldcp)->tbufendp \
? (ldcp)->tbufp : ((tbufp) + 1))
/* increment recv index */
#define INCR_RXI(i, ldcp) \
((i) = (((i) + 1) & ((ldcp)->num_rxds - 1)))
/* decrement recv index */
#define DECR_RXI(i, ldcp) \
((i) = (((i) - 1) & ((ldcp)->num_rxds - 1)))
/* increment tx index */
#define INCR_TXI(i, ldcp) \
((i) = (((i) + 1) & ((ldcp)->num_txds - 1)))
/* decrement tx index */
#define DECR_TXI(i, ldcp) \
((i) = (((i) - 1) & ((ldcp)->num_txds - 1)))
/* bounds check rx index */
#define CHECK_RXI(i, ldcp) \
(((i) >= 0) && ((i) < (ldcp)->num_rxds))
/* bounds check tx index */
#define CHECK_TXI(i, ldcp) \
(((i) >= 0) && ((i) < (ldcp)->num_txds))
#ifdef DEBUG
/* Error injection codes */
#define VGEN_ERR_HVER 0x1 /* handshake version */
#define VGEN_ERR_HTIMEOUT 0x2 /* handshake timeout */
#define VGEN_ERR_HSID 0x4 /* handshake session id */
#define VGEN_ERR_HSTATE 0x8 /* handshake state */
#define VGEN_ERR_TXTIMEOUT 0x10 /* tx timeout */
#define VGEN_ERR_RXLOST 0x20 /* rx lost pkts */
#endif
/* private descriptor */
typedef struct vgen_priv_desc {
uint64_t flags; /* flag bits */
vnet_public_desc_t *descp; /* associated public desc */
ldc_mem_handle_t memhandle; /* mem handle for data */
caddr_t datap; /* prealloc'd tx data buffer */
uint64_t datalen; /* total actual datalen */
uint64_t ncookies; /* num ldc_mem_cookies */
ldc_mem_cookie_t memcookie[MAX_COOKIES]; /* data cookies */
} vgen_private_desc_t;
/*
* Handshake parameters (per vio_mailbox.h) of each ldc end point, used
* during handshake negotiation.
*/
typedef struct vgen_handshake_params {
/* version specific params */
uint16_t ver_major; /* major version number */
uint16_t ver_minor; /* minor version number */
uint8_t dev_class; /* device class */
/* attributes specific params */
uint64_t mtu; /* max transfer unit size */
uint64_t addr; /* address of the device */
uint8_t addr_type; /* type of address */
uint8_t xfer_mode; /* SHM or PKT */
uint16_t ack_freq; /* dring data ack freq */
uint32_t physlink_update; /* physlink updates */
uint8_t dring_mode; /* Descriptor ring mode */
/* descriptor ring params */
uint32_t num_desc; /* # of descriptors in ring */
uint32_t desc_size; /* size of descriptor */
ldc_mem_cookie_t dring_cookie; /* desc ring cookie */
uint32_t dring_ncookies; /* # of dring cookies */
uint64_t dring_ident; /* ident=0 for INFO msg */
boolean_t dring_ready; /* dring ready flag */
} vgen_hparams_t;
/* version info */
typedef struct vgen_ver {
uint16_t ver_major; /* major version number */
uint16_t ver_minor; /* minor version number */
} vgen_ver_t;
/*
* vnet-protocol-version dependent function prototypes.
*/
typedef int (*vgen_ldctx_t) (void *, mblk_t *);
typedef void (*vgen_ldcrx_pktdata_t) (void *, void *, uint32_t);
typedef int (*vgen_ldcrx_dringdata_t) (void *, void *);
/*
* LDC end point abstraction in vnet. This structure holds all the information
* that is required to configure and use the Channel for data transfers with
* the peer LDC end point (vnet or vswitch), using VIO Protocol.
*/
typedef struct vgen_ldc {
struct vgen_port *portp; /* associated port */
/*
* Locks:
* locking hierarchy when more than one lock is held concurrently:
* cblock > rxlock > txlock > tclock.
*/
kmutex_t cblock; /* sync callback processing */
kmutex_t txlock; /* protect txd alloc */
kmutex_t tclock; /* tx reclaim lock */
kmutex_t wrlock; /* sync transmits */
kmutex_t rxlock; /* sync reception */
kmutex_t pollq_lock; /* sync polling and rxworker */
/*
* Channel and Handshake Info
*/
uint64_t ldc_id; /* channel number */
uint64_t ldc_handle; /* channel handle */
ldc_status_t ldc_status; /* channel status */
vgen_ver_t vgen_versions[VGEN_NUM_VER]; /* versions */
int hphase; /* handshake phase */
int hstate; /* handshake state bits */
link_state_t link_state; /* channel link state */
#ifdef VNET_IOC_DEBUG
boolean_t link_down_forced; /* forced link down */
#endif
uint32_t local_sid; /* local session id */
uint32_t peer_sid; /* session id of peer */
vgen_hparams_t local_hparams; /* local handshake params */
vgen_hparams_t peer_hparams; /* peer's handshake params */
timeout_id_t htid; /* handshake wd timeout id */
timeout_id_t cancel_htid; /* cancel handshake watchdog */
uint8_t dring_mtype; /* dring mem map type */
uint64_t *ldcmsg; /* msg buffer for ldc_read() */
uint64_t msglen; /* size of ldcmsg */
uint32_t flags; /* flags */
uint_t reset_in_progress; /* channel being reset */
uint32_t hretries; /* handshake retry count */
uint32_t ldc_reset_count; /* # of channel resets */
/*
* Transmit Specific Fields
*/
/* TX-Common (Used in both TxDring and RxDringData modes) */
uint32_t num_txds; /* # of descriptors */
uint32_t tx_dring_ncookies; /* # of dring cookies */
ldc_dring_handle_t tx_dring_handle; /* dring handle */
ldc_mem_cookie_t tx_dring_cookie; /* dring cookie */
uint32_t next_txi; /* free descriptor index */
caddr_t tx_datap; /* tx data area */
size_t tx_data_sz; /* size of data area */
size_t tx_dblk_sz; /* size of data blk */
timeout_id_t wd_tid; /* watchdog timeout id */
boolean_t tx_blocked; /* flow controlled */
clock_t tx_blocked_lbolt; /* flow controlled time */
boolean_t resched_peer; /* restart peer needed */
uint32_t resched_peer_txi; /* index to resched peer */
vgen_ldctx_t tx; /* transmit function */
vgen_ldctx_t tx_dringdata; /* dring transmit function */
/* TX-TxDring mode */
vnet_public_desc_t *txdp; /* exported dring */
vgen_private_desc_t *tbufp; /* dring associated resources */
vgen_private_desc_t *tbufendp; /* tbuf ring end */
vgen_private_desc_t *next_tbufp; /* free tbuf */
vgen_private_desc_t *cur_tbufp; /* reclaim tbuf */
uint32_t cur_txi; /* reclaim descrptor index */
uint64_t next_txseq; /* msg seqnum */
clock_t reclaim_lbolt; /* time of last reclaim */
/* TX-RxDringData mode */
uint32_t tx_data_ncookies; /* # of data cookies */
ldc_mem_handle_t tx_data_handle; /* mapped data handle */
ldc_mem_cookie_t *tx_data_cookie; /* mapped data cookies */
vnet_rx_dringdata_desc_t *mtxdp; /* mapped dring */
uint32_t dringdata_msgid; /* msg id */
/*
* Receive Specific Fields
*/
/* RX-Common (Used in both TxDring and RxDringData modes) */
uint32_t num_rxds; /* # of descriptors */
uint32_t rx_dring_ncookies; /* # of dring cookies */
ldc_dring_handle_t rx_dring_handle; /* dring handle */
ldc_mem_cookie_t rx_dring_cookie; /* dring cookie */
uint32_t next_rxi; /* free descriptor index */
vgen_ldcrx_dringdata_t rx_dringdata; /* dring rcv function */
vgen_ldcrx_pktdata_t rx_pktdata; /* raw data rcv function */
boolean_t polling_on; /* polling enabled ? */
/* RX-TxDring mode */
vnet_public_desc_t *mrxdp; /* mapped dring */
uint64_t next_rxseq; /* msg seqnum */
vio_multi_pool_t vmp; /* mblk pools */
uint32_t max_rxpool_size; /* max size of rxpool in use */
mblk_t *pollq_headp; /* head of pkts in pollq */
mblk_t *pollq_tailp; /* tail of pkts in pollq */
kthread_t *msg_thread; /* message thread */
uint32_t msg_thr_flags; /* message thread flags */
kmutex_t msg_thr_lock; /* lock for message thread */
kcondvar_t msg_thr_cv; /* cond.var for msg thread */
/* RX-RxDringData mode */
uint32_t num_rbufs; /* # of data bufs */
uint32_t rx_data_ncookies; /* # of data cookies */
ldc_mem_handle_t rx_data_handle; /* exported data handle */
ldc_mem_cookie_t *rx_data_cookie; /* exported data cookies */
vnet_rx_dringdata_desc_t *rxdp; /* exported dring */
vio_mblk_pool_t *rx_vmp; /* mblk pool */
vio_mblk_t **rxdp_to_vmp; /* descr to buf map tbl */
caddr_t rx_datap; /* mapped rx data area */
size_t rx_data_sz; /* size of mapped rx data */
size_t rx_dblk_sz; /* size of each rx data blk */
mblk_t *rx_pri_head; /* priority pkts head */
mblk_t *rx_pri_tail; /* priority pkts tail */
/* Channel Statistics */
vgen_stats_t stats; /* channel statistics */
kstat_t *ksp; /* channel kstats */
} vgen_ldc_t;
/* port information structure */
typedef struct vgen_port {
struct vgen_port *nextp; /* next port in the list */
struct vgen *vgenp; /* associated vgen_t */
int port_num; /* port number */
boolean_t is_vsw_port; /* connected to vswitch ? */
int num_ldcs; /* # of channels in this port */
uint64_t *ldc_ids; /* channel ids */
vgen_ldc_t *ldcp; /* list of ldcs for this port */
ether_addr_t macaddr; /* mac address of peer */
uint16_t pvid; /* port vlan id (untagged) */
uint16_t *vids; /* vlan ids (tagged) */
uint16_t nvids; /* # of vids */
mod_hash_t *vlan_hashp; /* vlan hash table */
uint32_t vlan_nchains; /* # of vlan hash chains */
uint32_t use_vsw_port; /* Use vsw_port or not */
uint32_t flags; /* status of this port */
vio_net_callbacks_t vcb; /* vnet callbacks */
vio_net_handle_t vhp; /* handle from vnet */
kmutex_t lock; /* synchornize ops */
} vgen_port_t;
/* port list structure */
typedef struct vgen_portlist {
vgen_port_t *headp; /* head of ports */
vgen_port_t *tailp; /* tail */
krwlock_t rwlock; /* sync access to the port list */
} vgen_portlist_t;
/* vgen instance information */
typedef struct vgen {
vnet_t *vnetp; /* associated vnet instance */
int instance; /* vnet instance */
dev_info_t *vnetdip; /* dip of vnet */
uint64_t regprop; /* "reg" property */
ether_addr_t macaddr; /* mac addr of vnet */
kmutex_t lock; /* synchornize ops */
int flags; /* flags */
vgen_portlist_t vgenports; /* Port List */
mdeg_node_spec_t *mdeg_parentp;
mdeg_handle_t mdeg_dev_hdl; /* mdeg cb handle for device */
mdeg_handle_t mdeg_port_hdl; /* mdeg cb handle for port */
vgen_port_t *vsw_portp; /* port connected to vsw */
struct ether_addr *mctab; /* multicast addr table */
uint32_t mcsize; /* allocated size of mctab */
uint32_t mccount; /* # of valid addrs in mctab */
ddi_taskq_t *rxp_taskq; /* VIO rx pool taskq */
uint32_t pri_num_types; /* # of priority eth types */
uint16_t *pri_types; /* priority eth types */
vio_mblk_pool_t *pri_tx_vmp; /* tx priority mblk pool */
uint32_t max_frame_size; /* max frame size supported */
uint32_t vsw_port_refcnt; /* refcnt for vsw_port */
boolean_t pls_negotiated; /* phys link state update ? */
link_state_t phys_link_state; /* physical link state */
} vgen_t;
#ifdef __cplusplus
}
#endif
#endif /* _VNET_GEN_H */
|