1*12965SWilliam.Taylor@Oracle.COM /*
2*12965SWilliam.Taylor@Oracle.COM * CDDL HEADER START
3*12965SWilliam.Taylor@Oracle.COM *
4*12965SWilliam.Taylor@Oracle.COM * The contents of this file are subject to the terms of the
5*12965SWilliam.Taylor@Oracle.COM * Common Development and Distribution License (the "License").
6*12965SWilliam.Taylor@Oracle.COM * You may not use this file except in compliance with the License.
7*12965SWilliam.Taylor@Oracle.COM *
8*12965SWilliam.Taylor@Oracle.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12965SWilliam.Taylor@Oracle.COM * or http://www.opensolaris.org/os/licensing.
10*12965SWilliam.Taylor@Oracle.COM * See the License for the specific language governing permissions
11*12965SWilliam.Taylor@Oracle.COM * and limitations under the License.
12*12965SWilliam.Taylor@Oracle.COM *
13*12965SWilliam.Taylor@Oracle.COM * When distributing Covered Code, include this CDDL HEADER in each
14*12965SWilliam.Taylor@Oracle.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12965SWilliam.Taylor@Oracle.COM * If applicable, add the following below this CDDL HEADER, with the
16*12965SWilliam.Taylor@Oracle.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*12965SWilliam.Taylor@Oracle.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*12965SWilliam.Taylor@Oracle.COM *
19*12965SWilliam.Taylor@Oracle.COM * CDDL HEADER END
20*12965SWilliam.Taylor@Oracle.COM */
21*12965SWilliam.Taylor@Oracle.COM
22*12965SWilliam.Taylor@Oracle.COM /*
23*12965SWilliam.Taylor@Oracle.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*12965SWilliam.Taylor@Oracle.COM */
25*12965SWilliam.Taylor@Oracle.COM
26*12965SWilliam.Taylor@Oracle.COM /*
27*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib.c
28*12965SWilliam.Taylor@Oracle.COM * Hermon Fibre Channel over IB routines
29*12965SWilliam.Taylor@Oracle.COM *
30*12965SWilliam.Taylor@Oracle.COM * Implements all the routines necessary for setting up, using, and
31*12965SWilliam.Taylor@Oracle.COM * (later) tearing down all the FCoIB state.
32*12965SWilliam.Taylor@Oracle.COM */
33*12965SWilliam.Taylor@Oracle.COM
34*12965SWilliam.Taylor@Oracle.COM #include <sys/ib/adapters/hermon/hermon.h>
35*12965SWilliam.Taylor@Oracle.COM
36*12965SWilliam.Taylor@Oracle.COM /*
37*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_enable()
38*12965SWilliam.Taylor@Oracle.COM * Context: user or kernel context
39*12965SWilliam.Taylor@Oracle.COM */
40*12965SWilliam.Taylor@Oracle.COM static int
hermon_fcoib_enable(hermon_state_t * state,int port)41*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_enable(hermon_state_t *state, int port)
42*12965SWilliam.Taylor@Oracle.COM {
43*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
44*12965SWilliam.Taylor@Oracle.COM hermon_hw_config_fc_basic_t config_fc_basic;
45*12965SWilliam.Taylor@Oracle.COM int status;
46*12965SWilliam.Taylor@Oracle.COM
47*12965SWilliam.Taylor@Oracle.COM port--; /* passed in as 1 or 2, used as 0 or 1 */
48*12965SWilliam.Taylor@Oracle.COM ASSERT(port >= 0 && port < HERMON_MAX_PORTS);
49*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
50*12965SWilliam.Taylor@Oracle.COM
51*12965SWilliam.Taylor@Oracle.COM /* Configure FCoIB on the port */
52*12965SWilliam.Taylor@Oracle.COM bzero(&config_fc_basic, sizeof (config_fc_basic));
53*12965SWilliam.Taylor@Oracle.COM config_fc_basic.fexch_base_hi = fcoib->hfc_fexch_base[port] >> 16;
54*12965SWilliam.Taylor@Oracle.COM config_fc_basic.fx_base_mpt_hi = fcoib->hfc_mpt_base[port] >> 17;
55*12965SWilliam.Taylor@Oracle.COM config_fc_basic.fx_base_mpt_lo = 0;
56*12965SWilliam.Taylor@Oracle.COM config_fc_basic.log2_num_rfci =
57*12965SWilliam.Taylor@Oracle.COM state->hs_ibtfinfo.hca_attr->hca_rfci_max_log2_qp;
58*12965SWilliam.Taylor@Oracle.COM config_fc_basic.rfci_base = fcoib->hfc_rfci_qps_per_port * port +
59*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_rfci_rsrc->hr_indx;
60*12965SWilliam.Taylor@Oracle.COM #if 1
61*12965SWilliam.Taylor@Oracle.COM status = hermon_config_fc_cmd_post(state, &config_fc_basic, 1,
62*12965SWilliam.Taylor@Oracle.COM HERMON_HW_FC_CONF_BASIC, 0, port + 1, HERMON_CMD_NOSLEEP_SPIN);
63*12965SWilliam.Taylor@Oracle.COM #else
64*12965SWilliam.Taylor@Oracle.COM status = hermon_config_fc_cmd_post(state, &config_fc_basic, 1,
65*12965SWilliam.Taylor@Oracle.COM HERMON_HW_FC_CONF_BASIC, 0, 0, HERMON_CMD_NOSLEEP_SPIN);
66*12965SWilliam.Taylor@Oracle.COM #endif
67*12965SWilliam.Taylor@Oracle.COM if (status != HERMON_CMD_SUCCESS) {
68*12965SWilliam.Taylor@Oracle.COM cmn_err(CE_CONT, "fcoib_enable failed: status 0x%x\n", status);
69*12965SWilliam.Taylor@Oracle.COM HERMON_WARNING(state, "fcoib_enable failed");
70*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
71*12965SWilliam.Taylor@Oracle.COM }
72*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_port_enabled[port] = 1;
73*12965SWilliam.Taylor@Oracle.COM state->hs_fcoib_may_be_running = B_TRUE;
74*12965SWilliam.Taylor@Oracle.COM return (DDI_SUCCESS);
75*12965SWilliam.Taylor@Oracle.COM }
76*12965SWilliam.Taylor@Oracle.COM
77*12965SWilliam.Taylor@Oracle.COM /*
78*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_set_id()
79*12965SWilliam.Taylor@Oracle.COM * Context: user or kernel context
80*12965SWilliam.Taylor@Oracle.COM */
81*12965SWilliam.Taylor@Oracle.COM int
hermon_fcoib_set_id(hermon_state_t * state,int port,uint32_t rfci_qpn,uint32_t src_id)82*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_set_id(hermon_state_t *state, int port, uint32_t rfci_qpn,
83*12965SWilliam.Taylor@Oracle.COM uint32_t src_id)
84*12965SWilliam.Taylor@Oracle.COM {
85*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
86*12965SWilliam.Taylor@Oracle.COM int status;
87*12965SWilliam.Taylor@Oracle.COM int offset;
88*12965SWilliam.Taylor@Oracle.COM uint32_t *n_port_ids;
89*12965SWilliam.Taylor@Oracle.COM
90*12965SWilliam.Taylor@Oracle.COM port--; /* passed in as 1 or 2, used as 0 or 1 */
91*12965SWilliam.Taylor@Oracle.COM ASSERT(port >= 0 && port < HERMON_MAX_PORTS);
92*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
93*12965SWilliam.Taylor@Oracle.COM mutex_enter(&fcoib->hfc_lock);
94*12965SWilliam.Taylor@Oracle.COM
95*12965SWilliam.Taylor@Oracle.COM if (fcoib->hfc_port_enabled[port] == 0) {
96*12965SWilliam.Taylor@Oracle.COM if (hermon_fcoib_enable(state, port + 1) != DDI_SUCCESS) {
97*12965SWilliam.Taylor@Oracle.COM mutex_exit(&fcoib->hfc_lock);
98*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
99*12965SWilliam.Taylor@Oracle.COM }
100*12965SWilliam.Taylor@Oracle.COM }
101*12965SWilliam.Taylor@Oracle.COM
102*12965SWilliam.Taylor@Oracle.COM n_port_ids = fcoib->hfc_n_port_ids[port];
103*12965SWilliam.Taylor@Oracle.COM offset = rfci_qpn - fcoib->hfc_rfci_base[port];
104*12965SWilliam.Taylor@Oracle.COM ASSERT(offset >= 0 && offset < fcoib->hfc_rfci_qps_per_port);
105*12965SWilliam.Taylor@Oracle.COM n_port_ids[offset] = src_id;
106*12965SWilliam.Taylor@Oracle.COM
107*12965SWilliam.Taylor@Oracle.COM status = hermon_config_fc_cmd_post(state, n_port_ids, 1,
108*12965SWilliam.Taylor@Oracle.COM HERMON_HW_FC_CONF_NPORT, fcoib->hfc_rfci_qps_per_port,
109*12965SWilliam.Taylor@Oracle.COM port + 1, HERMON_CMD_NOSLEEP_SPIN);
110*12965SWilliam.Taylor@Oracle.COM if (status != HERMON_CMD_SUCCESS) {
111*12965SWilliam.Taylor@Oracle.COM HERMON_WARNING(state, "fcoib_set_id failed");
112*12965SWilliam.Taylor@Oracle.COM mutex_exit(&fcoib->hfc_lock);
113*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
114*12965SWilliam.Taylor@Oracle.COM }
115*12965SWilliam.Taylor@Oracle.COM mutex_exit(&fcoib->hfc_lock);
116*12965SWilliam.Taylor@Oracle.COM return (DDI_SUCCESS);
117*12965SWilliam.Taylor@Oracle.COM }
118*12965SWilliam.Taylor@Oracle.COM
119*12965SWilliam.Taylor@Oracle.COM /*
120*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_get_id_idx()
121*12965SWilliam.Taylor@Oracle.COM * Context: user or kernel context
122*12965SWilliam.Taylor@Oracle.COM */
123*12965SWilliam.Taylor@Oracle.COM int
hermon_fcoib_get_id_idx(hermon_state_t * state,int port,ibt_fc_attr_t * fcp)124*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_get_id_idx(hermon_state_t *state, int port, ibt_fc_attr_t *fcp)
125*12965SWilliam.Taylor@Oracle.COM {
126*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
127*12965SWilliam.Taylor@Oracle.COM int idx;
128*12965SWilliam.Taylor@Oracle.COM
129*12965SWilliam.Taylor@Oracle.COM port--; /* passed in as 1 or 2, used as 0 or 1 */
130*12965SWilliam.Taylor@Oracle.COM ASSERT(port >= 0 && port < HERMON_MAX_PORTS);
131*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
132*12965SWilliam.Taylor@Oracle.COM
133*12965SWilliam.Taylor@Oracle.COM idx = fcp->fc_rfci_qpn - fcoib->hfc_rfci_base[port];
134*12965SWilliam.Taylor@Oracle.COM if (idx < 0 || idx >= fcoib->hfc_rfci_qps_per_port)
135*12965SWilliam.Taylor@Oracle.COM idx = -1;
136*12965SWilliam.Taylor@Oracle.COM
137*12965SWilliam.Taylor@Oracle.COM return (idx);
138*12965SWilliam.Taylor@Oracle.COM }
139*12965SWilliam.Taylor@Oracle.COM
140*12965SWilliam.Taylor@Oracle.COM /*
141*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_get_exch_base()
142*12965SWilliam.Taylor@Oracle.COM * Context: user or kernel context
143*12965SWilliam.Taylor@Oracle.COM */
144*12965SWilliam.Taylor@Oracle.COM int
hermon_fcoib_check_exch_base_off(hermon_state_t * state,int port,ibt_fc_attr_t * fcp)145*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_check_exch_base_off(hermon_state_t *state, int port,
146*12965SWilliam.Taylor@Oracle.COM ibt_fc_attr_t *fcp)
147*12965SWilliam.Taylor@Oracle.COM {
148*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
149*12965SWilliam.Taylor@Oracle.COM int exch_base_off;
150*12965SWilliam.Taylor@Oracle.COM
151*12965SWilliam.Taylor@Oracle.COM port--; /* passed in as 1 or 2, used as 0 or 1 */
152*12965SWilliam.Taylor@Oracle.COM ASSERT(port >= 0 && port < HERMON_MAX_PORTS);
153*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
154*12965SWilliam.Taylor@Oracle.COM
155*12965SWilliam.Taylor@Oracle.COM exch_base_off = fcp->fc_exch_base_off;
156*12965SWilliam.Taylor@Oracle.COM if (exch_base_off >= fcoib->hfc_fexch_qps_per_port)
157*12965SWilliam.Taylor@Oracle.COM exch_base_off = -1;
158*12965SWilliam.Taylor@Oracle.COM
159*12965SWilliam.Taylor@Oracle.COM return (exch_base_off);
160*12965SWilliam.Taylor@Oracle.COM }
161*12965SWilliam.Taylor@Oracle.COM
162*12965SWilliam.Taylor@Oracle.COM /*
163*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_qpnum_from_fexch()
164*12965SWilliam.Taylor@Oracle.COM * Context: user, kernel, or interrupt context
165*12965SWilliam.Taylor@Oracle.COM */
166*12965SWilliam.Taylor@Oracle.COM int
hermon_fcoib_is_fexch_qpn(hermon_state_t * state,uint_t qpnum)167*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_is_fexch_qpn(hermon_state_t *state, uint_t qpnum)
168*12965SWilliam.Taylor@Oracle.COM {
169*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
170*12965SWilliam.Taylor@Oracle.COM
171*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
172*12965SWilliam.Taylor@Oracle.COM qpnum -= fcoib->hfc_fexch_rsrc->hr_indx;
173*12965SWilliam.Taylor@Oracle.COM return (qpnum < fcoib->hfc_nports * fcoib->hfc_fexch_qps_per_port);
174*12965SWilliam.Taylor@Oracle.COM }
175*12965SWilliam.Taylor@Oracle.COM
176*12965SWilliam.Taylor@Oracle.COM /*
177*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_qpnum_from_fexch()
178*12965SWilliam.Taylor@Oracle.COM * Context: user, kernel, or interrupt context
179*12965SWilliam.Taylor@Oracle.COM */
180*12965SWilliam.Taylor@Oracle.COM uint_t
hermon_fcoib_qpnum_from_fexch(hermon_state_t * state,int port,uint16_t fexch)181*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_qpnum_from_fexch(hermon_state_t *state, int port,
182*12965SWilliam.Taylor@Oracle.COM uint16_t fexch)
183*12965SWilliam.Taylor@Oracle.COM {
184*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
185*12965SWilliam.Taylor@Oracle.COM uint_t qpnum;
186*12965SWilliam.Taylor@Oracle.COM
187*12965SWilliam.Taylor@Oracle.COM port--; /* passed in as 1 or 2, used as 0 or 1 */
188*12965SWilliam.Taylor@Oracle.COM ASSERT(port >= 0 && port < HERMON_MAX_PORTS);
189*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
190*12965SWilliam.Taylor@Oracle.COM qpnum = fexch + fcoib->hfc_fexch_base[port];
191*12965SWilliam.Taylor@Oracle.COM return (qpnum);
192*12965SWilliam.Taylor@Oracle.COM }
193*12965SWilliam.Taylor@Oracle.COM
194*12965SWilliam.Taylor@Oracle.COM /*
195*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_qpn_to_mkey
196*12965SWilliam.Taylor@Oracle.COM * Context: user or kernel context
197*12965SWilliam.Taylor@Oracle.COM */
198*12965SWilliam.Taylor@Oracle.COM uint32_t
hermon_fcoib_qpn_to_mkey(hermon_state_t * state,uint_t qpnum)199*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_qpn_to_mkey(hermon_state_t *state, uint_t qpnum)
200*12965SWilliam.Taylor@Oracle.COM {
201*12965SWilliam.Taylor@Oracle.COM int i;
202*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
203*12965SWilliam.Taylor@Oracle.COM uint32_t qp_indx;
204*12965SWilliam.Taylor@Oracle.COM
205*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
206*12965SWilliam.Taylor@Oracle.COM for (i = 0; i < fcoib->hfc_nports; i++) {
207*12965SWilliam.Taylor@Oracle.COM qp_indx = qpnum - fcoib->hfc_fexch_base[i];
208*12965SWilliam.Taylor@Oracle.COM if (qp_indx < fcoib->hfc_fexch_qps_per_port)
209*12965SWilliam.Taylor@Oracle.COM return ((qp_indx + fcoib->hfc_mpt_base[i]) << 8);
210*12965SWilliam.Taylor@Oracle.COM }
211*12965SWilliam.Taylor@Oracle.COM return ((uint32_t)-1); /* cannot get here with valid qpnum argument */
212*12965SWilliam.Taylor@Oracle.COM }
213*12965SWilliam.Taylor@Oracle.COM
214*12965SWilliam.Taylor@Oracle.COM /*
215*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_fexch_relative_qpn()
216*12965SWilliam.Taylor@Oracle.COM * Context: user or kernel context
217*12965SWilliam.Taylor@Oracle.COM */
218*12965SWilliam.Taylor@Oracle.COM uint32_t
hermon_fcoib_fexch_relative_qpn(hermon_state_t * state,uint8_t port,uint32_t qp_indx)219*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_fexch_relative_qpn(hermon_state_t *state, uint8_t port,
220*12965SWilliam.Taylor@Oracle.COM uint32_t qp_indx)
221*12965SWilliam.Taylor@Oracle.COM {
222*12965SWilliam.Taylor@Oracle.COM port--;
223*12965SWilliam.Taylor@Oracle.COM ASSERT(port < HERMON_MAX_PORTS);
224*12965SWilliam.Taylor@Oracle.COM qp_indx -= state->hs_fcoib.hfc_fexch_base[port];
225*12965SWilliam.Taylor@Oracle.COM return (qp_indx);
226*12965SWilliam.Taylor@Oracle.COM }
227*12965SWilliam.Taylor@Oracle.COM
228*12965SWilliam.Taylor@Oracle.COM /*
229*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_fexch_mkey_init()
230*12965SWilliam.Taylor@Oracle.COM * Context: user or kernel context
231*12965SWilliam.Taylor@Oracle.COM */
232*12965SWilliam.Taylor@Oracle.COM int
hermon_fcoib_fexch_mkey_init(hermon_state_t * state,hermon_pdhdl_t pd,uint8_t port,uint32_t qp_indx,uint_t sleep)233*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_fexch_mkey_init(hermon_state_t *state, hermon_pdhdl_t pd,
234*12965SWilliam.Taylor@Oracle.COM uint8_t port, uint32_t qp_indx, uint_t sleep)
235*12965SWilliam.Taylor@Oracle.COM {
236*12965SWilliam.Taylor@Oracle.COM int status;
237*12965SWilliam.Taylor@Oracle.COM uint32_t mpt_indx;
238*12965SWilliam.Taylor@Oracle.COM uint_t nummtt;
239*12965SWilliam.Taylor@Oracle.COM uint64_t mtt_addr;
240*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
241*12965SWilliam.Taylor@Oracle.COM
242*12965SWilliam.Taylor@Oracle.COM port--;
243*12965SWilliam.Taylor@Oracle.COM ASSERT(port < HERMON_MAX_PORTS);
244*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
245*12965SWilliam.Taylor@Oracle.COM qp_indx -= fcoib->hfc_fexch_base[port]; /* relative to FEXCH base */
246*12965SWilliam.Taylor@Oracle.COM if (qp_indx > fcoib->hfc_fexch_qps_per_port)
247*12965SWilliam.Taylor@Oracle.COM return (IBT_INVALID_PARAM);
248*12965SWilliam.Taylor@Oracle.COM mpt_indx = qp_indx + fcoib->hfc_mpt_base[port];
249*12965SWilliam.Taylor@Oracle.COM nummtt = fcoib->hfc_mtts_per_mpt;
250*12965SWilliam.Taylor@Oracle.COM mtt_addr = ((uint64_t)qp_indx * nummtt + fcoib->hfc_mtt_base[port]) <<
251*12965SWilliam.Taylor@Oracle.COM HERMON_MTT_SIZE_SHIFT;
252*12965SWilliam.Taylor@Oracle.COM
253*12965SWilliam.Taylor@Oracle.COM status = hermon_mr_fexch_mpt_init(state, pd, mpt_indx,
254*12965SWilliam.Taylor@Oracle.COM nummtt, mtt_addr, sleep);
255*12965SWilliam.Taylor@Oracle.COM return (status);
256*12965SWilliam.Taylor@Oracle.COM }
257*12965SWilliam.Taylor@Oracle.COM
258*12965SWilliam.Taylor@Oracle.COM /*
259*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_fexch_mkey_fini()
260*12965SWilliam.Taylor@Oracle.COM * Context: user or kernel context
261*12965SWilliam.Taylor@Oracle.COM */
262*12965SWilliam.Taylor@Oracle.COM int
hermon_fcoib_fexch_mkey_fini(hermon_state_t * state,hermon_pdhdl_t pd,uint32_t qpnum,uint_t sleep)263*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_fexch_mkey_fini(hermon_state_t *state, hermon_pdhdl_t pd,
264*12965SWilliam.Taylor@Oracle.COM uint32_t qpnum, uint_t sleep)
265*12965SWilliam.Taylor@Oracle.COM {
266*12965SWilliam.Taylor@Oracle.COM int status;
267*12965SWilliam.Taylor@Oracle.COM uint8_t port;
268*12965SWilliam.Taylor@Oracle.COM uint32_t qp_indx;
269*12965SWilliam.Taylor@Oracle.COM uint32_t mpt_indx;
270*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
271*12965SWilliam.Taylor@Oracle.COM
272*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
273*12965SWilliam.Taylor@Oracle.COM for (port = 0; port < fcoib->hfc_nports; port++) {
274*12965SWilliam.Taylor@Oracle.COM qp_indx = qpnum - fcoib->hfc_fexch_base[port];
275*12965SWilliam.Taylor@Oracle.COM if (qp_indx < fcoib->hfc_fexch_qps_per_port)
276*12965SWilliam.Taylor@Oracle.COM goto found;
277*12965SWilliam.Taylor@Oracle.COM }
278*12965SWilliam.Taylor@Oracle.COM return (IBT_INVALID_PARAM);
279*12965SWilliam.Taylor@Oracle.COM found:
280*12965SWilliam.Taylor@Oracle.COM /* qp_indx relative to FEXCH base */
281*12965SWilliam.Taylor@Oracle.COM mpt_indx = qp_indx + fcoib->hfc_mpt_base[port];
282*12965SWilliam.Taylor@Oracle.COM
283*12965SWilliam.Taylor@Oracle.COM status = hermon_mr_fexch_mpt_fini(state, pd, mpt_indx, sleep);
284*12965SWilliam.Taylor@Oracle.COM return (status);
285*12965SWilliam.Taylor@Oracle.COM }
286*12965SWilliam.Taylor@Oracle.COM
287*12965SWilliam.Taylor@Oracle.COM /*
288*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_query_fc()
289*12965SWilliam.Taylor@Oracle.COM * Context: user or kernel context
290*12965SWilliam.Taylor@Oracle.COM */
291*12965SWilliam.Taylor@Oracle.COM void
hermon_fcoib_query_fc(hermon_state_t * state,hermon_fcoib_t * fcoib)292*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_query_fc(hermon_state_t *state, hermon_fcoib_t *fcoib)
293*12965SWilliam.Taylor@Oracle.COM {
294*12965SWilliam.Taylor@Oracle.COM int status;
295*12965SWilliam.Taylor@Oracle.COM struct hermon_hw_query_fc_s query_fc;
296*12965SWilliam.Taylor@Oracle.COM
297*12965SWilliam.Taylor@Oracle.COM status = hermon_cmn_query_cmd_post(state, QUERY_FC, 0, 0, &query_fc,
298*12965SWilliam.Taylor@Oracle.COM sizeof (query_fc), HERMON_CMD_NOSLEEP_SPIN);
299*12965SWilliam.Taylor@Oracle.COM if (status == HERMON_CMD_SUCCESS) {
300*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_log2_max_port_ids_queried = query_fc.log2_max_nports;
301*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_log2_max_fexch_queried = query_fc.log2_max_fexch;
302*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_log2_max_rfci_queried = query_fc.log2_max_rfci;
303*12965SWilliam.Taylor@Oracle.COM } else
304*12965SWilliam.Taylor@Oracle.COM cmn_err(CE_CONT, "!query_fc status 0x%x\n", status);
305*12965SWilliam.Taylor@Oracle.COM }
306*12965SWilliam.Taylor@Oracle.COM
307*12965SWilliam.Taylor@Oracle.COM /*
308*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_init()
309*12965SWilliam.Taylor@Oracle.COM * Context: Only called from attach() path context
310*12965SWilliam.Taylor@Oracle.COM */
311*12965SWilliam.Taylor@Oracle.COM int
hermon_fcoib_init(hermon_state_t * state)312*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_init(hermon_state_t *state)
313*12965SWilliam.Taylor@Oracle.COM {
314*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
315*12965SWilliam.Taylor@Oracle.COM uint_t numports;
316*12965SWilliam.Taylor@Oracle.COM char string[128];
317*12965SWilliam.Taylor@Oracle.COM int i;
318*12965SWilliam.Taylor@Oracle.COM uintptr_t vmemstart = (uintptr_t)0x10000000;
319*12965SWilliam.Taylor@Oracle.COM
320*12965SWilliam.Taylor@Oracle.COM /* used for fast checking for FCoIB during cqe_consume */
321*12965SWilliam.Taylor@Oracle.COM state->hs_fcoib_may_be_running = B_FALSE;
322*12965SWilliam.Taylor@Oracle.COM
323*12965SWilliam.Taylor@Oracle.COM if ((state->hs_ibtfinfo.hca_attr->hca_flags2 & IBT_HCA2_FC) == 0)
324*12965SWilliam.Taylor@Oracle.COM return (DDI_SUCCESS);
325*12965SWilliam.Taylor@Oracle.COM
326*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
327*12965SWilliam.Taylor@Oracle.COM bzero(fcoib, sizeof (*fcoib));
328*12965SWilliam.Taylor@Oracle.COM
329*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_query_fc(state, fcoib);
330*12965SWilliam.Taylor@Oracle.COM
331*12965SWilliam.Taylor@Oracle.COM mutex_init(&fcoib->hfc_lock, NULL, MUTEX_DRIVER, NULL);
332*12965SWilliam.Taylor@Oracle.COM mutex_enter(&fcoib->hfc_lock);
333*12965SWilliam.Taylor@Oracle.COM
334*12965SWilliam.Taylor@Oracle.COM /* use a ROUND value that works on both 32 and 64-bit kernels */
335*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_vmemstart = vmemstart;
336*12965SWilliam.Taylor@Oracle.COM
337*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_nports = numports = state->hs_cfg_profile->cp_num_ports;
338*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_fexch_qps_per_port =
339*12965SWilliam.Taylor@Oracle.COM 1 << state->hs_ibtfinfo.hca_attr->hca_fexch_max_log2_qp;
340*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_mpts_per_port = fcoib->hfc_fexch_qps_per_port * 2;
341*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_mtts_per_mpt =
342*12965SWilliam.Taylor@Oracle.COM (1 << state->hs_ibtfinfo.hca_attr->hca_fexch_max_log2_mem) >>
343*12965SWilliam.Taylor@Oracle.COM PAGESHIFT;
344*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_rfci_qps_per_port =
345*12965SWilliam.Taylor@Oracle.COM 1 << state->hs_ibtfinfo.hca_attr->hca_rfci_max_log2_qp;
346*12965SWilliam.Taylor@Oracle.COM
347*12965SWilliam.Taylor@Oracle.COM if (hermon_rsrc_reserve(state, HERMON_DMPT, numports *
348*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_mpts_per_port, HERMON_SLEEP,
349*12965SWilliam.Taylor@Oracle.COM &fcoib->hfc_mpt_rsrc) != DDI_SUCCESS) {
350*12965SWilliam.Taylor@Oracle.COM mutex_exit(&fcoib->hfc_lock);
351*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_fini(state);
352*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
353*12965SWilliam.Taylor@Oracle.COM }
354*12965SWilliam.Taylor@Oracle.COM
355*12965SWilliam.Taylor@Oracle.COM /*
356*12965SWilliam.Taylor@Oracle.COM * Only reserve MTTs for the Primary MPTs (first half of the
357*12965SWilliam.Taylor@Oracle.COM * range for each port).
358*12965SWilliam.Taylor@Oracle.COM */
359*12965SWilliam.Taylor@Oracle.COM if (hermon_rsrc_reserve(state, HERMON_MTT, numports *
360*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_mpts_per_port * fcoib->hfc_mtts_per_mpt / 2,
361*12965SWilliam.Taylor@Oracle.COM HERMON_SLEEP, &fcoib->hfc_mtt_rsrc) != DDI_SUCCESS) {
362*12965SWilliam.Taylor@Oracle.COM mutex_exit(&fcoib->hfc_lock);
363*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_fini(state);
364*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
365*12965SWilliam.Taylor@Oracle.COM }
366*12965SWilliam.Taylor@Oracle.COM if (hermon_rsrc_reserve(state, HERMON_QPC, numports *
367*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_fexch_qps_per_port, HERMON_SLEEP,
368*12965SWilliam.Taylor@Oracle.COM &fcoib->hfc_fexch_rsrc) != DDI_SUCCESS) {
369*12965SWilliam.Taylor@Oracle.COM mutex_exit(&fcoib->hfc_lock);
370*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_fini(state);
371*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
372*12965SWilliam.Taylor@Oracle.COM }
373*12965SWilliam.Taylor@Oracle.COM if (hermon_rsrc_reserve(state, HERMON_QPC, numports *
374*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_rfci_qps_per_port, HERMON_SLEEP,
375*12965SWilliam.Taylor@Oracle.COM &fcoib->hfc_rfci_rsrc) != DDI_SUCCESS) {
376*12965SWilliam.Taylor@Oracle.COM mutex_exit(&fcoib->hfc_lock);
377*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_fini(state);
378*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
379*12965SWilliam.Taylor@Oracle.COM }
380*12965SWilliam.Taylor@Oracle.COM
381*12965SWilliam.Taylor@Oracle.COM for (i = 0; i < numports; i++) {
382*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_port_enabled[i] = 0;
383*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_n_port_ids[i] = kmem_zalloc(sizeof (uint32_t) *
384*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_rfci_qps_per_port, KM_SLEEP);
385*12965SWilliam.Taylor@Oracle.COM
386*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_mpt_base[i] = i * fcoib->hfc_mpts_per_port +
387*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_mpt_rsrc->hr_indx;
388*12965SWilliam.Taylor@Oracle.COM /* "/ 2" is for Secondary MKEYs never used on Client side */
389*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_mtt_base[i] = (i * fcoib->hfc_mpts_per_port *
390*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_mtts_per_mpt / 2) + fcoib->hfc_mtt_rsrc->hr_indx;
391*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_fexch_base[i] = i * fcoib->hfc_fexch_qps_per_port +
392*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_fexch_rsrc->hr_indx;
393*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_rfci_base[i] = i * fcoib->hfc_rfci_qps_per_port +
394*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_rfci_rsrc->hr_indx;
395*12965SWilliam.Taylor@Oracle.COM
396*12965SWilliam.Taylor@Oracle.COM /* init FEXCH QP rsrc pool */
397*12965SWilliam.Taylor@Oracle.COM (void) sprintf(string, "hermon%d_port%d_fexch_vmem",
398*12965SWilliam.Taylor@Oracle.COM state->hs_instance, i + 1);
399*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_fexch_vmemp[i] = vmem_create(string,
400*12965SWilliam.Taylor@Oracle.COM (void *)vmemstart, fcoib->hfc_fexch_qps_per_port,
401*12965SWilliam.Taylor@Oracle.COM 1, NULL, NULL, NULL, 0, VM_SLEEP);
402*12965SWilliam.Taylor@Oracle.COM
403*12965SWilliam.Taylor@Oracle.COM /* init RFCI QP rsrc pool */
404*12965SWilliam.Taylor@Oracle.COM (void) sprintf(string, "hermon%d_port%d_rfci_vmem",
405*12965SWilliam.Taylor@Oracle.COM state->hs_instance, i + 1);
406*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_rfci_vmemp[i] = vmem_create(string,
407*12965SWilliam.Taylor@Oracle.COM (void *)vmemstart, fcoib->hfc_rfci_qps_per_port,
408*12965SWilliam.Taylor@Oracle.COM 1, NULL, NULL, NULL, 0, VM_SLEEP);
409*12965SWilliam.Taylor@Oracle.COM }
410*12965SWilliam.Taylor@Oracle.COM
411*12965SWilliam.Taylor@Oracle.COM mutex_exit(&fcoib->hfc_lock);
412*12965SWilliam.Taylor@Oracle.COM
413*12965SWilliam.Taylor@Oracle.COM return (DDI_SUCCESS);
414*12965SWilliam.Taylor@Oracle.COM }
415*12965SWilliam.Taylor@Oracle.COM
416*12965SWilliam.Taylor@Oracle.COM
417*12965SWilliam.Taylor@Oracle.COM /*
418*12965SWilliam.Taylor@Oracle.COM * hermon_fcoib_fini()
419*12965SWilliam.Taylor@Oracle.COM * Context: Only called from attach() and/or detach() path contexts
420*12965SWilliam.Taylor@Oracle.COM */
421*12965SWilliam.Taylor@Oracle.COM void
hermon_fcoib_fini(hermon_state_t * state)422*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_fini(hermon_state_t *state)
423*12965SWilliam.Taylor@Oracle.COM {
424*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
425*12965SWilliam.Taylor@Oracle.COM uint_t numports;
426*12965SWilliam.Taylor@Oracle.COM int i;
427*12965SWilliam.Taylor@Oracle.COM
428*12965SWilliam.Taylor@Oracle.COM if ((state->hs_ibtfinfo.hca_attr->hca_flags2 & IBT_HCA2_FC) == 0)
429*12965SWilliam.Taylor@Oracle.COM return;
430*12965SWilliam.Taylor@Oracle.COM
431*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
432*12965SWilliam.Taylor@Oracle.COM
433*12965SWilliam.Taylor@Oracle.COM mutex_enter(&fcoib->hfc_lock);
434*12965SWilliam.Taylor@Oracle.COM
435*12965SWilliam.Taylor@Oracle.COM numports = fcoib->hfc_nports;
436*12965SWilliam.Taylor@Oracle.COM
437*12965SWilliam.Taylor@Oracle.COM for (i = 0; i < numports; i++) {
438*12965SWilliam.Taylor@Oracle.COM if (fcoib->hfc_rfci_vmemp[i])
439*12965SWilliam.Taylor@Oracle.COM vmem_destroy(fcoib->hfc_rfci_vmemp[i]);
440*12965SWilliam.Taylor@Oracle.COM if (fcoib->hfc_fexch_vmemp[i])
441*12965SWilliam.Taylor@Oracle.COM vmem_destroy(fcoib->hfc_fexch_vmemp[i]);
442*12965SWilliam.Taylor@Oracle.COM if (fcoib->hfc_n_port_ids[i])
443*12965SWilliam.Taylor@Oracle.COM kmem_free(fcoib->hfc_n_port_ids[i], sizeof (uint32_t) *
444*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_rfci_qps_per_port);
445*12965SWilliam.Taylor@Oracle.COM
446*12965SWilliam.Taylor@Oracle.COM /* XXX --- should we issue HERMON_HW_FC_CONF_BASIC disable? */
447*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_port_enabled[i] = 0;
448*12965SWilliam.Taylor@Oracle.COM }
449*12965SWilliam.Taylor@Oracle.COM if (fcoib->hfc_rfci_rsrc)
450*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_free(state, &fcoib->hfc_rfci_rsrc);
451*12965SWilliam.Taylor@Oracle.COM if (fcoib->hfc_fexch_rsrc)
452*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_free(state, &fcoib->hfc_fexch_rsrc);
453*12965SWilliam.Taylor@Oracle.COM if (fcoib->hfc_mpt_rsrc)
454*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_free(state, &fcoib->hfc_mpt_rsrc);
455*12965SWilliam.Taylor@Oracle.COM if (fcoib->hfc_mtt_rsrc)
456*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_free(state, &fcoib->hfc_mtt_rsrc);
457*12965SWilliam.Taylor@Oracle.COM
458*12965SWilliam.Taylor@Oracle.COM mutex_exit(&fcoib->hfc_lock);
459*12965SWilliam.Taylor@Oracle.COM mutex_destroy(&fcoib->hfc_lock);
460*12965SWilliam.Taylor@Oracle.COM
461*12965SWilliam.Taylor@Oracle.COM bzero(fcoib, sizeof (*fcoib));
462*12965SWilliam.Taylor@Oracle.COM }
463