nxge_hio.h revision 11878:ac93462db6d7
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#ifndef	_SYS_NXGE_NXGE_HIO_H
28#define	_SYS_NXGE_NXGE_HIO_H
29
30#ifdef	__cplusplus
31extern "C" {
32#endif
33
34#include <nxge_mac.h>
35#include <nxge_ipp.h>
36#include <nxge_fflp.h>
37#include <sys/mac_provider.h>
38
39#define	isLDOMservice(nxge) \
40	(nxge->environs == SOLARIS_SERVICE_DOMAIN)
41#define	isLDOMguest(nxge) \
42	(nxge->environs == SOLARIS_GUEST_DOMAIN)
43#define	isLDOMs(nxge) \
44	(isLDOMservice(nxge) || isLDOMguest(nxge))
45
46#define	NXGE_HIO_SHARE_MIN_CHANNELS	2
47#define	NXGE_HIO_SHARE_MAX_CHANNELS	2
48
49/* ------------------------------------------------------------------ */
50typedef uint8_t nx_rdc_t;
51typedef uint8_t nx_tdc_t;
52
53typedef uint64_t res_map_t;
54
55typedef uint64_t hv_rv_t;
56
57typedef hv_rv_t (*vr_assign)(uint64_t, uint64_t, uint32_t *);
58typedef hv_rv_t (*vr_unassign)(uint32_t);
59typedef hv_rv_t (*vr_getinfo)(uint32_t, uint64_t *, uint64_t *);
60
61/* HV 2.0 API group functions */
62typedef hv_rv_t (*vr_cfgh_assign)(uint64_t, uint64_t, uint64_t, uint32_t *);
63typedef hv_rv_t (*vrlp_cfgh_conf)(uint64_t, uint64_t, uint64_t, uint64_t,
64    uint64_t);
65typedef hv_rv_t (*vrlp_cfgh_info)(uint64_t, uint64_t, uint64_t, uint64_t *,
66    uint64_t *);
67
68
69typedef struct {
70	vr_assign	assign;		/* HV Major 1 interface */
71	vr_cfgh_assign	cfgh_assign;	/* HV Major 2 interface */
72	vr_unassign	unassign;
73	vr_getinfo	getinfo;
74} nxhv_vr_fp_t;
75
76typedef hv_rv_t (*vrlp_conf)(uint64_t, uint64_t, uint64_t, uint64_t);
77typedef hv_rv_t (*vrlp_info)(uint64_t, uint64_t, uint64_t *, uint64_t *);
78
79typedef hv_rv_t (*dc_assign)(uint32_t, uint64_t, uint64_t *);
80typedef hv_rv_t (*dc_unassign)(uint32_t, uint64_t);
81typedef hv_rv_t (*dc_getstate)(uint32_t, uint64_t, uint64_t *);
82typedef hv_rv_t (*dc_get_map)(uint32_t, uint64_t *);
83
84typedef hv_rv_t (*dc_getinfo)(uint32_t, uint64_t, uint64_t *, uint64_t *);
85
86typedef struct {
87	dc_assign	assign;
88	dc_unassign	unassign;
89	dc_getstate	getstate;
90	dc_get_map	get_map;
91
92	vrlp_conf	lp_conf;	/* HV Major 1 interface */
93	vrlp_info	lp_info;	/* HV Major 1 interface */
94	vrlp_cfgh_conf	lp_cfgh_conf;	/* HV Major 2 interface */
95	vrlp_cfgh_info	lp_cfgh_info;	/* HV Major 2 interface */
96	dc_getinfo	getinfo;
97} nxhv_dc_fp_t;
98
99typedef struct {
100	boolean_t	ldoms;
101	nxhv_vr_fp_t	vr;
102	nxhv_dc_fp_t	tx;
103	nxhv_dc_fp_t	rx;
104} nxhv_fp_t;
105
106/* ------------------------------------------------------------------ */
107#define	NXGE_VR_SR_MAX		8 /* There are 8 subregions (SR). */
108
109typedef enum {
110	NXGE_HIO_TYPE_SERVICE = 0x80,	/* We are a service domain driver. */
111	NXGE_HIO_TYPE_GUEST		/* We are a guest domain driver. */
112} nxge_hio_type_t;
113
114typedef enum {
115	FUNC0_MNT,
116	FUNC0_VIR = 0x1000000,
117	FUNC1_MNT = 0x2000000,
118	FUNC1_VIR = 0x3000000,
119	FUNC2_MNT = 0x4000000,
120	FUNC2_VIR = 0x5000000,
121	FUNC3_MNT = 0x6000000,
122	FUNC3_VIR = 0x7000000
123} vr_base_address_t;
124
125#define	VR_STEP		0x2000000
126#define	VR_VC_STEP	0x0004000
127
128typedef enum {			/* 0-8 */
129	FUNC0_VIR0,
130	FUNC0_VIR1,
131	FUNC1_VIR0,
132	FUNC1_VIR1,
133	FUNC2_VIR0,
134	FUNC2_VIR1,
135	FUNC3_VIR0,
136	FUNC3_VIR1,
137	FUNC_VIR_MAX
138} vr_region_t;
139
140typedef enum {
141	VP_CHANNEL_0,
142	VP_CHANNEL_1,
143	VP_CHANNEL_2,
144	VP_CHANNEL_3,
145	VP_CHANNEL_4,
146	VP_CHANNEL_5,
147	VP_CHANNEL_6,
148	VP_CHANNEL_7,
149	VP_CHANNEL_MAX
150} vp_channel_t;
151
152typedef enum {
153	VP_BOUND_TX = 1,
154	VP_BOUND_RX
155} vpc_type_t;
156
157#define	VP_VC_OFFSET(channel)	(channel << 10)
158#define	VP_RDC_OFFSET		(1 << 9)
159
160typedef enum {
161	RXDMA_CFIG1		= 0,
162	RXDMA_CFIG2		= 8,
163	RBR_CFIG_A		= 0x10,
164	RBR_CFIG_B		= 0x18,
165	RBR_KICK		= 0x20,
166	RBR_STAT		= 0x28,
167	RBR_HDH			= 0x30,
168	RBR_HDL			= 0x38,
169	RCRCFIG_A		= 0x40,
170	RCRCFIG_B		= 0x48,
171	RCRSTAT_A		= 0x50,
172	RCRSTAT_B		= 0x58,
173	RCRSTAT_C		= 0x60,
174	RX_DMA_ENT_MSK		= 0x68,
175	RX_DMA_CTL_STAT		= 0x70,
176	RCR_FLSH		= 0x78,
177	RXMISC			= 0x90,
178	RX_DMA_CTL_STAT_DBG	= 0x98
179
180} rdc_csr_offset_t;
181
182typedef enum {
183	Tx_RNG_CFIG		= 0,
184	Tx_RNG_HDL		= 0x10,
185	Tx_RNG_KICK		= 0x18,
186	Tx_ENT_MASK		= 0x20,
187	Tx_CS			= 0x28,
188	TxDMA_MBH		= 0x30,
189	TxDMA_MBL		= 0x38,
190	TxDMA_PRE_ST		= 0x40,
191	Tx_RNG_ERR_LOGH		= 0x48,
192	Tx_RNG_ERR_LOGL		= 0x50,
193	TDMC_INTR_DBG		= 0x60,
194	Tx_CS_DBG		= 0x68
195
196} tdc_csr_offset_t;
197
198/*
199 * -------------------------------------------------------------
200 * These definitions are used to handle the virtual PIO_LDSV
201 * space of a VR.
202 * -------------------------------------------------------------
203 */
204#define	VLDG_OFFSET		0x2000
205#define	VLDG_SLL		5
206
207typedef enum {
208	PIO_LDSV0,		/* ldf_0, 0-63 */
209	PIO_LDSV1,		/* ldf_1, 0-63 */
210	PIO_LDSV2,		/* ldf_0 & ldf_1, 64-69 */
211	PIO_LDGIMGN		/* arm/timer */
212
213} pio_ld_op_t;
214
215#define	VR_INTR_BLOCK_SIZE	8
216#define	HIO_INTR_BLOCK_SIZE	4
217
218/* ------------------------------------------------------------------ */
219typedef struct {
220	const char	*name;
221	int		offset;
222} dmc_reg_name_t;
223
224typedef struct {
225	uintptr_t	nxge;
226	dc_map_t	map;
227
228} nx_rdc_tbl_t;
229
230typedef struct nxge_hio_vr {
231	uintptr_t	nxge;
232
233	uint32_t	cookie;	/* The HV cookie. */
234	uintptr_t	address;
235	size_t		size;
236	vr_region_t	region;	/* 1 of 8 regions. */
237
238	int		rdc_tbl; /* 1 of 8 RDC tables. */
239	int		tdc_tbl; /* 1 of 8 TDC tables. */
240	ether_addr_t	altmac;	/* The alternate MAC address. */
241	int		slot;	/* According to nxge_m_mmac_add(). */
242
243	nxge_grp_t	rx_group;
244	nxge_grp_t	tx_group;
245
246} nxge_hio_vr_t;
247
248typedef nxge_status_t (*dc_init_t)(nxge_t *, int);
249typedef void (*dc_uninit_t)(nxge_t *, int);
250
251typedef struct {
252	uint32_t	number;	/* The LDG number assigned to this DC. */
253	uint64_t	index;	/* Bits 7:5 of the (virtual) PIO_LDSV. */
254
255	uint64_t	ldsv;	/* The logical device number */
256	uint64_t	map;	/* Currently unused */
257
258	int		vector;	/* The DDI vector number (index) */
259} hio_ldg_t;
260
261/*
262 * -------------------------------------------------------------
263 * The service domain driver makes use of both <index>, the index
264 * into a VR's virtual page, and <channel>, the absolute channel
265 * number, what we will call here the physical channel number.
266 *
267 * The guest domain will set both fields to the same value, since
268 * it doesn't know any better.  And if a service domain owns a
269 * DMA channel, it will also set both fields to the same value,
270 * since it is not using a VR per se.
271 * -------------------------------------------------------------
272 */
273typedef struct nx_dc {
274
275	struct nx_dc	*next;
276
277	nxge_hio_vr_t	*vr;	/* The VR belonged to. */
278
279	vp_channel_t	page;	/* VP_CHANNEL_0 - VP_CHANNEL_7 */
280	nxge_channel_t	channel; /* 1 of 16/24 channels */
281	/*
282	 * <channel> has its normal meaning. <page> refers to the
283	 * virtual page of the VR that <channel> has been bound to.
284	 * Therefore, in the service domain, <page> & <channel>
285	 * are almost always different. While in a guest domain,
286	 * they are always the same.
287	 */
288	vpc_type_t	type;	/* VP_BOUND_XX */
289	dc_init_t	init;	/* nxge_init_xxdma_channel() */
290	dc_uninit_t	uninit;	/* nxge_uninit_xxdma_channel() */
291
292	nxge_grp_t	*group;	/* The group belonged to. */
293	uint32_t	cookie;	/* The HV cookie. */
294
295	hio_ldg_t	ldg;
296	boolean_t	interrupting; /* Interrupt enabled? */
297
298} nxge_hio_dc_t;
299
300typedef struct {
301	nxge_hio_type_t		type;
302
303	kmutex_t		lock;
304	int			vrs;
305	unsigned		sequence;
306
307	nxhv_fp_t		hio;
308
309	/* vr[0] is reserved for the service domain. */
310	nxge_hio_vr_t		vr[NXGE_VR_SR_MAX]; /* subregion map */
311	nxge_hio_dc_t		rdc[NXGE_MAX_RDCS];
312	nxge_hio_dc_t		tdc[NXGE_MAX_TDCS];
313
314	nx_rdc_tbl_t		rdc_tbl[NXGE_MAX_RDC_GROUPS];
315
316} nxge_hio_data_t;
317
318/*
319 * -------------------------------------------------------------
320 * prototypes
321 * -------------------------------------------------------------
322 */
323extern void nxge_get_environs(nxge_t *);
324extern int nxge_hio_init(nxge_t *);
325extern void nxge_hio_uninit(nxge_t *);
326
327extern int nxge_dci_map(nxge_t *, vpc_type_t, int);
328
329/*
330 * ---------------------------------------------------------------------
331 * These are the general-purpose DMA channel group functions.  That is,
332 * these functions are used to manage groups of TDCs or RDCs in an HIO
333 * environment.
334 *
335 * But is also expected that in the future they will be able to manage
336 * Crossbow groups.
337 * ---------------------------------------------------------------------
338 */
339extern nxge_grp_t *nxge_grp_add(nxge_t *, nxge_grp_type_t);
340extern void nxge_grp_remove(nxge_t *, nxge_grp_t *);
341extern int nxge_grp_dc_add(nxge_t *, nxge_grp_t *, vpc_type_t, int);
342extern void nxge_grp_dc_remove(nxge_t *, vpc_type_t, int);
343extern nxge_hio_dc_t *nxge_grp_dc_find(nxge_t *, vpc_type_t, int);
344
345extern void nxge_delay(int);
346extern const char *nxge_ddi_perror(int);
347
348/*
349 * ---------------------------------------------------------------------
350 * These are the Sun4v HIO function prototypes.
351 * ---------------------------------------------------------------------
352 */
353extern void nxge_hio_group_get(void *arg, mac_ring_type_t type, int group,
354	mac_group_info_t *infop, mac_group_handle_t ghdl);
355extern int nxge_hio_share_alloc(void *arg, mac_share_handle_t *shandle);
356extern void nxge_hio_share_free(mac_share_handle_t shandle);
357extern void nxge_hio_share_query(mac_share_handle_t shandle,
358	mac_ring_type_t type, mac_ring_handle_t *rings, uint_t *n_rings);
359extern int nxge_hio_share_add_group(mac_share_handle_t,
360    mac_group_driver_t);
361extern int nxge_hio_share_rem_group(mac_share_handle_t,
362    mac_group_driver_t);
363extern int nxge_hio_share_bind(mac_share_handle_t, uint64_t cookie,
364    uint64_t *rcookie);
365extern void nxge_hio_share_unbind(mac_share_handle_t);
366extern int nxge_hio_rxdma_bind_intr(nxge_t *, rx_rcr_ring_t *, int);
367
368				/* nxge_hio_guest.c */
369extern void nxge_hio_unregister(nxge_t *);
370extern int nxge_hio_get_dc_htable_idx(nxge_t *nxge, vpc_type_t type,
371    uint32_t channel);
372
373extern int nxge_guest_regs_map(nxge_t *);
374extern void nxge_guest_regs_map_free(nxge_t *);
375
376extern int nxge_hio_vr_add(nxge_t *nxge);
377extern int nxge_hio_vr_release(nxge_t *nxge);
378
379extern nxge_status_t nxge_tdc_lp_conf(p_nxge_t, int);
380extern nxge_status_t nxge_rdc_lp_conf(p_nxge_t, int);
381
382extern void nxge_hio_start_timer(nxge_t *);
383
384				/* nxge_intr.c */
385extern nxge_status_t nxge_hio_intr_init(nxge_t *);
386extern void nxge_hio_intr_uninit(nxge_t *);
387
388extern nxge_status_t nxge_intr_add(nxge_t *, vpc_type_t, int);
389extern nxge_status_t nxge_intr_remove(nxge_t *, vpc_type_t, int);
390
391extern nxge_status_t nxge_hio_intr_add(nxge_t *, vpc_type_t, int);
392extern nxge_status_t nxge_hio_intr_remove(nxge_t *, vpc_type_t, int);
393
394extern nxge_status_t nxge_hio_intr_add(nxge_t *, vpc_type_t, int);
395extern nxge_status_t nxge_hio_intr_rem(nxge_t *, int);
396
397extern int nxge_hio_ldsv_add(nxge_t *, nxge_hio_dc_t *);
398
399extern void nxge_hio_ldsv_im(nxge_t *, nxge_ldg_t *, pio_ld_op_t, uint64_t *);
400extern void nxge_hio_ldgimgn(nxge_t *, nxge_ldg_t *);
401
402				/* nxge_hv.c */
403extern void nxge_hio_hv_init(nxge_t *);
404
405				/* nxge_mac.c */
406extern int nxge_hio_hostinfo_get_rdc_table(p_nxge_t);
407extern int nxge_hio_hostinfo_init(nxge_t *, nxge_hio_vr_t *, ether_addr_t *);
408extern void nxge_hio_hostinfo_uninit(nxge_t *, nxge_hio_vr_t *);
409
410#ifdef	__cplusplus
411}
412#endif
413
414#endif	/* _SYS_NXGE_NXGE_HIO_H */
415