summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/nxge/nxge_hio.h
blob: 492da24d55c059986317ceecc9ea1ab2d576fc1f (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
/*
 * 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_HIO_H
#define	_SYS_NXGE_NXGE_HIO_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <nxge_mac.h>
#include <nxge_ipp.h>
#include <nxge_fflp.h>
#include <sys/mac_provider.h>

#define	isLDOMservice(nxge) \
	(nxge->environs == SOLARIS_SERVICE_DOMAIN)
#define	isLDOMguest(nxge) \
	(nxge->environs == SOLARIS_GUEST_DOMAIN)
#define	isLDOMs(nxge) \
	(isLDOMservice(nxge) || isLDOMguest(nxge))

#define	NXGE_HIO_SHARE_MIN_CHANNELS	2
#define	NXGE_HIO_SHARE_MAX_CHANNELS	2

/* ------------------------------------------------------------------ */
typedef uint8_t nx_rdc_t;
typedef uint8_t nx_tdc_t;

typedef uint64_t res_map_t;

typedef uint64_t hv_rv_t;

typedef hv_rv_t (*vr_assign)(uint64_t, uint64_t, uint32_t *);
typedef hv_rv_t (*vr_unassign)(uint32_t);
typedef hv_rv_t (*vr_getinfo)(uint32_t, uint64_t *, uint64_t *);

/* HV 2.0 API group functions */
typedef hv_rv_t (*vr_cfgh_assign)(uint64_t, uint64_t, uint64_t, uint32_t *);
typedef hv_rv_t (*vrlp_cfgh_conf)(uint64_t, uint64_t, uint64_t, uint64_t,
    uint64_t);
typedef hv_rv_t (*vrlp_cfgh_info)(uint64_t, uint64_t, uint64_t, uint64_t *,
    uint64_t *);


typedef struct {
	vr_assign	assign;		/* HV Major 1 interface */
	vr_cfgh_assign	cfgh_assign;	/* HV Major 2 interface */
	vr_unassign	unassign;
	vr_getinfo	getinfo;
} nxhv_vr_fp_t;

typedef hv_rv_t (*vrlp_conf)(uint64_t, uint64_t, uint64_t, uint64_t);
typedef hv_rv_t (*vrlp_info)(uint64_t, uint64_t, uint64_t *, uint64_t *);

typedef hv_rv_t (*dc_assign)(uint32_t, uint64_t, uint64_t *);
typedef hv_rv_t (*dc_unassign)(uint32_t, uint64_t);
typedef hv_rv_t (*dc_getstate)(uint32_t, uint64_t, uint64_t *);
typedef hv_rv_t (*dc_get_map)(uint32_t, uint64_t *);

typedef hv_rv_t (*dc_getinfo)(uint32_t, uint64_t, uint64_t *, uint64_t *);

typedef struct {
	dc_assign	assign;
	dc_unassign	unassign;
	dc_getstate	getstate;
	dc_get_map	get_map;

	vrlp_conf	lp_conf;	/* HV Major 1 interface */
	vrlp_info	lp_info;	/* HV Major 1 interface */
	vrlp_cfgh_conf	lp_cfgh_conf;	/* HV Major 2 interface */
	vrlp_cfgh_info	lp_cfgh_info;	/* HV Major 2 interface */
	dc_getinfo	getinfo;
} nxhv_dc_fp_t;

typedef struct {
	boolean_t	ldoms;
	nxhv_vr_fp_t	vr;
	nxhv_dc_fp_t	tx;
	nxhv_dc_fp_t	rx;
} nxhv_fp_t;

/* ------------------------------------------------------------------ */
#define	NXGE_VR_SR_MAX		8 /* There are 8 subregions (SR). */

typedef enum {
	NXGE_HIO_TYPE_SERVICE = 0x80,	/* We are a service domain driver. */
	NXGE_HIO_TYPE_GUEST		/* We are a guest domain driver. */
} nxge_hio_type_t;

typedef enum {
	FUNC0_MNT,
	FUNC0_VIR = 0x1000000,
	FUNC1_MNT = 0x2000000,
	FUNC1_VIR = 0x3000000,
	FUNC2_MNT = 0x4000000,
	FUNC2_VIR = 0x5000000,
	FUNC3_MNT = 0x6000000,
	FUNC3_VIR = 0x7000000
} vr_base_address_t;

#define	VR_STEP		0x2000000
#define	VR_VC_STEP	0x0004000

typedef enum {			/* 0-8 */
	FUNC0_VIR0,
	FUNC0_VIR1,
	FUNC1_VIR0,
	FUNC1_VIR1,
	FUNC2_VIR0,
	FUNC2_VIR1,
	FUNC3_VIR0,
	FUNC3_VIR1,
	FUNC_VIR_MAX
} vr_region_t;

typedef enum {
	VP_CHANNEL_0,
	VP_CHANNEL_1,
	VP_CHANNEL_2,
	VP_CHANNEL_3,
	VP_CHANNEL_4,
	VP_CHANNEL_5,
	VP_CHANNEL_6,
	VP_CHANNEL_7,
	VP_CHANNEL_MAX
} vp_channel_t;

typedef enum {
	VP_BOUND_TX = 1,
	VP_BOUND_RX
} vpc_type_t;

#define	VP_VC_OFFSET(channel)	(channel << 10)
#define	VP_RDC_OFFSET		(1 << 9)

typedef enum {
	RXDMA_CFIG1		= 0,
	RXDMA_CFIG2		= 8,
	RBR_CFIG_A		= 0x10,
	RBR_CFIG_B		= 0x18,
	RBR_KICK		= 0x20,
	RBR_STAT		= 0x28,
	RBR_HDH			= 0x30,
	RBR_HDL			= 0x38,
	RCRCFIG_A		= 0x40,
	RCRCFIG_B		= 0x48,
	RCRSTAT_A		= 0x50,
	RCRSTAT_B		= 0x58,
	RCRSTAT_C		= 0x60,
	RX_DMA_ENT_MSK		= 0x68,
	RX_DMA_CTL_STAT		= 0x70,
	RCR_FLSH		= 0x78,
	RXMISC			= 0x90,
	RX_DMA_CTL_STAT_DBG	= 0x98

} rdc_csr_offset_t;

typedef enum {
	Tx_RNG_CFIG		= 0,
	Tx_RNG_HDL		= 0x10,
	Tx_RNG_KICK		= 0x18,
	Tx_ENT_MASK		= 0x20,
	Tx_CS			= 0x28,
	TxDMA_MBH		= 0x30,
	TxDMA_MBL		= 0x38,
	TxDMA_PRE_ST		= 0x40,
	Tx_RNG_ERR_LOGH		= 0x48,
	Tx_RNG_ERR_LOGL		= 0x50,
	TDMC_INTR_DBG		= 0x60,
	Tx_CS_DBG		= 0x68

} tdc_csr_offset_t;

/*
 * -------------------------------------------------------------
 * These definitions are used to handle the virtual PIO_LDSV
 * space of a VR.
 * -------------------------------------------------------------
 */
#define	VLDG_OFFSET		0x2000
#define	VLDG_SLL		5

typedef enum {
	PIO_LDSV0,		/* ldf_0, 0-63 */
	PIO_LDSV1,		/* ldf_1, 0-63 */
	PIO_LDSV2,		/* ldf_0 & ldf_1, 64-69 */
	PIO_LDGIMGN		/* arm/timer */

} pio_ld_op_t;

#define	VR_INTR_BLOCK_SIZE	8
#define	HIO_INTR_BLOCK_SIZE	4

/* ------------------------------------------------------------------ */
typedef struct {
	const char	*name;
	int		offset;
} dmc_reg_name_t;

typedef struct {
	uintptr_t	nxge;
	dc_map_t	map;

} nx_rdc_tbl_t;

typedef struct nxge_hio_vr {
	uintptr_t	nxge;

	uint32_t	cookie;	/* The HV cookie. */
	uintptr_t	address;
	size_t		size;
	vr_region_t	region;	/* 1 of 8 regions. */

	int		rdc_tbl; /* 1 of 8 RDC tables. */
	int		tdc_tbl; /* 1 of 8 TDC tables. */
	ether_addr_t	altmac;	/* The alternate MAC address. */
	int		slot;	/* According to nxge_m_mmac_add(). */

	nxge_grp_t	rx_group;
	nxge_grp_t	tx_group;

} nxge_hio_vr_t;

typedef nxge_status_t (*dc_init_t)(nxge_t *, int);
typedef void (*dc_uninit_t)(nxge_t *, int);

typedef struct {
	uint32_t	number;	/* The LDG number assigned to this DC. */
	uint64_t	index;	/* Bits 7:5 of the (virtual) PIO_LDSV. */

	uint64_t	ldsv;	/* The logical device number */
	uint64_t	map;	/* Currently unused */

	int		vector;	/* The DDI vector number (index) */
} hio_ldg_t;

/*
 * -------------------------------------------------------------
 * The service domain driver makes use of both <index>, the index
 * into a VR's virtual page, and <channel>, the absolute channel
 * number, what we will call here the physical channel number.
 *
 * The guest domain will set both fields to the same value, since
 * it doesn't know any better.  And if a service domain owns a
 * DMA channel, it will also set both fields to the same value,
 * since it is not using a VR per se.
 * -------------------------------------------------------------
 */
typedef struct nx_dc {

	struct nx_dc	*next;

	nxge_hio_vr_t	*vr;	/* The VR belonged to. */

	vp_channel_t	page;	/* VP_CHANNEL_0 - VP_CHANNEL_7 */
	nxge_channel_t	channel; /* 1 of 16/24 channels */
	/*
	 * <channel> has its normal meaning. <page> refers to the
	 * virtual page of the VR that <channel> has been bound to.
	 * Therefore, in the service domain, <page> & <channel>
	 * are almost always different. While in a guest domain,
	 * they are always the same.
	 */
	vpc_type_t	type;	/* VP_BOUND_XX */
	dc_init_t	init;	/* nxge_init_xxdma_channel() */
	dc_uninit_t	uninit;	/* nxge_uninit_xxdma_channel() */

	nxge_grp_t	*group;	/* The group belonged to. */
	uint32_t	cookie;	/* The HV cookie. */

	hio_ldg_t	ldg;
	boolean_t	interrupting; /* Interrupt enabled? */

} nxge_hio_dc_t;

typedef struct {
	nxge_hio_type_t		type;

	kmutex_t		lock;
	int			vrs;
	unsigned		sequence;

	nxhv_fp_t		hio;

	/* vr[0] is reserved for the service domain. */
	nxge_hio_vr_t		vr[NXGE_VR_SR_MAX]; /* subregion map */
	nxge_hio_dc_t		rdc[NXGE_MAX_RDCS];
	nxge_hio_dc_t		tdc[NXGE_MAX_TDCS];

	nx_rdc_tbl_t		rdc_tbl[NXGE_MAX_RDC_GROUPS];

} nxge_hio_data_t;

/*
 * -------------------------------------------------------------
 * prototypes
 * -------------------------------------------------------------
 */
extern void nxge_get_environs(nxge_t *);
extern int nxge_hio_init(nxge_t *);
extern void nxge_hio_uninit(nxge_t *);

extern int nxge_dci_map(nxge_t *, vpc_type_t, int);

/*
 * ---------------------------------------------------------------------
 * These are the general-purpose DMA channel group functions.  That is,
 * these functions are used to manage groups of TDCs or RDCs in an HIO
 * environment.
 *
 * But is also expected that in the future they will be able to manage
 * Crossbow groups.
 * ---------------------------------------------------------------------
 */
extern nxge_grp_t *nxge_grp_add(nxge_t *, nxge_grp_type_t);
extern void nxge_grp_remove(nxge_t *, nxge_grp_t *);
extern int nxge_grp_dc_add(nxge_t *, nxge_grp_t *, vpc_type_t, int);
extern void nxge_grp_dc_remove(nxge_t *, vpc_type_t, int);
extern nxge_hio_dc_t *nxge_grp_dc_find(nxge_t *, vpc_type_t, int);

extern void nxge_delay(int);
extern const char *nxge_ddi_perror(int);

/*
 * ---------------------------------------------------------------------
 * These are the Sun4v HIO function prototypes.
 * ---------------------------------------------------------------------
 */
extern void nxge_hio_group_get(void *arg, mac_ring_type_t type, int group,
	mac_group_info_t *infop, mac_group_handle_t ghdl);
extern int nxge_hio_share_alloc(void *arg, mac_share_handle_t *shandle);
extern void nxge_hio_share_free(mac_share_handle_t shandle);
extern void nxge_hio_share_query(mac_share_handle_t shandle,
	mac_ring_type_t type, mac_ring_handle_t *rings, uint_t *n_rings);
extern int nxge_hio_share_add_group(mac_share_handle_t,
    mac_group_driver_t);
extern int nxge_hio_share_rem_group(mac_share_handle_t,
    mac_group_driver_t);
extern int nxge_hio_share_bind(mac_share_handle_t, uint64_t cookie,
    uint64_t *rcookie);
extern void nxge_hio_share_unbind(mac_share_handle_t);
extern int nxge_hio_rxdma_bind_intr(nxge_t *, rx_rcr_ring_t *, int);

				/* nxge_hio_guest.c */
extern void nxge_hio_unregister(nxge_t *);
extern int nxge_hio_get_dc_htable_idx(nxge_t *nxge, vpc_type_t type,
    uint32_t channel);

extern int nxge_guest_regs_map(nxge_t *);
extern void nxge_guest_regs_map_free(nxge_t *);

extern int nxge_hio_vr_add(nxge_t *nxge);
extern int nxge_hio_vr_release(nxge_t *nxge);

extern nxge_status_t nxge_tdc_lp_conf(p_nxge_t, int);
extern nxge_status_t nxge_rdc_lp_conf(p_nxge_t, int);

extern void nxge_hio_start_timer(nxge_t *);

				/* nxge_intr.c */
extern nxge_status_t nxge_hio_intr_init(nxge_t *);
extern void nxge_hio_intr_uninit(nxge_t *);

extern nxge_status_t nxge_intr_add(nxge_t *, vpc_type_t, int);
extern nxge_status_t nxge_intr_remove(nxge_t *, vpc_type_t, int);

extern nxge_status_t nxge_hio_intr_add(nxge_t *, vpc_type_t, int);
extern nxge_status_t nxge_hio_intr_remove(nxge_t *, vpc_type_t, int);

extern nxge_status_t nxge_hio_intr_add(nxge_t *, vpc_type_t, int);
extern nxge_status_t nxge_hio_intr_rem(nxge_t *, int);

extern int nxge_hio_ldsv_add(nxge_t *, nxge_hio_dc_t *);

extern void nxge_hio_ldsv_im(nxge_t *, nxge_ldg_t *, pio_ld_op_t, uint64_t *);
extern void nxge_hio_ldgimgn(nxge_t *, nxge_ldg_t *);

				/* nxge_hv.c */
extern void nxge_hio_hv_init(nxge_t *);

				/* nxge_mac.c */
extern int nxge_hio_hostinfo_get_rdc_table(p_nxge_t);
extern int nxge_hio_hostinfo_init(nxge_t *, nxge_hio_vr_t *, ether_addr_t *);
extern void nxge_hio_hostinfo_uninit(nxge_t *, nxge_hio_vr_t *);

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_NXGE_NXGE_HIO_H */