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