xref: /onnv-gate/usr/src/uts/common/sys/ib/adapters/hermon/hermon_wr.h (revision 9517:b4839b0aa7a4)
1*9517SBill.Taylor@Sun.COM /*
2*9517SBill.Taylor@Sun.COM  * CDDL HEADER START
3*9517SBill.Taylor@Sun.COM  *
4*9517SBill.Taylor@Sun.COM  * The contents of this file are subject to the terms of the
5*9517SBill.Taylor@Sun.COM  * Common Development and Distribution License (the "License").
6*9517SBill.Taylor@Sun.COM  * You may not use this file except in compliance with the License.
7*9517SBill.Taylor@Sun.COM  *
8*9517SBill.Taylor@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9517SBill.Taylor@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*9517SBill.Taylor@Sun.COM  * See the License for the specific language governing permissions
11*9517SBill.Taylor@Sun.COM  * and limitations under the License.
12*9517SBill.Taylor@Sun.COM  *
13*9517SBill.Taylor@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*9517SBill.Taylor@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9517SBill.Taylor@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*9517SBill.Taylor@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*9517SBill.Taylor@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9517SBill.Taylor@Sun.COM  *
19*9517SBill.Taylor@Sun.COM  * CDDL HEADER END
20*9517SBill.Taylor@Sun.COM  */
21*9517SBill.Taylor@Sun.COM 
22*9517SBill.Taylor@Sun.COM /*
23*9517SBill.Taylor@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*9517SBill.Taylor@Sun.COM  * Use is subject to license terms.
25*9517SBill.Taylor@Sun.COM  */
26*9517SBill.Taylor@Sun.COM 
27*9517SBill.Taylor@Sun.COM #ifndef	_SYS_IB_ADAPTERS_HERMON_WR_H
28*9517SBill.Taylor@Sun.COM #define	_SYS_IB_ADAPTERS_HERMON_WR_H
29*9517SBill.Taylor@Sun.COM 
30*9517SBill.Taylor@Sun.COM /*
31*9517SBill.Taylor@Sun.COM  * hermon_wr.h
32*9517SBill.Taylor@Sun.COM  *    Contains all of the prototypes, #defines, and structures necessary
33*9517SBill.Taylor@Sun.COM  *    for the Hermon Work Request Processing Routines
34*9517SBill.Taylor@Sun.COM  *    Specifically it contains #defines, macros, and prototypes for each of
35*9517SBill.Taylor@Sun.COM  *    building each of the various types of WQE and for managing the WRID
36*9517SBill.Taylor@Sun.COM  *    tracking mechanisms.
37*9517SBill.Taylor@Sun.COM  */
38*9517SBill.Taylor@Sun.COM 
39*9517SBill.Taylor@Sun.COM #include <sys/types.h>
40*9517SBill.Taylor@Sun.COM #include <sys/conf.h>
41*9517SBill.Taylor@Sun.COM #include <sys/ddi.h>
42*9517SBill.Taylor@Sun.COM #include <sys/sunddi.h>
43*9517SBill.Taylor@Sun.COM 
44*9517SBill.Taylor@Sun.COM #ifdef __cplusplus
45*9517SBill.Taylor@Sun.COM extern "C" {
46*9517SBill.Taylor@Sun.COM #endif
47*9517SBill.Taylor@Sun.COM 
48*9517SBill.Taylor@Sun.COM /*
49*9517SBill.Taylor@Sun.COM  * WQEADDRSZ is a bit of a misnomer, it's really a token for the
50*9517SBill.Taylor@Sun.COM  * WRID processing.  We simply use the wqe_counter.
51*9517SBill.Taylor@Sun.COM  */
52*9517SBill.Taylor@Sun.COM #define	HERMON_QP_WQEADDRSZ(wcnt, qpn)	(wcnt) & 0xFFFF
53*9517SBill.Taylor@Sun.COM 
54*9517SBill.Taylor@Sun.COM /* And put the get from the CQ here as well	*/
55*9517SBill.Taylor@Sun.COM #define	HERMON_CQE_WQEADDRSZ_GET(cq, cqe)				\
56*9517SBill.Taylor@Sun.COM 	((uint32_t)((((uint8_t *)(cqe))[0x18]) << 8) | ((uint8_t *)(cqe))[0x19])
57*9517SBill.Taylor@Sun.COM 
58*9517SBill.Taylor@Sun.COM 
59*9517SBill.Taylor@Sun.COM /*
60*9517SBill.Taylor@Sun.COM  * The following macro sets the owner bit in the Control Segment of the
61*9517SBill.Taylor@Sun.COM  * WQE, based on the wqe_counter value passed in
62*9517SBill.Taylor@Sun.COM  */
63*9517SBill.Taylor@Sun.COM #define	HERMON_SET_SEND_WQE_OWNER(qp, desc, opcode)			\
64*9517SBill.Taylor@Sun.COM 	*(uint32_t *)desc = htonl((((*(uint8_t *)desc & 0x80) ^ 0x80) << 24) | \
65*9517SBill.Taylor@Sun.COM 	    opcode);
66*9517SBill.Taylor@Sun.COM 
67*9517SBill.Taylor@Sun.COM /*
68*9517SBill.Taylor@Sun.COM  * The following macros are used to calculate pointers to the Send or Receive
69*9517SBill.Taylor@Sun.COM  * (or SRQ) WQEs on a given QP, respectively
70*9517SBill.Taylor@Sun.COM  */
71*9517SBill.Taylor@Sun.COM #define	HERMON_QP_SQ_ENTRY(qp, tail)					\
72*9517SBill.Taylor@Sun.COM 	((uint64_t *)((uintptr_t)((qp)->qp_sq_buf) +			\
73*9517SBill.Taylor@Sun.COM 	((tail) << (qp)->qp_sq_log_wqesz)))
74*9517SBill.Taylor@Sun.COM #define	HERMON_QP_RQ_ENTRY(qp, tail)					\
75*9517SBill.Taylor@Sun.COM 	((uint64_t *)((uintptr_t)((qp)->qp_rq_buf) +			\
76*9517SBill.Taylor@Sun.COM 	((tail) << (qp)->qp_rq_log_wqesz)))
77*9517SBill.Taylor@Sun.COM #define	HERMON_SRQ_WQ_ENTRY(srq, tail)					\
78*9517SBill.Taylor@Sun.COM 	((uint64_t *)((uintptr_t)((srq)->srq_wq_buf) +			\
79*9517SBill.Taylor@Sun.COM 	((tail) << (srq)->srq_wq_log_wqesz)))
80*9517SBill.Taylor@Sun.COM 
81*9517SBill.Taylor@Sun.COM /*
82*9517SBill.Taylor@Sun.COM  * The following macro is used to calculate the 'wqe_index' field during SRQ
83*9517SBill.Taylor@Sun.COM  * operation.  This returns the index based on the WQE size, that can be used
84*9517SBill.Taylor@Sun.COM  * to reference WQEs in an SRQ.
85*9517SBill.Taylor@Sun.COM  */
86*9517SBill.Taylor@Sun.COM #define	HERMON_SRQ_WQE_INDEX(srq_base_addr, wqe_addr, log_wqesz)	\
87*9517SBill.Taylor@Sun.COM 	(((uint32_t)(uintptr_t)wqe_addr -				\
88*9517SBill.Taylor@Sun.COM 	(uint32_t)(uintptr_t)srq_base_addr) >> log_wqesz)
89*9517SBill.Taylor@Sun.COM /*
90*9517SBill.Taylor@Sun.COM  * The following macro is used to calculate the 'wqe_addr' during SRQ
91*9517SBill.Taylor@Sun.COM  * operation.  This returns the addr based on the WQE size and index,
92*9517SBill.Taylor@Sun.COM  * that can be used to reference WQEs in an SRQ.
93*9517SBill.Taylor@Sun.COM  */
94*9517SBill.Taylor@Sun.COM 
95*9517SBill.Taylor@Sun.COM #define	HERMON_SRQ_WQE_ADDR(srq, wqe_index)				\
96*9517SBill.Taylor@Sun.COM 	((uint64_t *)((uintptr_t)srq->srq_wq_buf +			\
97*9517SBill.Taylor@Sun.COM 	(wqe_index << srq->srq_wq_log_wqesz)))
98*9517SBill.Taylor@Sun.COM 
99*9517SBill.Taylor@Sun.COM /*
100*9517SBill.Taylor@Sun.COM  * The following macros are used to access specific fields in Directed Route
101*9517SBill.Taylor@Sun.COM  * MAD packets.  We can extract the MgmtClass, "hop pointer", and "hop count".
102*9517SBill.Taylor@Sun.COM  * We can also update the "hop pointer" as appropriate.  Note:  Again, because
103*9517SBill.Taylor@Sun.COM  * of the limited amount of direct handling the Hermon hardware does on special
104*9517SBill.Taylor@Sun.COM  * QP request (specifically on Directed Route MADs), the driver needs to
105*9517SBill.Taylor@Sun.COM  * update (as necessary) the "hop pointer" value depending on whether a MAD
106*9517SBill.Taylor@Sun.COM  * is outbound or inbound (i.e. depending on the relationship between "hop
107*9517SBill.Taylor@Sun.COM  * pointer" and "hop count" in the given MAD)
108*9517SBill.Taylor@Sun.COM  */
109*9517SBill.Taylor@Sun.COM #define	HERMON_SPECIAL_QP_DRMAD_GET_MGMTCLASS(mgmtclass, offset, va, len) \
110*9517SBill.Taylor@Sun.COM 	if (((mgmtclass) == NULL) && ((offset) + (len) > 1)) {		 \
111*9517SBill.Taylor@Sun.COM 	    (mgmtclass) = &((uint8_t *)(uintptr_t)(va))[1 - (offset)];	 \
112*9517SBill.Taylor@Sun.COM 	}
113*9517SBill.Taylor@Sun.COM #define	HERMON_SPECIAL_QP_DRMAD_GET_HOPPOINTER(hp, offset, va, len)	\
114*9517SBill.Taylor@Sun.COM 	if (((hp) == NULL) &&					  	\
115*9517SBill.Taylor@Sun.COM 	    ((offset) + (len) > 6)) {					\
116*9517SBill.Taylor@Sun.COM 	    (hp) = &((uint8_t *)(uintptr_t)(va))[6 - (offset)];		\
117*9517SBill.Taylor@Sun.COM 	}
118*9517SBill.Taylor@Sun.COM #define	HERMON_SPECIAL_QP_DRMAD_GET_HOPCOUNT(hc, offset, va, len)	\
119*9517SBill.Taylor@Sun.COM 	if (((hc) == NULL) &&						\
120*9517SBill.Taylor@Sun.COM 	    ((offset) + (len) > 7)) {					\
121*9517SBill.Taylor@Sun.COM 	    (hc) = &((uint8_t *)(uintptr_t)(va))[7 - (offset)];		\
122*9517SBill.Taylor@Sun.COM 	}
123*9517SBill.Taylor@Sun.COM #define	HERMON_SPECIAL_QP_DRMAD_DO_HOPPOINTER_MODIFY(mgmtclass, hp, hc)	\
124*9517SBill.Taylor@Sun.COM 	if ((mgmtclass) == 0x81) {					\
125*9517SBill.Taylor@Sun.COM 		if ((hp) < (hc)) {					\
126*9517SBill.Taylor@Sun.COM 			(hp) = (hp) + 1;				\
127*9517SBill.Taylor@Sun.COM 		} else if ((hp) > (hc)) {				\
128*9517SBill.Taylor@Sun.COM 			(hp) = (hp) - 1;				\
129*9517SBill.Taylor@Sun.COM 		}							\
130*9517SBill.Taylor@Sun.COM 	}
131*9517SBill.Taylor@Sun.COM 
132*9517SBill.Taylor@Sun.COM /*
133*9517SBill.Taylor@Sun.COM  * The hermon_workq_hdr_s structure is used internally by the Hermon driver
134*9517SBill.Taylor@Sun.COM  * to track the information necessary to manage the work queues (send, recv,
135*9517SBill.Taylor@Sun.COM  * or shared recv).  The hermon_workq_avl_s is used for each association of
136*9517SBill.Taylor@Sun.COM  * a work queue with a given completion queue, where SRQs can be associated
137*9517SBill.Taylor@Sun.COM  * with multiple queue pairs and their associated completion queues.
138*9517SBill.Taylor@Sun.COM  */
139*9517SBill.Taylor@Sun.COM struct hermon_workq_hdr_s {
140*9517SBill.Taylor@Sun.COM 	uint32_t		wq_size;
141*9517SBill.Taylor@Sun.COM 	uint32_t		wq_mask;
142*9517SBill.Taylor@Sun.COM 	ibt_wrid_t		*wq_wrid;
143*9517SBill.Taylor@Sun.COM 	uint32_t		wq_head;
144*9517SBill.Taylor@Sun.COM 	uint32_t		wq_tail;
145*9517SBill.Taylor@Sun.COM 	uint32_t		wq_full;
146*9517SBill.Taylor@Sun.COM };
147*9517SBill.Taylor@Sun.COM 
148*9517SBill.Taylor@Sun.COM _NOTE(SCHEME_PROTECTS_DATA("safe sharing",
149*9517SBill.Taylor@Sun.COM     hermon_workq_hdr_s::wq_wrid
150*9517SBill.Taylor@Sun.COM     hermon_workq_hdr_s::wq_head
151*9517SBill.Taylor@Sun.COM     hermon_workq_hdr_s::wq_tail
152*9517SBill.Taylor@Sun.COM     hermon_workq_hdr_s::wq_full))
153*9517SBill.Taylor@Sun.COM 
154*9517SBill.Taylor@Sun.COM struct hermon_workq_avl_s {
155*9517SBill.Taylor@Sun.COM 	avl_node_t		wqa_link;
156*9517SBill.Taylor@Sun.COM 	uint32_t		wqa_qpn;
157*9517SBill.Taylor@Sun.COM 	uint32_t		wqa_type;	/* send or recv */
158*9517SBill.Taylor@Sun.COM 	struct hermon_workq_hdr_s *wqa_wq;
159*9517SBill.Taylor@Sun.COM 
160*9517SBill.Taylor@Sun.COM 	/* For SRQ, this is needed to add the wqe to the free list */
161*9517SBill.Taylor@Sun.COM 	uint_t			wqa_srq_en;
162*9517SBill.Taylor@Sun.COM 	hermon_srqhdl_t		wqa_srq;
163*9517SBill.Taylor@Sun.COM };
164*9517SBill.Taylor@Sun.COM 
165*9517SBill.Taylor@Sun.COM #define	HERMON_WR_RECV			0x0
166*9517SBill.Taylor@Sun.COM #define	HERMON_WR_SEND			0x1
167*9517SBill.Taylor@Sun.COM #define	HERMON_WR_SRQ			0x2
168*9517SBill.Taylor@Sun.COM 
169*9517SBill.Taylor@Sun.COM extern int hermon_wrid_workq_compare(const void *p1, const void *p2);
170*9517SBill.Taylor@Sun.COM typedef struct hermon_workq_compare_s {
171*9517SBill.Taylor@Sun.COM 	uint32_t cmp_type;
172*9517SBill.Taylor@Sun.COM 	uint32_t cmp_qpn;
173*9517SBill.Taylor@Sun.COM } hermon_workq_compare_t;
174*9517SBill.Taylor@Sun.COM 
175*9517SBill.Taylor@Sun.COM /* For Work Request posting */
176*9517SBill.Taylor@Sun.COM int hermon_post_send(hermon_state_t *state, hermon_qphdl_t qphdl,
177*9517SBill.Taylor@Sun.COM     ibt_send_wr_t *wr_p, uint_t num_wr, uint_t *num_posted);
178*9517SBill.Taylor@Sun.COM int hermon_post_recv(hermon_state_t *state, hermon_qphdl_t qphdl,
179*9517SBill.Taylor@Sun.COM     ibt_recv_wr_t *wr_p, uint_t num_wr, uint_t *num_posted);
180*9517SBill.Taylor@Sun.COM int hermon_post_srq(hermon_state_t *state, hermon_srqhdl_t srqhdl,
181*9517SBill.Taylor@Sun.COM     ibt_recv_wr_t *wr_p, uint_t num_wr, uint_t *num_posted);
182*9517SBill.Taylor@Sun.COM 
183*9517SBill.Taylor@Sun.COM /* For WRID handling */
184*9517SBill.Taylor@Sun.COM int hermon_wrid_from_reset_handling(hermon_state_t *state, hermon_qphdl_t qp);
185*9517SBill.Taylor@Sun.COM int hermon_wrid_to_reset_handling(hermon_state_t *state, hermon_qphdl_t qp);
186*9517SBill.Taylor@Sun.COM ibt_wrid_t hermon_wrid_get_entry(hermon_cqhdl_t cqhdl, hermon_hw_cqe_t *cqe);
187*9517SBill.Taylor@Sun.COM hermon_workq_hdr_t *hermon_wrid_wqhdr_create(int bufsz);
188*9517SBill.Taylor@Sun.COM void hermon_wrid_wqhdr_destroy(hermon_workq_hdr_t *wqhdr);
189*9517SBill.Taylor@Sun.COM 
190*9517SBill.Taylor@Sun.COM /* debug routine */
191*9517SBill.Taylor@Sun.COM void hermon_check_qp_debug(hermon_state_t *state, hermon_qphdl_t qp);
192*9517SBill.Taylor@Sun.COM 
193*9517SBill.Taylor@Sun.COM 
194*9517SBill.Taylor@Sun.COM #ifdef __cplusplus
195*9517SBill.Taylor@Sun.COM }
196*9517SBill.Taylor@Sun.COM #endif
197*9517SBill.Taylor@Sun.COM 
198*9517SBill.Taylor@Sun.COM #endif	/* _SYS_IB_ADAPTERS_HERMON_WR_H */
199