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