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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 #ifndef	_SYS_IB_ADAPTERS_HERMON_RSRC_H
27 #define	_SYS_IB_ADAPTERS_HERMON_RSRC_H
28 
29 /*
30  * hermon_rsrc.h
31  *    Contains all of the prototypes, #defines, and structures necessary
32  *    for the Hermon Resource Management routines.
33  *    Specifically it contains the resource names, resource types, and
34  *    structures used for enabling both init/fini and alloc/free operations.
35  */
36 
37 #include <sys/types.h>
38 #include <sys/conf.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 #include <sys/disp.h>
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 /*
48  * The above extern and the following #defines and macro are used to determine
49  * the current context for purposes of setting the sleepflag.  If the calling
50  * thread is running in the interrupt context, then macro will return
51  * HERMON_NOSLEEP (indicating that it is not appropriate to sleep in the current
52  * context.  In all other cases, this macro will return HERMON_SLEEP.
53  *
54  * The HERMON_CMD_SLEEP_NOSPIN and HERMON_CMD_NOSLEEP_SPIN #defines from
55  * hermon_cmd.h are set to use and be compatible with the following SLEEP
56  * variables.  It is important that these remain in sync so that the
57  * HERMON_SLEEPFLAG_FOR_CONTEXT() macro will work in all cases.
58  */
59 #define	HERMON_SLEEP			0
60 #define	HERMON_NOSLEEP			1
61 #define	HERMON_SLEEPFLAG_FOR_CONTEXT()					\
62 	((servicing_interrupt() || ddi_in_panic()) ? HERMON_NOSLEEP :	\
63 	    HERMON_SLEEP)
64 
65 /*
66  * The following #defines are used as the names for various resource pools.
67  * They represent the kmem_cache and vmem_arena names, respectively.  In
68  * order to provide for unique naming when multiple Hermon drivers are present,
69  * the HERMON_RSRC_NAME macro below is used to append the driver's instance
70  * number to the provided string.  Note: resource names should not be longer
71  * than HERMON_RSRC_NAME_MAXLEN.
72  */
73 
74 
75 #define	HERMON_RSRC_CACHE		"hermon_rsrc_cache"
76 #define	HERMON_PDHDL_CACHE		"hermon_pdhdl_cache"
77 #define	HERMON_MRHDL_CACHE		"hermon_mrhdl_cache"
78 #define	HERMON_EQHDL_CACHE		"hermon_eqhdl_cache"
79 #define	HERMON_CQHDL_CACHE		"hermon_cqhdl_cache"
80 #define	HERMON_SRQHDL_CACHE		"hermon_srqhdl_cache"
81 #define	HERMON_AHHDL_CACHE		"hermon_ahhdl_cache"
82 #define	HERMON_QPHDL_CACHE		"hermon_qphdl_cache"
83 #define	HERMON_REFCNT_CACHE		"hermon_refcnt_cache"
84 
85 #define	HERMON_ICM_VMEM			"hermon_icm_vmem"
86 #define	HERMON_INMBOX_VMEM		"hermon_inmbox_vmem"
87 #define	HERMON_OUTMBOX_VMEM		"hermon_outmbox_vmem"
88 #define	HERMON_INTR_INMBOX_VMEM		"hermon_intr_inmbox_vmem"
89 #define	HERMON_INTR_OUTMBOX_VMEM	"hermon_intr_outmbox_vmem"
90 /* ICM based vmem */
91 #define	HERMON_CMPT_VMEM		"hermon_cmpt_vmem"
92 #define	HERMON_CMPT_QPC_VMEM		"hermon_cmpt_qpc_vmem"
93 #define	HERMON_CMPT_SRQ_VMEM		"hermon_cmpt_srq_vmem"
94 #define	HERMON_CMPT_CQC_VMEM		"hermon_cmpt_cqc_vmem"
95 #define	HERMON_CMPT_EQC_VMEM		"hermon_cmpt_eqc_vmem"
96 #define	HERMON_DMPT_VMEM		"hermon_dmpt_vmem"
97 #define	HERMON_MTT_VMEM			"hermon_mtt_vmem"
98 #define	HERMON_QPC_VMEM			"hermon_qpc_vmem"
99 #define	HERMON_SRQC_VMEM		"hermon_srqc_vmem"
100 #define	HERMON_RDB_VMEM			"hermon_rdb_vmem"
101 #define	HERMON_CQC_VMEM			"hermon_cqc_vmem"
102 #define	HERMON_ALTC_VMEM		"hermon_altc_vmem"
103 #define	HERMON_AUXC_VMEM		"hermon_auxc_vmem"
104 #define	HERMON_EQC_VMEM			"hermon_eqc_vmem"
105 #define	HERMON_MCG_VMEM			"hermon_mcg_vmem"
106 /* Add'd vmem arenas */
107 #define	HERMON_UAR_PAGE_VMEM_ATTCH	"hermon_uar_pg_vmem:a"
108 #define	HERMON_UAR_PAGE_VMEM_RUNTM	"hermon_uar_pg_vmem:r"
109 #define	HERMON_BLUEFLAME_VMEM		"hermon_blueflame_vmem"
110 #define	HERMON_PDHDL_VMEM		"hermon_pd_vmem"
111 
112 /* Macro provided for building unique naming for multiple instance  */
113 #define	HERMON_RSRC_NAME(rsrc_name, string)		\
114 	(void) sprintf((rsrc_name), string"%08X",	\
115 	    state->hs_instance)
116 #define	HERMON_RSRC_NAME_MAXLEN		0x80
117 
118 /* various cMPT types - need to concatenate w/ index to find it in ICM */
119 typedef enum {
120 	HERMON_QP_CMPT	= 0,
121 	HERMON_SRQ_CMPT	= 1,
122 	HERMON_CQ_CMPT	= 2,
123 	HERMON_EQ_CMPT	= 3,
124 	HERMON_MPT_DMPT	= 4
125 } hermon_mpt_rsrc_type_t;
126 
127 
128 /*
129  * The following enumerated type is used to capture all the various types
130  * of Hermon resources.  Note the HERMON_NUM_RESOURCES type is used as a marker
131  * for the end of the resource types.  No additional resources should be
132  * added after this. Note also that HERMON_NUM_ICM_RESOURCES is used similarly,
133  * indicating the number of ICM resource types. If additional ICM types are
134  * added, they should be added before MERMON_NUM_ICM_RESOURCES.
135  */
136 
137 typedef enum {
138 	HERMON_CMPT,		/* for sizing ICM space for control MPTs */
139 	HERMON_QPC,
140 	HERMON_SRQC,
141 	HERMON_CQC,
142 	HERMON_EQC,
143 	HERMON_DMPT,
144 	HERMON_MTT,
145 	HERMON_ALTC,		/* for allocation of ICM backing memory */
146 	HERMON_AUXC,		/* for allocation of ICM backing memory */
147 	HERMON_RDB,		/* for allocation of ICM backing memory */
148 	HERMON_CMPT_QPC,	/* for allocation of ICM backing memory */
149 	HERMON_CMPT_SRQC,	/* for allocation of ICM backing memory */
150 	HERMON_CMPT_CQC,	/* for allocation of ICM backing memory */
151 	HERMON_CMPT_EQC,	/* for allocation of ICM backing memory */
152 	HERMON_MCG,		/* type 0x0E */
153 	/* all types above are in ICM, all below are in non-ICM */
154 	HERMON_NUM_ICM_RESOURCES,
155 	HERMON_IN_MBOX = HERMON_NUM_ICM_RESOURCES,
156 	HERMON_OUT_MBOX,	/* type 0x10 */
157 	HERMON_PDHDL,
158 	HERMON_MRHDL,
159 	HERMON_EQHDL,
160 	HERMON_CQHDL,
161 	HERMON_QPHDL,
162 	HERMON_SRQHDL,
163 	HERMON_AHHDL,
164 	HERMON_REFCNT,
165 	HERMON_UARPG,
166 	HERMON_INTR_IN_MBOX,
167 	HERMON_INTR_OUT_MBOX,	/* type 0x1B */
168 	HERMON_QPC_FEXCH_PORT1,
169 	HERMON_QPC_FEXCH_PORT2,
170 	HERMON_QPC_RFCI_PORT1,
171 	HERMON_QPC_RFCI_PORT2,
172 	HERMON_NUM_RESOURCES
173 } hermon_rsrc_type_t;
174 
175 /*
176  * The following enumerated type and structures are used during resource
177  * initialization.  Note: The HERMON_RSRC_CLEANUP_ALL type is used as a marker
178  * for end of the cleanup steps.  No cleanup steps should be added after
179  * HERMON_RSRC_CLEANUP_ALL.  Any addition steps should be added before it.
180  */
181 typedef enum {
182 	HERMON_RSRC_CLEANUP_LEVEL0,
183 	HERMON_RSRC_CLEANUP_LEVEL1,
184 	HERMON_RSRC_CLEANUP_LEVEL2,
185 	HERMON_RSRC_CLEANUP_LEVEL3,
186 	HERMON_RSRC_CLEANUP_LEVEL4,
187 	HERMON_RSRC_CLEANUP_LEVEL5,
188 	HERMON_RSRC_CLEANUP_LEVEL6,
189 	HERMON_RSRC_CLEANUP_LEVEL7,
190 	HERMON_RSRC_CLEANUP_PHASE1_COMPLETE,
191 	HERMON_RSRC_CLEANUP_LEVEL8,
192 	HERMON_RSRC_CLEANUP_LEVEL9,
193 	HERMON_RSRC_CLEANUP_LEVEL10,
194 	HERMON_RSRC_CLEANUP_LEVEL10QP,
195 	HERMON_RSRC_CLEANUP_LEVEL10SRQ,
196 	HERMON_RSRC_CLEANUP_LEVEL10CQ,
197 	HERMON_RSRC_CLEANUP_LEVEL10EQ,
198 	HERMON_RSRC_CLEANUP_LEVEL11,
199 	HERMON_RSRC_CLEANUP_LEVEL12,
200 	HERMON_RSRC_CLEANUP_LEVEL13,
201 	HERMON_RSRC_CLEANUP_LEVEL14,
202 	HERMON_RSRC_CLEANUP_LEVEL15,
203 	HERMON_RSRC_CLEANUP_LEVEL16,
204 	HERMON_RSRC_CLEANUP_LEVEL17,
205 	HERMON_RSRC_CLEANUP_LEVEL18,
206 	HERMON_RSRC_CLEANUP_LEVEL19,
207 	HERMON_RSRC_CLEANUP_LEVEL20,
208 	HERMON_RSRC_CLEANUP_LEVEL21,
209 	HERMON_RSRC_CLEANUP_LEVEL22,
210 	HERMON_RSRC_CLEANUP_LEVEL23,
211 	HERMON_RSRC_CLEANUP_LEVEL24,
212 	HERMON_RSRC_CLEANUP_LEVEL25,
213 	HERMON_RSRC_CLEANUP_LEVEL26,
214 	HERMON_RSRC_CLEANUP_LEVEL27,
215 	HERMON_RSRC_CLEANUP_LEVEL28,
216 	HERMON_RSRC_CLEANUP_LEVEL29,
217 	HERMON_RSRC_CLEANUP_LEVEL30,
218 	HERMON_RSRC_CLEANUP_LEVEL31,
219 	/* No more cleanup steps below this point! */
220 	HERMON_RSRC_CLEANUP_ALL
221 } hermon_rsrc_cleanup_level_t;
222 
223 /*
224  * The hermon_rsrc_mbox_info_t structure is used when initializing the two
225  * Hermon mailbox types ("In" and "Out").  This structure contains the
226  * requested number and size of the mailboxes, and the resource pool from
227  * which the other relevant properties will come.
228  */
229 typedef struct hermon_rsrc_mbox_info_s {
230 	uint64_t		mbi_num;
231 	uint64_t		mbi_size;
232 	hermon_rsrc_pool_info_t *mbi_rsrcpool;
233 } hermon_rsrc_mbox_info_t;
234 
235 /*
236  * The hermon_rsrc_hw_entry_info_t structure is used when initializing the
237  * Hermon HW entry types.  This structure contains the requested number of
238  * entries for the resource.  That value is compared against the maximum
239  * number (usually determined as a result of the Hermon QUERY_DEV_CAP command).
240  * In addition it contains a number of requested entries to be "pre-allocated"
241  * (this is generally because the Hermon hardware requires a certain number
242  * for its own purposes).  Lastly the resource pool and resource name
243  * information.
244  */
245 typedef struct hermon_rsrc_hw_entry_info_s {
246 	uint64_t		hwi_num;
247 	uint64_t		hwi_max;
248 	uint64_t		hwi_prealloc;
249 	hermon_rsrc_pool_info_t *hwi_rsrcpool;
250 	char			*hwi_rsrcname;
251 } hermon_rsrc_hw_entry_info_t;
252 
253 /*
254  * The hermon_rsrc_sw_hdl_info_t structure is used when initializing the
255  * Hermon software handle types.  This structure also contains the requested
256  * number of handles for the resource.  That value is compared against a
257  * maximum number passed in.  Because many of the software handle resource
258  * types are managed through the use of kmem_cache, fields are provided for
259  * specifying cache constructor and destructor methods.  Just like above,
260  * there is space for resource pool and resource name information.  And,
261  * somewhat like above, there is space to provide information (size, type,
262  * pointer to table, etc). about any "pre-allocated" resources that need to
263  * be set aside.
264  * Note specifically that the "swi_flags" field may contain any of the flags
265  * #define'd below.  The HERMON_SWHDL_KMEMCACHE_INIT flag indicates that the
266  * given resource should have a kmem_cache setup for it, and the
267  * HERMON_SWHDL_TABLE_INIT flag indicates that some preallocation (as defined
268  * by the "swi_num" and "swi_prealloc_sz" fields) should be done, with the
269  * resulting table pointer passed back in "swi_table_ptr".
270  */
271 typedef struct hermon_rsrc_sw_hdl_info_s {
272 	uint64_t		swi_num;
273 	uint64_t		swi_max;
274 	uint64_t		swi_prealloc_sz;
275 	hermon_rsrc_pool_info_t 	*swi_rsrcpool;
276 	int (*swi_constructor)(void *, void *, int);
277 	void (*swi_destructor)(void *, void *);
278 	char			*swi_rsrcname;
279 	uint_t			swi_flags;
280 	void			*swi_table_ptr;
281 } hermon_rsrc_sw_hdl_info_t;
282 #define	HERMON_SWHDL_NOFLAGS		0
283 #define	HERMON_SWHDL_KMEMCACHE_INIT	(1 << 0)
284 #define	HERMON_SWHDL_TABLE_INIT		(1 << 1)
285 
286 
287 /*
288  * The following structure is used to specify (at init time) and to track
289  * (during allocation and freeing) all the useful information regarding a
290  * particular resource type.  An array of these resources (indexed by
291  * resource type) is allocated at driver startup time.  It is available
292  * through the driver's soft state structure.
293  * Each resource has an indication of its type and its location.  Resources
294  * may be located in one of three possible places - in the Hermon ICM memory
295  * (device virtual, backed by system memory),in system memory, or in
296  * Hermon UAR memory (residing behind BAR2).
297  * Each resource pool also has properties associated with it and the object
298  * that make up the pool.  These include the pool's size, the size of the
299  * individual objects (rsrc_quantum), any alignment restrictions placed on
300  * the pool of objects, and the shift size (log2) of each object.
301  * In addition (depending on object type) the "rsrc_ddr_offset" field may
302  * indicate where in DDR memory a given resource pool is located (e.g. a
303  * QP context table).  It may have a pointer to a vmem_arena for that table
304  * and/or it may point to some other private information (rsrc_private)
305  * specific to the given object type.
306  * Always, though, the resource pool pointer provides a pointer back to the
307  * soft state structure of the Hermon driver instance with which it is
308  * associated.
309  */
310 struct hermon_rsrc_pool_info_s {
311 	hermon_rsrc_type_t	rsrc_type;
312 	uint_t			rsrc_loc;
313 	uint64_t		rsrc_pool_size; /* table size (num x size) */
314 	uint64_t		rsrc_align;
315 	uint_t			rsrc_shift;
316 	uint_t			rsrc_quantum; /* size of each content */
317 	void			*rsrc_start; /* phys start addr of table */
318 	vmem_t			*rsrc_vmp; /* vmem arena for table */
319 	hermon_state_t		*rsrc_state;
320 	void			*rsrc_private;
321 };
322 #define	HERMON_IN_ICM			0x0
323 #define	HERMON_IN_SYSMEM		0x1
324 #define	HERMON_IN_UAR			0x2
325 
326 /*
327  * The hermon_rsrc_priv_mbox_t structure is used to pass along additional
328  * information about the mailbox types.  Specifically, by containing the
329  * DMA attributes, access handle, dev access handle, etc., it provides enough
330  * information that each mailbox can be later by bound/unbound/etc. for
331  * DMA access by the hardware.  Note: we can also specify (using the
332  * "pmb_xfer_mode" field), whether a given mailbox type should be bound for
333  * DDI_DMA_STREAMING or DDI_DMA_CONSISTENT operations.
334  */
335 typedef struct hermon_rsrc_priv_mbox_s {
336 	dev_info_t		*pmb_dip;
337 	ddi_dma_attr_t		pmb_dmaattr;
338 	/* JBDB what is this handle for? */
339 	ddi_acc_handle_t	pmb_acchdl;
340 	ddi_device_acc_attr_t	pmb_devaccattr;
341 	uint_t			pmb_xfer_mode;
342 } hermon_rsrc_priv_mbox_t;
343 
344 /*
345  * The hermon_rsrc_t structure is the structure returned by the Hermon resource
346  * allocation routines.  It contains all the necessary information about the
347  * allocated object.  Specifically, it provides an address where the object
348  * can be accessed.  It also provides the length and index (specifically, for
349  * those resources that are accessed from tables).  In addition it can provide
350  * an access handles and DMA handle to be used when accessing or setting DMA
351  * to a specific object.  Note: not all of this information is valid for all
352  * object types.  See the consumers of each object for more explanation of
353  * which fields are used (and for what purpose).
354  */
355 struct hermon_rsrc_s {
356 	hermon_rsrc_type_t	rsrc_type;
357 	void			*hr_addr;
358 	uint32_t		hr_len;
359 	uint32_t		hr_indx;
360 	ddi_acc_handle_t	hr_acchdl;
361 	ddi_dma_handle_t	hr_dmahdl;
362 };
363 
364 /*
365  * The following are the Hermon Resource Management routines that accessible
366  * externally (i.e. throughout the rest of the Hermon driver software).
367  * These include the alloc/free routines, the initialization routines, which
368  * are broken into two phases (see hermon_rsrc.c for further explanation),
369  * and the Hermon resource cleanup routines (which are used at driver detach()
370  * time.
371  */
372 int hermon_rsrc_alloc(hermon_state_t *state, hermon_rsrc_type_t rsrc,
373     uint_t num, uint_t sleepflag, hermon_rsrc_t **hdl);
374 void hermon_rsrc_free(hermon_state_t *state, hermon_rsrc_t **hdl);
375 int hermon_rsrc_init_phase1(hermon_state_t *state);
376 int hermon_rsrc_init_phase2(hermon_state_t *state);
377 void hermon_rsrc_fini(hermon_state_t *state,
378     hermon_rsrc_cleanup_level_t clean);
379 
380 /* Exporting resource reservation capabilitity to FCoIB */
381 int hermon_rsrc_reserve(hermon_state_t *state, hermon_rsrc_type_t rsrc,
382     uint_t num, uint_t sleepflag, hermon_rsrc_t **hdl);
383 
384 #ifdef __cplusplus
385 }
386 #endif
387 
388 #endif	/* _SYS_IB_ADAPTERS_HERMON_RSRC_H */
389