hermon_cq.h revision 9517:b4839b0aa7a4
167754Smsmith/*
267754Smsmith * CDDL HEADER START
367754Smsmith *
467754Smsmith * The contents of this file are subject to the terms of the
567754Smsmith * Common Development and Distribution License (the "License").
667754Smsmith * You may not use this file except in compliance with the License.
7217365Sjkim *
8229989Sjkim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
970243Smsmith * or http://www.opensolaris.org/os/licensing.
1067754Smsmith * See the License for the specific language governing permissions
11217365Sjkim * and limitations under the License.
12217365Sjkim *
13217365Sjkim * When distributing Covered Code, include this CDDL HEADER in each
14217365Sjkim * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15217365Sjkim * If applicable, add the following below this CDDL HEADER, with the
16217365Sjkim * fields enclosed by brackets "[]" replaced with your own identifying
17217365Sjkim * information: Portions Copyright [yyyy] [name of copyright owner]
18217365Sjkim *
19217365Sjkim * CDDL HEADER END
20217365Sjkim */
21217365Sjkim
22217365Sjkim/*
23217365Sjkim * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24217365Sjkim * Use is subject to license terms.
2567754Smsmith */
26217365Sjkim
27217365Sjkim#ifndef	_SYS_IB_ADAPTERS_HERMON_CQ_H
28217365Sjkim#define	_SYS_IB_ADAPTERS_HERMON_CQ_H
2967754Smsmith
30217365Sjkim/*
31217365Sjkim * hermon_cq.h
32217365Sjkim *    Contains all of the prototypes, #defines, and structures necessary
33217365Sjkim *    for the Completion Queue Processing routines.
34217365Sjkim *    Specifically it contains the various completion types, flags,
35217365Sjkim *    structures used for managing Hermon completion queues, and prototypes
36217365Sjkim *    for many of the functions consumed by other parts of the Hermon driver
37217365Sjkim *    (including those routines directly exposed through the IBTF CI
38217365Sjkim *    interface).
39217365Sjkim *
40217365Sjkim *    Most of the values defined below establish default values which,
41217365Sjkim *    where indicated, can be controlled via their related patchable values,
42217365Sjkim *    if 'hermon_alt_config_enable' is set.
4367754Smsmith */
4467754Smsmith
4567754Smsmith#include <sys/types.h>
4667754Smsmith#include <sys/conf.h>
47193341Sjkim#include <sys/ddi.h>
48193341Sjkim#include <sys/sunddi.h>
49193341Sjkim
50193341Sjkim#include <sys/ib/adapters/hermon/hermon_misc.h>
51193341Sjkim
5267754Smsmith#ifdef __cplusplus
5377424Smsmithextern "C" {
5491116Smsmith#endif
5567754Smsmith
56151937Sjkim/*
5767754Smsmith * The following defines the default number of Completion Queues. This
58151937Sjkim * is controllable via the "hermon_log_num_cq" configuration variable.
59151937Sjkim * We also have a define for the minimum size of a CQ.  CQs allocated
60151937Sjkim * with size 0, 1, 2, or 3 will always get back a CQ of size 4.
61151937Sjkim */
62151937Sjkim#define	HERMON_NUM_CQ_SHIFT		0x10
63151937Sjkim/*
64151937Sjkim *	#define	HERMON_CQ_MIN_SIZE	0x3
65151937Sjkim */
66151937Sjkim
67151937Sjkim/*
68151937Sjkim *	#define	HERMON_CQ_MIN_SIZE	0xFF	 testing, try min 1 page
69151937Sjkim */
70151937Sjkim
71151937Sjkim/* page div 32 (cqe size) minus 1, for min size */
72167802Sjkim#define	HERMON_CQ_MIN_SIZE	((PAGESIZE / 32) - 1)
73167802Sjkim
74167802Sjkim/*
75167802Sjkim * These are the defines for the Hermon CQ completion statuses.
76167802Sjkim */
77167802Sjkim#define	HERMON_CQE_SUCCESS		0x0
78151937Sjkim#define	HERMON_CQE_LOC_LEN_ERR		0x1
79167802Sjkim#define	HERMON_CQE_LOC_OP_ERR		0x2
8067754Smsmith#define	HERMON_CQE_LOC_PROT_ERR		0x4
8167754Smsmith#define	HERMON_CQE_WR_FLUSHED_ERR	0x5
8267754Smsmith#define	HERMON_CQE_MW_BIND_ERR		0x6
8367754Smsmith#define	HERMON_CQE_BAD_RESPONSE_ERR	0x10
8467754Smsmith#define	HERMON_CQE_LOCAL_ACCESS_ERR	0x11
8567754Smsmith#define	HERMON_CQE_REM_INV_REQ_ERR	0x12
8667754Smsmith#define	HERMON_CQE_REM_ACC_ERR		0x13
8767754Smsmith#define	HERMON_CQE_REM_OP_ERR		0x14
8867754Smsmith#define	HERMON_CQE_TRANS_TO_ERR		0x15
8967754Smsmith#define	HERMON_CQE_RNRNAK_TO_ERR	0x16
9067754Smsmith#define	HERMON_CQE_EEC_REM_ABORTED_ERR	0x22
9167754Smsmith
9267754Smsmith/*
9367754Smsmith * These are the defines for the Hermon CQ entry types. They indicate what type
9467754Smsmith * of work request is completing (for successful completions).  Note: The
9567754Smsmith * "SND" or "RCV" in each define is used to indicate whether the completion
9667754Smsmith * work request was from the Send work queue or the Receive work queue on
9767754Smsmith * the associated QP.
9867754Smsmith */
9967754Smsmith#define	HERMON_CQE_SND_NOP		0x0
10067754Smsmith#define	HERMON_CQE_SND_SND_INV		0x1
101167802Sjkim#define	HERMON_CQE_SND_RDMAWR		0x8
10267754Smsmith#define	HERMON_CQE_SND_RDMAWR_IMM	0x9
10367754Smsmith#define	HERMON_CQE_SND_SEND		0xA
10482367Smsmith#define	HERMON_CQE_SND_SEND_IMM		0xB
10582367Smsmith#define	HERMON_CQE_SND_LSO		0xE
106138287Smarks#define	HERMON_CQE_SND_RDMARD		0x10
107138287Smarks#define	HERMON_CQE_SND_ATOMIC_CS	0x11
10867754Smsmith#define	HERMON_CQE_SND_ATOMIC_FA	0x12
10999146Siwasaki#define	HERMON_CQE_SND_ATOMIC_CS_EX	0x14
11067754Smsmith#define	HERMON_CQE_SND_ATOMIC_FC_EX	0x15
11199146Siwasaki#define	HERMON_CQE_SND_FRWR		0x19
11267754Smsmith#define	HERMON_CQE_SND_LCL_INV		0x1B
11367754Smsmith#define	HERMON_CQE_SND_CONFIG		0x1F
11467754Smsmith#define	HERMON_CQE_SND_BIND_MW		0x18
11567754Smsmith
116209746Sjkim#define	HERMON_CQE_RCV_RDMAWR_IMM	0x00
117209746Sjkim#define	HERMON_CQE_RCV_SEND		0x01
11867754Smsmith#define	HERMON_CQE_RCV_SEND_IMM		0x02
11967754Smsmith#define	HERMON_CQE_RCV_SND_INV		0x03
120167802Sjkim#define	HERMON_CQE_RCV_ERROR_CODE	0x1E
12167754Smsmith#define	HERMON_CQE_RCV_RESIZE_CODE	0x16
12267754Smsmith
123114237Snjl
124209746Sjkim/* Define for maximum CQ number mask (CQ number is 24 bits) */
125209746Sjkim#define	HERMON_CQ_MAXNUMBER_MSK		0xFFFFFF
126102550Siwasaki
127102550Siwasaki
128102550Siwasaki/*
12999146Siwasaki * new EQ mgmt - per domain (when it gets there).
130114237Snjl * The first N are for CQ Completions.  Following that are:
13182367Smsmith *
132209746Sjkim *	1 for CQ Errors
13382367Smsmith *	1 for Asyncs and Command Completions, and finally
134209746Sjkim *	1 for All Other events.
13567754Smsmith *
13667754Smsmith * hs_intrmsi_allocd is the N in the above.
13767754Smsmith */
13867754Smsmith
13967754Smsmith#define	HERMON_CQ_EQNUM_GET(state)					\
14077424Smsmith	(state->hs_devlim.num_rsvd_eq +					\
14167754Smsmith	    (atomic_inc_uint_nv(&state->hs_eq_dist) %			\
14267754Smsmith	    state->hs_intrmsi_allocd))
14367754Smsmith
14467754Smsmith#define	HERMON_CQ_ERREQNUM_GET(state)					\
14567754Smsmith	(state->hs_devlim.num_rsvd_eq + state->hs_intrmsi_allocd)
14667754Smsmith/*
14767754Smsmith * The following defines are used for Hermon CQ error handling.  Note: For
14867754Smsmith * CQEs which correspond to error events, the Hermon device requires some
14967754Smsmith * special handling by software.  These defines are used to identify and
15067754Smsmith * extract the necessary information from each error CQE, including status
15177424Smsmith * code (above), doorbell count, and whether a error completion is for a
15277424Smsmith * send or receive work request.
15367754Smsmith */
15477424Smsmith
15567754Smsmith
15667754Smsmith#define	HERMON_CQE_ERR_STATUS_SHIFT	0
15767754Smsmith#define	HERMON_CQE_ERR_STATUS_MASK	0xFF
15873561Smsmith#define	HERMON_CQE_ERR_DBDCNT_MASK	0xFFFF
15967754Smsmith#define	HERMON_CQE_SEND_ERR_OPCODE	0x1E
16067754Smsmith#define	HERMON_CQE_RECV_ERR_OPCODE	0x1E
16167754Smsmith
16267754Smsmith/* Defines for tracking whether a CQ is being used with special QP or not */
16367754Smsmith#define	HERMON_CQ_IS_NORMAL		0
164167802Sjkim#define	HERMON_CQ_IS_SPECIAL		1
16567754Smsmith
16667754Smsmith/*
16799146Siwasaki * The hermon_sw_cq_s structure is also referred to using the "hermon_cqhdl_t"
16899146Siwasaki * typedef (see hermon_typedef.h).  It encodes all the information necessary
16967754Smsmith * to track the various resources needed to allocate, initialize, poll, resize,
17067754Smsmith * and (later) free a completion queue (CQ).
17167754Smsmith *
17267754Smsmith * Specifically, it has a consumer index and a lock to ensure single threaded
173138287Smarks * access to it.  It has pointers to the various resources allocated for the
174193267Sjkim * completion queue, i.e. a CQC resource and the memory for the completion
175193267Sjkim * queue itself. It also has a reference count and the number(s) of the EQs
17667754Smsmith * to which it is associated (for success and for errors).
177167802Sjkim *
178167802Sjkim * Additionally, it has a pointer to the associated MR handle (for the mapped
179167802Sjkim * queue memory) and a void pointer that holds the argument that should be
180199337Sjkim * passed back to the IBTF when events are generated on the CQ.
181123315Snjl *
182123315Snjl * We also have the always necessary backpointer to the resource for the
183167802Sjkim * CQ handle structure itself.  But we also have pointers to the "Work Request
184123315Snjl * ID" processing lists (both the lock and the regular list, as well as the
18567754Smsmith * head and tail for the "reapable" list).  See hermon_wrid.c for more details.
186167802Sjkim */
18767754Smsmith
188167802Sjkim#define	HERMON_CQ_DEF_UAR_DOORBELL	0x11	/* cmd_sn = 1, req solicited */
189167802Sjkim#define	HERMON_CD_DEF_UAR_DB_SHIFT	0x38	/* decimal 56 */
190167802Sjkim
191167802Sjkimstruct hermon_sw_cq_s {
192167802Sjkim	kmutex_t		cq_lock;
193167802Sjkim	struct hermon_sw_cq_s 	*cq_resize_hdl; /* points to tranistory hdl */
194167802Sjkim	uint32_t		cq_consindx;
195197104Sjkim	uint32_t		cq_cqnum;
196197104Sjkim	hermon_hw_cqe_t		*cq_buf;
197197104Sjkim	hermon_mrhdl_t		cq_mrhdl;
198197104Sjkim	uint32_t		cq_bufsz;
199197104Sjkim	uint32_t		cq_log_cqsz;
200197104Sjkim	uint_t			cq_refcnt;
201197104Sjkim	uint32_t		cq_eqnum;
202197104Sjkim	uint32_t		cq_erreqnum;
203197104Sjkim	uint_t			cq_is_special;
204197104Sjkim	uint_t			cq_is_umap;
205197104Sjkim	uint32_t		cq_uarpg;
206197104Sjkim	devmap_cookie_t		cq_umap_dhp;
207197104Sjkim	hermon_rsrc_t		*cq_cqcrsrcp;
208197104Sjkim	hermon_rsrc_t		*cq_rsrcp;
209197104Sjkim	uint_t			cq_intmod_count;
210197104Sjkim	uint_t			cq_intmod_usec;
211167802Sjkim
212167802Sjkim	/* DoorBell Record Information */
213123315Snjl	ddi_acc_handle_t	cq_arm_ci_dbr_acchdl;
214199337Sjkim	hermon_dbr_t		*cq_arm_ci_vdbr;
215123315Snjl	uint64_t		cq_arm_ci_pdbr;
216209746Sjkim	uint64_t		cq_dbr_mapoffset;	/* user mode access */
217209746Sjkim
218209746Sjkim	void			*cq_hdlrarg;
219209746Sjkim
220209746Sjkim	/* For Work Request ID processing */
221209746Sjkim	avl_tree_t		cq_wrid_wqhdr_avl_tree;
222209746Sjkim
223209746Sjkim	struct hermon_qalloc_info_s cq_cqinfo;
224209746Sjkim};
225209746Sjkim_NOTE(READ_ONLY_DATA(hermon_sw_cq_s::cq_cqnum
226167802Sjkim    hermon_sw_cq_s::cq_eqnum
22767754Smsmith    hermon_sw_cq_s::cq_erreqnum
22867754Smsmith    hermon_sw_cq_s::cq_cqcrsrcp
229167802Sjkim    hermon_sw_cq_s::cq_rsrcp
23067754Smsmith    hermon_sw_cq_s::cq_hdlrarg
23167754Smsmith    hermon_sw_cq_s::cq_is_umap
232114237Snjl    hermon_sw_cq_s::cq_uarpg))
233209746Sjkim_NOTE(DATA_READABLE_WITHOUT_LOCK(hermon_sw_cq_s::cq_bufsz
234209746Sjkim    hermon_sw_cq_s::cq_consindx
235167802Sjkim    hermon_sw_cq_s::cq_cqinfo))
23667754Smsmith_NOTE(MUTEX_PROTECTS_DATA(hermon_sw_cq_s::cq_lock,
23767754Smsmith    hermon_sw_cq_s::cq_buf
238167802Sjkim    hermon_sw_cq_s::cq_mrhdl
239167802Sjkim    hermon_sw_cq_s::cq_refcnt
240167802Sjkim    hermon_sw_cq_s::cq_is_special
241167802Sjkim    hermon_sw_cq_s::cq_umap_dhp))
242167802Sjkim_NOTE(SCHEME_PROTECTS_DATA("safe sharing",
24367754Smsmith    hermon_sw_cq_s::cq_intmod_count
24467754Smsmith    hermon_sw_cq_s::cq_intmod_usec
24567754Smsmith    hermon_sw_cq_s::cq_resize_hdl))
24667754Smsmith
24767754Smsmithint hermon_cq_alloc(hermon_state_t *state, ibt_cq_hdl_t ibt_cqhdl,
24867754Smsmith    ibt_cq_attr_t *attr_p, uint_t *actual_size, hermon_cqhdl_t *cqhdl,
24967754Smsmith    uint_t sleepflag);
25067754Smsmithint hermon_cq_free(hermon_state_t *state, hermon_cqhdl_t *cqhdl,
25167754Smsmith    uint_t sleepflag);
25267754Smsmithint hermon_cq_resize(hermon_state_t *state, hermon_cqhdl_t cqhdl,
25367754Smsmith    uint_t req_size, uint_t *actual_size, uint_t sleepflag);
25467754Smsmithint hermon_cq_modify(hermon_state_t *state, hermon_cqhdl_t cqhdl,
25567754Smsmith    uint_t count, uint_t usec, ibt_cq_handler_id_t hid, uint_t sleepflag);
25667754Smsmithint hermon_cq_notify(hermon_state_t *state, hermon_cqhdl_t cqhdl,
257241973Sjkim    ibt_cq_notify_flags_t flags);
25867754Smsmithint hermon_cq_poll(hermon_state_t *state, hermon_cqhdl_t cqhdl, ibt_wc_t *wc_p,
25967754Smsmith    uint_t num_wc, uint_t *num_polled);
26067754Smsmithint hermon_cq_handler(hermon_state_t *state, hermon_eqhdl_t eq,
26167754Smsmith    hermon_hw_eqe_t *eqe);
26267754Smsmithint hermon_cq_err_handler(hermon_state_t *state, hermon_eqhdl_t eq,
26367754Smsmith    hermon_hw_eqe_t *eqe);
26467754Smsmithint hermon_cq_refcnt_inc(hermon_cqhdl_t cq, uint_t is_special);
26567754Smsmithvoid hermon_cq_refcnt_dec(hermon_cqhdl_t cq);
266151937Sjkimhermon_cqhdl_t hermon_cqhdl_from_cqnum(hermon_state_t *state, uint_t cqnum);
26767754Smsmithvoid hermon_cq_entries_flush(hermon_state_t *state, hermon_qphdl_t qp);
26867754Smsmithvoid hermon_cq_resize_helper(hermon_state_t *state, hermon_cqhdl_t cq);
26967754Smsmith
27067754Smsmith#ifdef __cplusplus
27167754Smsmith}
27267754Smsmith#endif
27391116Smsmith
274167802Sjkim#endif	/* _SYS_IB_ADAPTERS_HERMON_CQ_H */
27567754Smsmith