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