1*13101SVenki.Rajagopalan@Sun.COM /*
2*13101SVenki.Rajagopalan@Sun.COM * CDDL HEADER START
3*13101SVenki.Rajagopalan@Sun.COM *
4*13101SVenki.Rajagopalan@Sun.COM * The contents of this file are subject to the terms of the
5*13101SVenki.Rajagopalan@Sun.COM * Common Development and Distribution License (the "License").
6*13101SVenki.Rajagopalan@Sun.COM * You may not use this file except in compliance with the License.
7*13101SVenki.Rajagopalan@Sun.COM *
8*13101SVenki.Rajagopalan@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*13101SVenki.Rajagopalan@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*13101SVenki.Rajagopalan@Sun.COM * See the License for the specific language governing permissions
11*13101SVenki.Rajagopalan@Sun.COM * and limitations under the License.
12*13101SVenki.Rajagopalan@Sun.COM *
13*13101SVenki.Rajagopalan@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*13101SVenki.Rajagopalan@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*13101SVenki.Rajagopalan@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*13101SVenki.Rajagopalan@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*13101SVenki.Rajagopalan@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*13101SVenki.Rajagopalan@Sun.COM *
19*13101SVenki.Rajagopalan@Sun.COM * CDDL HEADER END
20*13101SVenki.Rajagopalan@Sun.COM */
21*13101SVenki.Rajagopalan@Sun.COM
22*13101SVenki.Rajagopalan@Sun.COM /*
23*13101SVenki.Rajagopalan@Sun.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*13101SVenki.Rajagopalan@Sun.COM */
25*13101SVenki.Rajagopalan@Sun.COM
26*13101SVenki.Rajagopalan@Sun.COM #include <sys/types.h>
27*13101SVenki.Rajagopalan@Sun.COM #include <sys/kmem.h>
28*13101SVenki.Rajagopalan@Sun.COM #include <sys/conf.h>
29*13101SVenki.Rajagopalan@Sun.COM #include <sys/ddi.h>
30*13101SVenki.Rajagopalan@Sun.COM #include <sys/sunddi.h>
31*13101SVenki.Rajagopalan@Sun.COM #include <sys/ksynch.h>
32*13101SVenki.Rajagopalan@Sun.COM
33*13101SVenki.Rajagopalan@Sun.COM #include <sys/ib/clients/eoib/enx_impl.h>
34*13101SVenki.Rajagopalan@Sun.COM
35*13101SVenki.Rajagopalan@Sun.COM /*
36*13101SVenki.Rajagopalan@Sun.COM * Module (static) info passed to IBTL during ibt_attach
37*13101SVenki.Rajagopalan@Sun.COM */
38*13101SVenki.Rajagopalan@Sun.COM static ibt_clnt_modinfo_t eibnx_clnt_modinfo = {
39*13101SVenki.Rajagopalan@Sun.COM IBTI_V_CURR,
40*13101SVenki.Rajagopalan@Sun.COM IBT_GENERIC,
41*13101SVenki.Rajagopalan@Sun.COM eibnx_async_handler,
42*13101SVenki.Rajagopalan@Sun.COM NULL,
43*13101SVenki.Rajagopalan@Sun.COM "EoIB Nexus"
44*13101SVenki.Rajagopalan@Sun.COM };
45*13101SVenki.Rajagopalan@Sun.COM
46*13101SVenki.Rajagopalan@Sun.COM ib_gid_t enx_advertise_mgid;
47*13101SVenki.Rajagopalan@Sun.COM ib_gid_t enx_solicit_mgid;
48*13101SVenki.Rajagopalan@Sun.COM
49*13101SVenki.Rajagopalan@Sun.COM /*
50*13101SVenki.Rajagopalan@Sun.COM * Static function declarations
51*13101SVenki.Rajagopalan@Sun.COM */
52*13101SVenki.Rajagopalan@Sun.COM static int eibnx_state_init(void);
53*13101SVenki.Rajagopalan@Sun.COM static int eibnx_setup_txbufs(eibnx_thr_info_t *);
54*13101SVenki.Rajagopalan@Sun.COM static int eibnx_setup_rxbufs(eibnx_thr_info_t *);
55*13101SVenki.Rajagopalan@Sun.COM static int eibnx_join_solicit_mcg(eibnx_thr_info_t *);
56*13101SVenki.Rajagopalan@Sun.COM static int eibnx_join_advertise_mcg(eibnx_thr_info_t *);
57*13101SVenki.Rajagopalan@Sun.COM static int eibnx_rb_ibt_init(eibnx_t *);
58*13101SVenki.Rajagopalan@Sun.COM static void eibnx_rb_state_init(void);
59*13101SVenki.Rajagopalan@Sun.COM static void eibnx_rb_setup_txbufs(eibnx_thr_info_t *);
60*13101SVenki.Rajagopalan@Sun.COM static void eibnx_rb_setup_rxbufs(eibnx_thr_info_t *);
61*13101SVenki.Rajagopalan@Sun.COM static void eibnx_rb_join_solicit_mcg(eibnx_thr_info_t *);
62*13101SVenki.Rajagopalan@Sun.COM static void eibnx_rb_join_advertise_mcg(eibnx_thr_info_t *);
63*13101SVenki.Rajagopalan@Sun.COM
64*13101SVenki.Rajagopalan@Sun.COM /*
65*13101SVenki.Rajagopalan@Sun.COM * eibnx_ibt_init() is expected to be called during the nexus driver's
66*13101SVenki.Rajagopalan@Sun.COM * attach time; given that there is only one instance of the nexus
67*13101SVenki.Rajagopalan@Sun.COM * driver allowed, and no threads are active before the initialization
68*13101SVenki.Rajagopalan@Sun.COM * is complete, we don't really have to acquire any driver specific mutex
69*13101SVenki.Rajagopalan@Sun.COM * within this routine.
70*13101SVenki.Rajagopalan@Sun.COM */
71*13101SVenki.Rajagopalan@Sun.COM int
eibnx_ibt_init(eibnx_t * ss)72*13101SVenki.Rajagopalan@Sun.COM eibnx_ibt_init(eibnx_t *ss)
73*13101SVenki.Rajagopalan@Sun.COM {
74*13101SVenki.Rajagopalan@Sun.COM eibnx_hca_t *hca_list;
75*13101SVenki.Rajagopalan@Sun.COM eibnx_hca_t *hca_tail;
76*13101SVenki.Rajagopalan@Sun.COM eibnx_hca_t *hca;
77*13101SVenki.Rajagopalan@Sun.COM uint_t num_hcas;
78*13101SVenki.Rajagopalan@Sun.COM ib_guid_t *hca_guids;
79*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
80*13101SVenki.Rajagopalan@Sun.COM int i;
81*13101SVenki.Rajagopalan@Sun.COM
82*13101SVenki.Rajagopalan@Sun.COM /*
83*13101SVenki.Rajagopalan@Sun.COM * Do per-state initialization
84*13101SVenki.Rajagopalan@Sun.COM */
85*13101SVenki.Rajagopalan@Sun.COM (void) eibnx_state_init();
86*13101SVenki.Rajagopalan@Sun.COM
87*13101SVenki.Rajagopalan@Sun.COM /*
88*13101SVenki.Rajagopalan@Sun.COM * Attach to IBTL
89*13101SVenki.Rajagopalan@Sun.COM */
90*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_attach(&eibnx_clnt_modinfo, ss->nx_dip, ss,
91*13101SVenki.Rajagopalan@Sun.COM &ss->nx_ibt_hdl)) != IBT_SUCCESS) {
92*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_attach() failed, ret=%d", ret);
93*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_state_init();
94*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
95*13101SVenki.Rajagopalan@Sun.COM }
96*13101SVenki.Rajagopalan@Sun.COM
97*13101SVenki.Rajagopalan@Sun.COM /*
98*13101SVenki.Rajagopalan@Sun.COM * Get the list of HCA guids on the system
99*13101SVenki.Rajagopalan@Sun.COM */
100*13101SVenki.Rajagopalan@Sun.COM if ((num_hcas = ibt_get_hca_list(&hca_guids)) == 0) {
101*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_VERBOSE("no HCAs found on the system");
102*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_detach(ss->nx_ibt_hdl)) != IBT_SUCCESS) {
103*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_detach() failed, ret=%d", ret);
104*13101SVenki.Rajagopalan@Sun.COM }
105*13101SVenki.Rajagopalan@Sun.COM ss->nx_ibt_hdl = NULL;
106*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
107*13101SVenki.Rajagopalan@Sun.COM }
108*13101SVenki.Rajagopalan@Sun.COM
109*13101SVenki.Rajagopalan@Sun.COM /*
110*13101SVenki.Rajagopalan@Sun.COM * Open the HCAs and store the handles
111*13101SVenki.Rajagopalan@Sun.COM */
112*13101SVenki.Rajagopalan@Sun.COM hca_list = hca_tail = NULL;
113*13101SVenki.Rajagopalan@Sun.COM for (i = 0; i < num_hcas; i++) {
114*13101SVenki.Rajagopalan@Sun.COM /*
115*13101SVenki.Rajagopalan@Sun.COM * If we cannot open a HCA, allocate a protection domain
116*13101SVenki.Rajagopalan@Sun.COM * on it or get portinfo on it, print an error and move on
117*13101SVenki.Rajagopalan@Sun.COM * to the next HCA. Otherwise, queue it up in our hca list
118*13101SVenki.Rajagopalan@Sun.COM */
119*13101SVenki.Rajagopalan@Sun.COM if ((hca = eibnx_prepare_hca(hca_guids[i])) == NULL)
120*13101SVenki.Rajagopalan@Sun.COM continue;
121*13101SVenki.Rajagopalan@Sun.COM
122*13101SVenki.Rajagopalan@Sun.COM if (hca_tail) {
123*13101SVenki.Rajagopalan@Sun.COM hca_tail->hc_next = hca;
124*13101SVenki.Rajagopalan@Sun.COM } else {
125*13101SVenki.Rajagopalan@Sun.COM hca_list = hca;
126*13101SVenki.Rajagopalan@Sun.COM }
127*13101SVenki.Rajagopalan@Sun.COM hca_tail = hca;
128*13101SVenki.Rajagopalan@Sun.COM }
129*13101SVenki.Rajagopalan@Sun.COM
130*13101SVenki.Rajagopalan@Sun.COM /*
131*13101SVenki.Rajagopalan@Sun.COM * Free the HCA guid list we've allocated via ibt_get_hca_list()
132*13101SVenki.Rajagopalan@Sun.COM */
133*13101SVenki.Rajagopalan@Sun.COM ibt_free_hca_list(hca_guids, num_hcas);
134*13101SVenki.Rajagopalan@Sun.COM
135*13101SVenki.Rajagopalan@Sun.COM /*
136*13101SVenki.Rajagopalan@Sun.COM * Put the hca list in the state structure
137*13101SVenki.Rajagopalan@Sun.COM */
138*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_lock);
139*13101SVenki.Rajagopalan@Sun.COM ss->nx_hca = hca_list;
140*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_lock);
141*13101SVenki.Rajagopalan@Sun.COM
142*13101SVenki.Rajagopalan@Sun.COM /*
143*13101SVenki.Rajagopalan@Sun.COM * Register for subnet notices
144*13101SVenki.Rajagopalan@Sun.COM */
145*13101SVenki.Rajagopalan@Sun.COM ibt_register_subnet_notices(ss->nx_ibt_hdl,
146*13101SVenki.Rajagopalan@Sun.COM eibnx_subnet_notices_handler, ss);
147*13101SVenki.Rajagopalan@Sun.COM
148*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
149*13101SVenki.Rajagopalan@Sun.COM }
150*13101SVenki.Rajagopalan@Sun.COM
151*13101SVenki.Rajagopalan@Sun.COM static int
eibnx_state_init(void)152*13101SVenki.Rajagopalan@Sun.COM eibnx_state_init(void)
153*13101SVenki.Rajagopalan@Sun.COM {
154*13101SVenki.Rajagopalan@Sun.COM eibnx_t *ss = enx_global_ss;
155*13101SVenki.Rajagopalan@Sun.COM kthread_t *kt;
156*13101SVenki.Rajagopalan@Sun.COM
157*13101SVenki.Rajagopalan@Sun.COM /*
158*13101SVenki.Rajagopalan@Sun.COM * Initialize synchronization primitives
159*13101SVenki.Rajagopalan@Sun.COM */
160*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ss->nx_lock, NULL, MUTEX_DRIVER, NULL);
161*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ss->nx_nodeq_lock, NULL, MUTEX_DRIVER, NULL);
162*13101SVenki.Rajagopalan@Sun.COM cv_init(&ss->nx_nodeq_cv, NULL, CV_DEFAULT, NULL);
163*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ss->nx_busop_lock, NULL, MUTEX_DRIVER, NULL);
164*13101SVenki.Rajagopalan@Sun.COM cv_init(&ss->nx_busop_cv, NULL, CV_DEFAULT, NULL);
165*13101SVenki.Rajagopalan@Sun.COM
166*13101SVenki.Rajagopalan@Sun.COM /*
167*13101SVenki.Rajagopalan@Sun.COM * Initialize well-known mgids: there must be a better way to
168*13101SVenki.Rajagopalan@Sun.COM * do this instead of having to express every single gid as a
169*13101SVenki.Rajagopalan@Sun.COM * tuple of two 8-byte integer quantities.
170*13101SVenki.Rajagopalan@Sun.COM */
171*13101SVenki.Rajagopalan@Sun.COM enx_solicit_mgid.gid_prefix = EIB_GUID_SOLICIT_PREFIX;
172*13101SVenki.Rajagopalan@Sun.COM enx_solicit_mgid.gid_guid = 0;
173*13101SVenki.Rajagopalan@Sun.COM enx_advertise_mgid.gid_prefix = EIB_GUID_ADVERTISE_PREFIX;
174*13101SVenki.Rajagopalan@Sun.COM enx_advertise_mgid.gid_guid = 0;
175*13101SVenki.Rajagopalan@Sun.COM
176*13101SVenki.Rajagopalan@Sun.COM /*
177*13101SVenki.Rajagopalan@Sun.COM * Start up the eoib node creation thread
178*13101SVenki.Rajagopalan@Sun.COM */
179*13101SVenki.Rajagopalan@Sun.COM kt = thread_create(NULL, 0, eibnx_create_eoib_node, NULL, 0,
180*13101SVenki.Rajagopalan@Sun.COM &p0, TS_RUN, minclsyspri);
181*13101SVenki.Rajagopalan@Sun.COM ss->nx_nodeq_kt_did = kt->t_did;
182*13101SVenki.Rajagopalan@Sun.COM
183*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
184*13101SVenki.Rajagopalan@Sun.COM }
185*13101SVenki.Rajagopalan@Sun.COM
186*13101SVenki.Rajagopalan@Sun.COM /*
187*13101SVenki.Rajagopalan@Sun.COM * Locate the two multicast groups: the All-EoIB-GWs-GID and
188*13101SVenki.Rajagopalan@Sun.COM * All-EoIB-ENodes-GID. Make sure the MTU is something that
189*13101SVenki.Rajagopalan@Sun.COM * we can work with and Qkey is as expected.
190*13101SVenki.Rajagopalan@Sun.COM */
191*13101SVenki.Rajagopalan@Sun.COM int
eibnx_find_mgroups(eibnx_thr_info_t * info)192*13101SVenki.Rajagopalan@Sun.COM eibnx_find_mgroups(eibnx_thr_info_t *info)
193*13101SVenki.Rajagopalan@Sun.COM {
194*13101SVenki.Rajagopalan@Sun.COM ibt_hca_portinfo_t *pi = info->ti_pi;
195*13101SVenki.Rajagopalan@Sun.COM ibt_mcg_attr_t mcg_attr;
196*13101SVenki.Rajagopalan@Sun.COM ib_gid_t rgid;
197*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
198*13101SVenki.Rajagopalan@Sun.COM uint_t entries;
199*13101SVenki.Rajagopalan@Sun.COM
200*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&info->ti_mcg_lock);
201*13101SVenki.Rajagopalan@Sun.COM
202*13101SVenki.Rajagopalan@Sun.COM if ((info->ti_mcg_status & ENX_MCGS_FOUND) == ENX_MCGS_FOUND) {
203*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
204*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
205*13101SVenki.Rajagopalan@Sun.COM }
206*13101SVenki.Rajagopalan@Sun.COM
207*13101SVenki.Rajagopalan@Sun.COM /*
208*13101SVenki.Rajagopalan@Sun.COM * Request GID defining this port
209*13101SVenki.Rajagopalan@Sun.COM */
210*13101SVenki.Rajagopalan@Sun.COM rgid = pi->p_sgid_tbl[0];
211*13101SVenki.Rajagopalan@Sun.COM
212*13101SVenki.Rajagopalan@Sun.COM /*
213*13101SVenki.Rajagopalan@Sun.COM * First, locate the multicast group to use for sending solicit
214*13101SVenki.Rajagopalan@Sun.COM * requests to the GW
215*13101SVenki.Rajagopalan@Sun.COM */
216*13101SVenki.Rajagopalan@Sun.COM bzero(&mcg_attr, sizeof (ibt_mcg_attr_t));
217*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_mgid = enx_solicit_mgid;
218*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_pkey = (ib_pkey_t)EIB_ADMIN_PKEY;
219*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_qkey = (ib_qkey_t)EIB_FIP_QKEY;
220*13101SVenki.Rajagopalan@Sun.COM
221*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_query_mcg(rgid, &mcg_attr, 1, &info->ti_solicit_mcg,
222*13101SVenki.Rajagopalan@Sun.COM &entries)) != IBT_SUCCESS) {
223*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("solicit mcg (gid=%llx.%llx) not found, "
224*13101SVenki.Rajagopalan@Sun.COM "ibt_query_mcg() returned %d", enx_solicit_mgid.gid_prefix,
225*13101SVenki.Rajagopalan@Sun.COM enx_solicit_mgid.gid_guid, ret);
226*13101SVenki.Rajagopalan@Sun.COM goto find_mgroups_fail;
227*13101SVenki.Rajagopalan@Sun.COM }
228*13101SVenki.Rajagopalan@Sun.COM
229*13101SVenki.Rajagopalan@Sun.COM /*
230*13101SVenki.Rajagopalan@Sun.COM * Make sure the multicast mtu isn't bigger than the port mtu
231*13101SVenki.Rajagopalan@Sun.COM * and the multicast group's qkey is the same as EIB_FIP_QKEY.
232*13101SVenki.Rajagopalan@Sun.COM */
233*13101SVenki.Rajagopalan@Sun.COM if (info->ti_solicit_mcg->mc_mtu > pi->p_mtu) {
234*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("solicit mcg (gid=%llx.%llx) mtu too big, "
235*13101SVenki.Rajagopalan@Sun.COM "0x%x > 0x%x", enx_solicit_mgid.gid_prefix,
236*13101SVenki.Rajagopalan@Sun.COM enx_solicit_mgid.gid_guid, info->ti_solicit_mcg->mc_mtu,
237*13101SVenki.Rajagopalan@Sun.COM pi->p_mtu);
238*13101SVenki.Rajagopalan@Sun.COM goto find_mgroups_fail;
239*13101SVenki.Rajagopalan@Sun.COM }
240*13101SVenki.Rajagopalan@Sun.COM if (info->ti_solicit_mcg->mc_qkey != EIB_FIP_QKEY) {
241*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("solicit mcg (gid=%llx.%llx) qkey bad, "
242*13101SVenki.Rajagopalan@Sun.COM "actual=0x%x, expected=0x%x", enx_solicit_mgid.gid_prefix,
243*13101SVenki.Rajagopalan@Sun.COM enx_solicit_mgid.gid_guid, info->ti_solicit_mcg->mc_qkey,
244*13101SVenki.Rajagopalan@Sun.COM EIB_FIP_QKEY);
245*13101SVenki.Rajagopalan@Sun.COM goto find_mgroups_fail;
246*13101SVenki.Rajagopalan@Sun.COM }
247*13101SVenki.Rajagopalan@Sun.COM
248*13101SVenki.Rajagopalan@Sun.COM /*
249*13101SVenki.Rajagopalan@Sun.COM * Now, locate the multicast group for receiving discover
250*13101SVenki.Rajagopalan@Sun.COM * advertisements from the GW
251*13101SVenki.Rajagopalan@Sun.COM */
252*13101SVenki.Rajagopalan@Sun.COM bzero(&mcg_attr, sizeof (ibt_mcg_attr_t));
253*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_mgid = enx_advertise_mgid;
254*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_pkey = (ib_pkey_t)EIB_ADMIN_PKEY;
255*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_qkey = (ib_qkey_t)EIB_FIP_QKEY;
256*13101SVenki.Rajagopalan@Sun.COM
257*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_query_mcg(rgid, &mcg_attr, 1, &info->ti_advertise_mcg,
258*13101SVenki.Rajagopalan@Sun.COM &entries)) != IBT_SUCCESS) {
259*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("advertise mcg (gid=%llx.%llx) not found, "
260*13101SVenki.Rajagopalan@Sun.COM "ibt_query_mcg() returned %d",
261*13101SVenki.Rajagopalan@Sun.COM enx_advertise_mgid.gid_prefix,
262*13101SVenki.Rajagopalan@Sun.COM enx_advertise_mgid.gid_guid, ret);
263*13101SVenki.Rajagopalan@Sun.COM goto find_mgroups_fail;
264*13101SVenki.Rajagopalan@Sun.COM }
265*13101SVenki.Rajagopalan@Sun.COM
266*13101SVenki.Rajagopalan@Sun.COM /*
267*13101SVenki.Rajagopalan@Sun.COM * Verify the multicast group's mtu and qkey as before
268*13101SVenki.Rajagopalan@Sun.COM */
269*13101SVenki.Rajagopalan@Sun.COM if (info->ti_advertise_mcg->mc_mtu > pi->p_mtu) {
270*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("advertise mcg (gid=%llx.%llx) mtu too big, "
271*13101SVenki.Rajagopalan@Sun.COM "0x%x > 0x%x", enx_advertise_mgid.gid_prefix,
272*13101SVenki.Rajagopalan@Sun.COM enx_advertise_mgid.gid_guid,
273*13101SVenki.Rajagopalan@Sun.COM info->ti_advertise_mcg->mc_mtu, pi->p_mtu);
274*13101SVenki.Rajagopalan@Sun.COM goto find_mgroups_fail;
275*13101SVenki.Rajagopalan@Sun.COM }
276*13101SVenki.Rajagopalan@Sun.COM if (info->ti_advertise_mcg->mc_qkey != EIB_FIP_QKEY) {
277*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("advertise mcg (gid=%llx.%llx) qkey bad, "
278*13101SVenki.Rajagopalan@Sun.COM "actual=0x%x, expected=0x%x",
279*13101SVenki.Rajagopalan@Sun.COM enx_advertise_mgid.gid_prefix, enx_advertise_mgid.gid_guid,
280*13101SVenki.Rajagopalan@Sun.COM info->ti_advertise_mcg->mc_qkey, EIB_FIP_QKEY);
281*13101SVenki.Rajagopalan@Sun.COM goto find_mgroups_fail;
282*13101SVenki.Rajagopalan@Sun.COM }
283*13101SVenki.Rajagopalan@Sun.COM
284*13101SVenki.Rajagopalan@Sun.COM info->ti_mcg_status |= ENX_MCGS_FOUND;
285*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
286*13101SVenki.Rajagopalan@Sun.COM
287*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
288*13101SVenki.Rajagopalan@Sun.COM
289*13101SVenki.Rajagopalan@Sun.COM find_mgroups_fail:
290*13101SVenki.Rajagopalan@Sun.COM if (info->ti_advertise_mcg) {
291*13101SVenki.Rajagopalan@Sun.COM ibt_free_mcg_info(info->ti_advertise_mcg, 1);
292*13101SVenki.Rajagopalan@Sun.COM info->ti_advertise_mcg = NULL;
293*13101SVenki.Rajagopalan@Sun.COM }
294*13101SVenki.Rajagopalan@Sun.COM if (info->ti_solicit_mcg) {
295*13101SVenki.Rajagopalan@Sun.COM ibt_free_mcg_info(info->ti_solicit_mcg, 1);
296*13101SVenki.Rajagopalan@Sun.COM info->ti_solicit_mcg = NULL;
297*13101SVenki.Rajagopalan@Sun.COM }
298*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
299*13101SVenki.Rajagopalan@Sun.COM
300*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
301*13101SVenki.Rajagopalan@Sun.COM }
302*13101SVenki.Rajagopalan@Sun.COM
303*13101SVenki.Rajagopalan@Sun.COM /*
304*13101SVenki.Rajagopalan@Sun.COM * Allocate and setup a single completion queue for tx and rx
305*13101SVenki.Rajagopalan@Sun.COM */
306*13101SVenki.Rajagopalan@Sun.COM int
eibnx_setup_cq(eibnx_thr_info_t * info)307*13101SVenki.Rajagopalan@Sun.COM eibnx_setup_cq(eibnx_thr_info_t *info)
308*13101SVenki.Rajagopalan@Sun.COM {
309*13101SVenki.Rajagopalan@Sun.COM ibt_hca_attr_t hca_attr;
310*13101SVenki.Rajagopalan@Sun.COM ibt_cq_attr_t cq_attr;
311*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
312*13101SVenki.Rajagopalan@Sun.COM uint_t sz;
313*13101SVenki.Rajagopalan@Sun.COM
314*13101SVenki.Rajagopalan@Sun.COM /*
315*13101SVenki.Rajagopalan@Sun.COM * Get this HCA's attributes
316*13101SVenki.Rajagopalan@Sun.COM */
317*13101SVenki.Rajagopalan@Sun.COM ret = ibt_query_hca(info->ti_hca, &hca_attr);
318*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
319*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_query_hca(hca_hdl=0x%llx) failed, ret=%d",
320*13101SVenki.Rajagopalan@Sun.COM info->ti_hca, ret);
321*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
322*13101SVenki.Rajagopalan@Sun.COM }
323*13101SVenki.Rajagopalan@Sun.COM
324*13101SVenki.Rajagopalan@Sun.COM /*
325*13101SVenki.Rajagopalan@Sun.COM * Allocate a completion queue for our sends and receives
326*13101SVenki.Rajagopalan@Sun.COM */
327*13101SVenki.Rajagopalan@Sun.COM cq_attr.cq_sched = NULL;
328*13101SVenki.Rajagopalan@Sun.COM cq_attr.cq_flags = IBT_CQ_NO_FLAGS;
329*13101SVenki.Rajagopalan@Sun.COM cq_attr.cq_size = (hca_attr.hca_max_cq_sz < ENX_CQ_SIZE) ?
330*13101SVenki.Rajagopalan@Sun.COM hca_attr.hca_max_cq_sz : ENX_CQ_SIZE;
331*13101SVenki.Rajagopalan@Sun.COM
332*13101SVenki.Rajagopalan@Sun.COM ret = ibt_alloc_cq(info->ti_hca, &cq_attr, &info->ti_cq_hdl, &sz);
333*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
334*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_alloc_cq(hca_hdl=0x%llx, cq_sz=0x%lx) "
335*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", info->ti_hca, cq_attr.cq_size, ret);
336*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
337*13101SVenki.Rajagopalan@Sun.COM }
338*13101SVenki.Rajagopalan@Sun.COM
339*13101SVenki.Rajagopalan@Sun.COM /*
340*13101SVenki.Rajagopalan@Sun.COM * Set up other parameters for collecting completion information
341*13101SVenki.Rajagopalan@Sun.COM */
342*13101SVenki.Rajagopalan@Sun.COM info->ti_cq_sz = sz;
343*13101SVenki.Rajagopalan@Sun.COM info->ti_wc = kmem_zalloc(sizeof (ibt_wc_t) * sz, KM_SLEEP);
344*13101SVenki.Rajagopalan@Sun.COM
345*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
346*13101SVenki.Rajagopalan@Sun.COM }
347*13101SVenki.Rajagopalan@Sun.COM
348*13101SVenki.Rajagopalan@Sun.COM /*
349*13101SVenki.Rajagopalan@Sun.COM * Allocate and setup the UD channel parameters
350*13101SVenki.Rajagopalan@Sun.COM */
351*13101SVenki.Rajagopalan@Sun.COM int
eibnx_setup_ud_channel(eibnx_thr_info_t * info)352*13101SVenki.Rajagopalan@Sun.COM eibnx_setup_ud_channel(eibnx_thr_info_t *info)
353*13101SVenki.Rajagopalan@Sun.COM {
354*13101SVenki.Rajagopalan@Sun.COM ibt_ud_chan_alloc_args_t alloc_attr;
355*13101SVenki.Rajagopalan@Sun.COM ibt_ud_chan_query_attr_t query_attr;
356*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
357*13101SVenki.Rajagopalan@Sun.COM
358*13101SVenki.Rajagopalan@Sun.COM /*
359*13101SVenki.Rajagopalan@Sun.COM * Protect against arbitrary additions to the chan_alloc_args
360*13101SVenki.Rajagopalan@Sun.COM * and chan_query_attr structures (make sure the ones we don't
361*13101SVenki.Rajagopalan@Sun.COM * use are zero'd).
362*13101SVenki.Rajagopalan@Sun.COM */
363*13101SVenki.Rajagopalan@Sun.COM bzero(&alloc_attr, sizeof (ibt_ud_chan_alloc_args_t));
364*13101SVenki.Rajagopalan@Sun.COM bzero(&query_attr, sizeof (ibt_ud_chan_query_attr_t));
365*13101SVenki.Rajagopalan@Sun.COM
366*13101SVenki.Rajagopalan@Sun.COM /*
367*13101SVenki.Rajagopalan@Sun.COM * This ud channel is not going to be used by the nexus driver
368*13101SVenki.Rajagopalan@Sun.COM * to send any LSO packets, so we won't need the IBT_USES_LSO flag.
369*13101SVenki.Rajagopalan@Sun.COM */
370*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_flags = IBT_ALL_SIGNALED;
371*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_hca_port_num = info->ti_pi->p_port_num;
372*13101SVenki.Rajagopalan@Sun.COM
373*13101SVenki.Rajagopalan@Sun.COM ret = ibt_pkey2index(info->ti_hca, info->ti_pi->p_port_num,
374*13101SVenki.Rajagopalan@Sun.COM (ib_pkey_t)EIB_ADMIN_PKEY, &(alloc_attr.ud_pkey_ix));
375*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
376*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_pkey2index(hca_hdl=0x%llx, "
377*13101SVenki.Rajagopalan@Sun.COM "port_num=0x%x, pkey=0x%x) failed, ret=%d",
378*13101SVenki.Rajagopalan@Sun.COM info->ti_hca, info->ti_pi->p_port_num,
379*13101SVenki.Rajagopalan@Sun.COM EIB_ADMIN_PKEY, ret);
380*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
381*13101SVenki.Rajagopalan@Sun.COM }
382*13101SVenki.Rajagopalan@Sun.COM
383*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_sizes.cs_sq = ENX_NUM_SWQE;
384*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_sizes.cs_rq = ENX_NUM_RWQE;
385*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_sizes.cs_sq_sgl = 1;
386*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_sizes.cs_rq_sgl = 1;
387*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_sizes.cs_inline = 0;
388*13101SVenki.Rajagopalan@Sun.COM
389*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_qkey = EIB_FIP_QKEY;
390*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_scq = info->ti_cq_hdl;
391*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_rcq = info->ti_cq_hdl;
392*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_pd = info->ti_pd;
393*13101SVenki.Rajagopalan@Sun.COM
394*13101SVenki.Rajagopalan@Sun.COM ret = ibt_alloc_ud_channel(info->ti_hca, IBT_ACHAN_NO_FLAGS,
395*13101SVenki.Rajagopalan@Sun.COM &alloc_attr, &info->ti_chan, NULL);
396*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
397*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_alloc_ud_channel(hca_hdl=0x%llx, "
398*13101SVenki.Rajagopalan@Sun.COM "cs_sq=0x%lx, cs_rq=0x%lx) failed, ret=%d",
399*13101SVenki.Rajagopalan@Sun.COM info->ti_hca, alloc_attr.ud_sizes.cs_sq,
400*13101SVenki.Rajagopalan@Sun.COM alloc_attr.ud_sizes.cs_rq, ret);
401*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
402*13101SVenki.Rajagopalan@Sun.COM }
403*13101SVenki.Rajagopalan@Sun.COM
404*13101SVenki.Rajagopalan@Sun.COM ret = ibt_query_ud_channel(info->ti_chan, &query_attr);
405*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
406*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_query_ud_channel(chan_hdl=0x%llx) "
407*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", info->ti_chan, ret);
408*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_free_channel(info->ti_chan)) != IBT_SUCCESS) {
409*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_free_channel(chan_hdl=0x%llx) "
410*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", info->ti_chan, ret);
411*13101SVenki.Rajagopalan@Sun.COM }
412*13101SVenki.Rajagopalan@Sun.COM info->ti_chan = NULL;
413*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
414*13101SVenki.Rajagopalan@Sun.COM }
415*13101SVenki.Rajagopalan@Sun.COM info->ti_qpn = query_attr.ud_qpn;
416*13101SVenki.Rajagopalan@Sun.COM
417*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
418*13101SVenki.Rajagopalan@Sun.COM }
419*13101SVenki.Rajagopalan@Sun.COM
420*13101SVenki.Rajagopalan@Sun.COM /*
421*13101SVenki.Rajagopalan@Sun.COM * Set up the transmit buffers for communicating with the gateway. Since
422*13101SVenki.Rajagopalan@Sun.COM * the EoIB Nexus driver only exchanges control messages with the
423*13101SVenki.Rajagopalan@Sun.COM * gateway, we don't really need too much space.
424*13101SVenki.Rajagopalan@Sun.COM */
425*13101SVenki.Rajagopalan@Sun.COM static int
eibnx_setup_txbufs(eibnx_thr_info_t * info)426*13101SVenki.Rajagopalan@Sun.COM eibnx_setup_txbufs(eibnx_thr_info_t *info)
427*13101SVenki.Rajagopalan@Sun.COM {
428*13101SVenki.Rajagopalan@Sun.COM eibnx_tx_t *snd_p = &info->ti_snd;
429*13101SVenki.Rajagopalan@Sun.COM eibnx_wqe_t *swqe;
430*13101SVenki.Rajagopalan@Sun.COM ibt_mr_attr_t attr;
431*13101SVenki.Rajagopalan@Sun.COM ibt_mr_desc_t desc;
432*13101SVenki.Rajagopalan@Sun.COM ib_memlen_t tx_bufsz;
433*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
434*13101SVenki.Rajagopalan@Sun.COM ibt_ud_dest_hdl_t dest;
435*13101SVenki.Rajagopalan@Sun.COM uint8_t *buf;
436*13101SVenki.Rajagopalan@Sun.COM uint_t mtu = (128 << info->ti_pi->p_mtu);
437*13101SVenki.Rajagopalan@Sun.COM int i;
438*13101SVenki.Rajagopalan@Sun.COM
439*13101SVenki.Rajagopalan@Sun.COM /*
440*13101SVenki.Rajagopalan@Sun.COM * Allocate for the tx buf
441*13101SVenki.Rajagopalan@Sun.COM */
442*13101SVenki.Rajagopalan@Sun.COM tx_bufsz = ENX_NUM_SWQE * mtu;
443*13101SVenki.Rajagopalan@Sun.COM snd_p->tx_vaddr = (ib_vaddr_t)(uintptr_t)kmem_zalloc(tx_bufsz,
444*13101SVenki.Rajagopalan@Sun.COM KM_SLEEP);
445*13101SVenki.Rajagopalan@Sun.COM
446*13101SVenki.Rajagopalan@Sun.COM /*
447*13101SVenki.Rajagopalan@Sun.COM * Register the memory region with IBTF for use
448*13101SVenki.Rajagopalan@Sun.COM */
449*13101SVenki.Rajagopalan@Sun.COM attr.mr_vaddr = snd_p->tx_vaddr;
450*13101SVenki.Rajagopalan@Sun.COM attr.mr_len = tx_bufsz;
451*13101SVenki.Rajagopalan@Sun.COM attr.mr_as = NULL;
452*13101SVenki.Rajagopalan@Sun.COM attr.mr_flags = IBT_MR_SLEEP;
453*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_register_mr(info->ti_hca, info->ti_pd, &attr,
454*13101SVenki.Rajagopalan@Sun.COM &snd_p->tx_mr, &desc)) != IBT_SUCCESS) {
455*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_register_mr() failed for tx "
456*13101SVenki.Rajagopalan@Sun.COM "region (0x%llx, 0x%llx) with ret=%d",
457*13101SVenki.Rajagopalan@Sun.COM attr.mr_vaddr, attr.mr_len, ret);
458*13101SVenki.Rajagopalan@Sun.COM kmem_free((void *)(uintptr_t)(snd_p->tx_vaddr), tx_bufsz);
459*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
460*13101SVenki.Rajagopalan@Sun.COM }
461*13101SVenki.Rajagopalan@Sun.COM snd_p->tx_lkey = desc.md_lkey;
462*13101SVenki.Rajagopalan@Sun.COM
463*13101SVenki.Rajagopalan@Sun.COM /*
464*13101SVenki.Rajagopalan@Sun.COM * Now setup the send wqes
465*13101SVenki.Rajagopalan@Sun.COM */
466*13101SVenki.Rajagopalan@Sun.COM buf = (uint8_t *)(uintptr_t)(snd_p->tx_vaddr);
467*13101SVenki.Rajagopalan@Sun.COM for (i = 0; i < ENX_NUM_SWQE; i++) {
468*13101SVenki.Rajagopalan@Sun.COM swqe = &snd_p->tx_wqe[i];
469*13101SVenki.Rajagopalan@Sun.COM
470*13101SVenki.Rajagopalan@Sun.COM /*
471*13101SVenki.Rajagopalan@Sun.COM * Allocate a UD destination handle
472*13101SVenki.Rajagopalan@Sun.COM */
473*13101SVenki.Rajagopalan@Sun.COM ret = ibt_alloc_ud_dest(info->ti_hca, IBT_UD_DEST_NO_FLAGS,
474*13101SVenki.Rajagopalan@Sun.COM info->ti_pd, &dest);
475*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
476*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_alloc_ud_dest(hca_hdl=0x%llx) "
477*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", info->ti_hca, ret);
478*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_txbufs(info);
479*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
480*13101SVenki.Rajagopalan@Sun.COM }
481*13101SVenki.Rajagopalan@Sun.COM
482*13101SVenki.Rajagopalan@Sun.COM /*
483*13101SVenki.Rajagopalan@Sun.COM * We set up everything in the send wqes except initialize
484*13101SVenki.Rajagopalan@Sun.COM * the UD destination and the state of the entry. The ds_len
485*13101SVenki.Rajagopalan@Sun.COM * should also be adjusted correctly. All this should be
486*13101SVenki.Rajagopalan@Sun.COM * done later in the appropriate routines, before posting.
487*13101SVenki.Rajagopalan@Sun.COM */
488*13101SVenki.Rajagopalan@Sun.COM swqe->qe_type = ENX_QETYP_SWQE;
489*13101SVenki.Rajagopalan@Sun.COM swqe->qe_bufsz = mtu;
490*13101SVenki.Rajagopalan@Sun.COM swqe->qe_sgl.ds_va = (ib_vaddr_t)(uintptr_t)buf;
491*13101SVenki.Rajagopalan@Sun.COM swqe->qe_sgl.ds_key = snd_p->tx_lkey;
492*13101SVenki.Rajagopalan@Sun.COM swqe->qe_sgl.ds_len = swqe->qe_bufsz;
493*13101SVenki.Rajagopalan@Sun.COM swqe->qe_wr.send.wr_id = (ibt_wrid_t)(uintptr_t)swqe;
494*13101SVenki.Rajagopalan@Sun.COM swqe->qe_wr.send.wr_flags = IBT_WR_NO_FLAGS;
495*13101SVenki.Rajagopalan@Sun.COM swqe->qe_wr.send.wr_trans = IBT_UD_SRV;
496*13101SVenki.Rajagopalan@Sun.COM swqe->qe_wr.send.wr_opcode = IBT_WRC_SEND;
497*13101SVenki.Rajagopalan@Sun.COM swqe->qe_wr.send.wr_nds = 1;
498*13101SVenki.Rajagopalan@Sun.COM swqe->qe_wr.send.wr_sgl = &swqe->qe_sgl;
499*13101SVenki.Rajagopalan@Sun.COM swqe->qe_wr.send.wr.ud.udwr_dest = dest;
500*13101SVenki.Rajagopalan@Sun.COM
501*13101SVenki.Rajagopalan@Sun.COM mutex_init(&swqe->qe_lock, NULL, MUTEX_DRIVER, NULL);
502*13101SVenki.Rajagopalan@Sun.COM swqe->qe_flags = 0;
503*13101SVenki.Rajagopalan@Sun.COM
504*13101SVenki.Rajagopalan@Sun.COM buf += mtu;
505*13101SVenki.Rajagopalan@Sun.COM }
506*13101SVenki.Rajagopalan@Sun.COM
507*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
508*13101SVenki.Rajagopalan@Sun.COM }
509*13101SVenki.Rajagopalan@Sun.COM
510*13101SVenki.Rajagopalan@Sun.COM /*
511*13101SVenki.Rajagopalan@Sun.COM * Set up bufs for receiving gateway advertisements
512*13101SVenki.Rajagopalan@Sun.COM */
513*13101SVenki.Rajagopalan@Sun.COM static int
eibnx_setup_rxbufs(eibnx_thr_info_t * info)514*13101SVenki.Rajagopalan@Sun.COM eibnx_setup_rxbufs(eibnx_thr_info_t *info)
515*13101SVenki.Rajagopalan@Sun.COM {
516*13101SVenki.Rajagopalan@Sun.COM eibnx_rx_t *rcv_p = &info->ti_rcv;
517*13101SVenki.Rajagopalan@Sun.COM eibnx_wqe_t *rwqe;
518*13101SVenki.Rajagopalan@Sun.COM ibt_mr_attr_t attr;
519*13101SVenki.Rajagopalan@Sun.COM ibt_mr_desc_t desc;
520*13101SVenki.Rajagopalan@Sun.COM ib_memlen_t rx_bufsz;
521*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
522*13101SVenki.Rajagopalan@Sun.COM uint8_t *buf;
523*13101SVenki.Rajagopalan@Sun.COM uint_t mtu = (128 << info->ti_pi->p_mtu);
524*13101SVenki.Rajagopalan@Sun.COM int i;
525*13101SVenki.Rajagopalan@Sun.COM
526*13101SVenki.Rajagopalan@Sun.COM /*
527*13101SVenki.Rajagopalan@Sun.COM * Allocate for the rx buf
528*13101SVenki.Rajagopalan@Sun.COM */
529*13101SVenki.Rajagopalan@Sun.COM rx_bufsz = ENX_NUM_RWQE * (mtu + ENX_GRH_SZ);
530*13101SVenki.Rajagopalan@Sun.COM rcv_p->rx_vaddr = (ib_vaddr_t)(uintptr_t)kmem_zalloc(rx_bufsz,
531*13101SVenki.Rajagopalan@Sun.COM KM_SLEEP);
532*13101SVenki.Rajagopalan@Sun.COM
533*13101SVenki.Rajagopalan@Sun.COM attr.mr_vaddr = rcv_p->rx_vaddr;
534*13101SVenki.Rajagopalan@Sun.COM attr.mr_len = rx_bufsz;
535*13101SVenki.Rajagopalan@Sun.COM attr.mr_as = NULL;
536*13101SVenki.Rajagopalan@Sun.COM attr.mr_flags = IBT_MR_SLEEP | IBT_MR_ENABLE_LOCAL_WRITE;
537*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_register_mr(info->ti_hca, info->ti_pd, &attr,
538*13101SVenki.Rajagopalan@Sun.COM &rcv_p->rx_mr, &desc)) != IBT_SUCCESS) {
539*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_register_mr() failed for rx "
540*13101SVenki.Rajagopalan@Sun.COM "region (0x%llx, 0x%llx) with ret=%d",
541*13101SVenki.Rajagopalan@Sun.COM attr.mr_vaddr, attr.mr_len, ret);
542*13101SVenki.Rajagopalan@Sun.COM kmem_free((void *)(uintptr_t)(rcv_p->rx_vaddr), rx_bufsz);
543*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
544*13101SVenki.Rajagopalan@Sun.COM }
545*13101SVenki.Rajagopalan@Sun.COM rcv_p->rx_lkey = desc.md_lkey;
546*13101SVenki.Rajagopalan@Sun.COM
547*13101SVenki.Rajagopalan@Sun.COM buf = (uint8_t *)(uintptr_t)(rcv_p->rx_vaddr);
548*13101SVenki.Rajagopalan@Sun.COM for (i = 0; i < ENX_NUM_RWQE; i++) {
549*13101SVenki.Rajagopalan@Sun.COM rwqe = &rcv_p->rx_wqe[i];
550*13101SVenki.Rajagopalan@Sun.COM
551*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_type = ENX_QETYP_RWQE;
552*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_bufsz = mtu + ENX_GRH_SZ;
553*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_sgl.ds_va = (ib_vaddr_t)(uintptr_t)buf;
554*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_sgl.ds_key = rcv_p->rx_lkey;
555*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_sgl.ds_len = rwqe->qe_bufsz;
556*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_wr.recv.wr_id = (ibt_wrid_t)(uintptr_t)rwqe;
557*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_wr.recv.wr_nds = 1;
558*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_wr.recv.wr_sgl = &rwqe->qe_sgl;
559*13101SVenki.Rajagopalan@Sun.COM
560*13101SVenki.Rajagopalan@Sun.COM mutex_init(&rwqe->qe_lock, NULL, MUTEX_DRIVER, NULL);
561*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_flags = 0;
562*13101SVenki.Rajagopalan@Sun.COM
563*13101SVenki.Rajagopalan@Sun.COM buf += (mtu + ENX_GRH_SZ);
564*13101SVenki.Rajagopalan@Sun.COM }
565*13101SVenki.Rajagopalan@Sun.COM
566*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
567*13101SVenki.Rajagopalan@Sun.COM }
568*13101SVenki.Rajagopalan@Sun.COM
569*13101SVenki.Rajagopalan@Sun.COM /*
570*13101SVenki.Rajagopalan@Sun.COM * Set up transmit and receive buffers and post the receive buffers
571*13101SVenki.Rajagopalan@Sun.COM */
572*13101SVenki.Rajagopalan@Sun.COM int
eibnx_setup_bufs(eibnx_thr_info_t * info)573*13101SVenki.Rajagopalan@Sun.COM eibnx_setup_bufs(eibnx_thr_info_t *info)
574*13101SVenki.Rajagopalan@Sun.COM {
575*13101SVenki.Rajagopalan@Sun.COM eibnx_rx_t *rcv_p = &info->ti_rcv;
576*13101SVenki.Rajagopalan@Sun.COM eibnx_wqe_t *rwqe;
577*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
578*13101SVenki.Rajagopalan@Sun.COM int i;
579*13101SVenki.Rajagopalan@Sun.COM
580*13101SVenki.Rajagopalan@Sun.COM if (eibnx_setup_txbufs(info) != ENX_E_SUCCESS)
581*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
582*13101SVenki.Rajagopalan@Sun.COM
583*13101SVenki.Rajagopalan@Sun.COM if (eibnx_setup_rxbufs(info) != ENX_E_SUCCESS) {
584*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_txbufs(info);
585*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
586*13101SVenki.Rajagopalan@Sun.COM }
587*13101SVenki.Rajagopalan@Sun.COM
588*13101SVenki.Rajagopalan@Sun.COM for (i = 0; i < ENX_NUM_RWQE; i++) {
589*13101SVenki.Rajagopalan@Sun.COM rwqe = &rcv_p->rx_wqe[i];
590*13101SVenki.Rajagopalan@Sun.COM
591*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&rwqe->qe_lock);
592*13101SVenki.Rajagopalan@Sun.COM
593*13101SVenki.Rajagopalan@Sun.COM rwqe->qe_flags |= (ENX_QEFL_INUSE | ENX_QEFL_POSTED);
594*13101SVenki.Rajagopalan@Sun.COM ret = ibt_post_recv(info->ti_chan, &(rwqe->qe_wr.recv), 1,
595*13101SVenki.Rajagopalan@Sun.COM NULL);
596*13101SVenki.Rajagopalan@Sun.COM
597*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&rwqe->qe_lock);
598*13101SVenki.Rajagopalan@Sun.COM
599*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
600*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_post_recv(chan_hdl=0x%llx) "
601*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", info->ti_chan, ret);
602*13101SVenki.Rajagopalan@Sun.COM
603*13101SVenki.Rajagopalan@Sun.COM ret = ibt_flush_channel(info->ti_chan);
604*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
605*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_flush_channel"
606*13101SVenki.Rajagopalan@Sun.COM "(chan_hdl=0x%llx) failed, ret=%d",
607*13101SVenki.Rajagopalan@Sun.COM info->ti_chan, ret);
608*13101SVenki.Rajagopalan@Sun.COM }
609*13101SVenki.Rajagopalan@Sun.COM
610*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_rxbufs(info);
611*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_txbufs(info);
612*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
613*13101SVenki.Rajagopalan@Sun.COM }
614*13101SVenki.Rajagopalan@Sun.COM }
615*13101SVenki.Rajagopalan@Sun.COM
616*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
617*13101SVenki.Rajagopalan@Sun.COM }
618*13101SVenki.Rajagopalan@Sun.COM
619*13101SVenki.Rajagopalan@Sun.COM /*
620*13101SVenki.Rajagopalan@Sun.COM * Set up the completion queue handler. While we don't quit if we cannot
621*13101SVenki.Rajagopalan@Sun.COM * use soft interrupts, that path is really unreliable and untested.
622*13101SVenki.Rajagopalan@Sun.COM */
623*13101SVenki.Rajagopalan@Sun.COM int
eibnx_setup_cq_handler(eibnx_thr_info_t * info)624*13101SVenki.Rajagopalan@Sun.COM eibnx_setup_cq_handler(eibnx_thr_info_t *info)
625*13101SVenki.Rajagopalan@Sun.COM {
626*13101SVenki.Rajagopalan@Sun.COM eibnx_t *ss = enx_global_ss;
627*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
628*13101SVenki.Rajagopalan@Sun.COM int rv;
629*13101SVenki.Rajagopalan@Sun.COM
630*13101SVenki.Rajagopalan@Sun.COM /*
631*13101SVenki.Rajagopalan@Sun.COM * We'll try to use a softintr if possible. If not, it's not
632*13101SVenki.Rajagopalan@Sun.COM * fatal, we'll try and use the completion handler directly from
633*13101SVenki.Rajagopalan@Sun.COM * the interrupt handler.
634*13101SVenki.Rajagopalan@Sun.COM */
635*13101SVenki.Rajagopalan@Sun.COM
636*13101SVenki.Rajagopalan@Sun.COM rv = ddi_intr_add_softint(ss->nx_dip, &info->ti_softint_hdl,
637*13101SVenki.Rajagopalan@Sun.COM EIB_SOFTPRI_ADM, eibnx_comp_handler, info);
638*13101SVenki.Rajagopalan@Sun.COM if (rv != DDI_SUCCESS) {
639*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ddi_intr_add_softint(dip=0x%llx) "
640*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", ss->nx_dip, rv);
641*13101SVenki.Rajagopalan@Sun.COM }
642*13101SVenki.Rajagopalan@Sun.COM
643*13101SVenki.Rajagopalan@Sun.COM ibt_set_cq_handler(info->ti_cq_hdl, eibnx_comp_intr, info);
644*13101SVenki.Rajagopalan@Sun.COM
645*13101SVenki.Rajagopalan@Sun.COM ret = ibt_enable_cq_notify(info->ti_cq_hdl, IBT_NEXT_COMPLETION);
646*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
647*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_enable_cq_notify(cq_hdl=0x%llx) "
648*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", info->ti_cq_hdl, ret);
649*13101SVenki.Rajagopalan@Sun.COM if (info->ti_softint_hdl) {
650*13101SVenki.Rajagopalan@Sun.COM (void) ddi_intr_remove_softint(info->ti_softint_hdl);
651*13101SVenki.Rajagopalan@Sun.COM info->ti_softint_hdl = NULL;
652*13101SVenki.Rajagopalan@Sun.COM }
653*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
654*13101SVenki.Rajagopalan@Sun.COM }
655*13101SVenki.Rajagopalan@Sun.COM
656*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
657*13101SVenki.Rajagopalan@Sun.COM }
658*13101SVenki.Rajagopalan@Sun.COM
659*13101SVenki.Rajagopalan@Sun.COM /*
660*13101SVenki.Rajagopalan@Sun.COM * Join the solicit multicast group (All-EoIB-GWs-GID) as a full member
661*13101SVenki.Rajagopalan@Sun.COM */
662*13101SVenki.Rajagopalan@Sun.COM static int
eibnx_join_solicit_mcg(eibnx_thr_info_t * info)663*13101SVenki.Rajagopalan@Sun.COM eibnx_join_solicit_mcg(eibnx_thr_info_t *info)
664*13101SVenki.Rajagopalan@Sun.COM {
665*13101SVenki.Rajagopalan@Sun.COM ib_gid_t rgid = info->ti_pi->p_sgid_tbl[0];
666*13101SVenki.Rajagopalan@Sun.COM ibt_mcg_attr_t mcg_attr;
667*13101SVenki.Rajagopalan@Sun.COM ibt_mcg_info_t mcg_info;
668*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
669*13101SVenki.Rajagopalan@Sun.COM
670*13101SVenki.Rajagopalan@Sun.COM bzero(&mcg_attr, sizeof (ibt_mcg_attr_t));
671*13101SVenki.Rajagopalan@Sun.COM
672*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_mgid = enx_solicit_mgid;
673*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_qkey = (ib_qkey_t)EIB_FIP_QKEY;
674*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_pkey = (ib_pkey_t)EIB_ADMIN_PKEY;
675*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_join_state = IB_MC_JSTATE_FULL;
676*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_flow = info->ti_solicit_mcg->mc_adds_vect.av_flow;
677*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_tclass = info->ti_solicit_mcg->mc_adds_vect.av_tclass;
678*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_sl = info->ti_solicit_mcg->mc_adds_vect.av_srvl;
679*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_scope = IB_MC_SCOPE_SUBNET_LOCAL;
680*13101SVenki.Rajagopalan@Sun.COM
681*13101SVenki.Rajagopalan@Sun.COM /*
682*13101SVenki.Rajagopalan@Sun.COM * We only need to send to solicit mcg, so we only need to join
683*13101SVenki.Rajagopalan@Sun.COM * the multicast group, no need to attach our qp to it
684*13101SVenki.Rajagopalan@Sun.COM */
685*13101SVenki.Rajagopalan@Sun.COM ret = ibt_join_mcg(rgid, &mcg_attr, &mcg_info, NULL, NULL);
686*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
687*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_join_mcg() failed for solicit "
688*13101SVenki.Rajagopalan@Sun.COM "mgid=%llx.%llx, ret=%x", enx_solicit_mgid.gid_prefix,
689*13101SVenki.Rajagopalan@Sun.COM enx_solicit_mgid.gid_guid, ret);
690*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
691*13101SVenki.Rajagopalan@Sun.COM }
692*13101SVenki.Rajagopalan@Sun.COM
693*13101SVenki.Rajagopalan@Sun.COM /*
694*13101SVenki.Rajagopalan@Sun.COM * We can throw away the old mcg info we got when we queried
695*13101SVenki.Rajagopalan@Sun.COM * for the mcg and use the new one. They both should be the
696*13101SVenki.Rajagopalan@Sun.COM * same, really.
697*13101SVenki.Rajagopalan@Sun.COM */
698*13101SVenki.Rajagopalan@Sun.COM if (info->ti_solicit_mcg) {
699*13101SVenki.Rajagopalan@Sun.COM bcopy(&mcg_info, info->ti_solicit_mcg,
700*13101SVenki.Rajagopalan@Sun.COM sizeof (ibt_mcg_info_t));
701*13101SVenki.Rajagopalan@Sun.COM }
702*13101SVenki.Rajagopalan@Sun.COM
703*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
704*13101SVenki.Rajagopalan@Sun.COM }
705*13101SVenki.Rajagopalan@Sun.COM
706*13101SVenki.Rajagopalan@Sun.COM /*
707*13101SVenki.Rajagopalan@Sun.COM * Join and attach to the advertise multicast group (All-EoIB-ENodes-GID)
708*13101SVenki.Rajagopalan@Sun.COM * to receive unsolicitied advertisements from the gateways.
709*13101SVenki.Rajagopalan@Sun.COM */
710*13101SVenki.Rajagopalan@Sun.COM static int
eibnx_join_advertise_mcg(eibnx_thr_info_t * info)711*13101SVenki.Rajagopalan@Sun.COM eibnx_join_advertise_mcg(eibnx_thr_info_t *info)
712*13101SVenki.Rajagopalan@Sun.COM {
713*13101SVenki.Rajagopalan@Sun.COM ib_gid_t rgid = info->ti_pi->p_sgid_tbl[0];
714*13101SVenki.Rajagopalan@Sun.COM ibt_mcg_attr_t mcg_attr;
715*13101SVenki.Rajagopalan@Sun.COM ibt_mcg_info_t mcg_info;
716*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
717*13101SVenki.Rajagopalan@Sun.COM
718*13101SVenki.Rajagopalan@Sun.COM if (info->ti_chan == NULL)
719*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
720*13101SVenki.Rajagopalan@Sun.COM
721*13101SVenki.Rajagopalan@Sun.COM bzero(&mcg_attr, sizeof (ibt_mcg_attr_t));
722*13101SVenki.Rajagopalan@Sun.COM
723*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_mgid = enx_advertise_mgid;
724*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_qkey = (ib_qkey_t)EIB_FIP_QKEY;
725*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_pkey = (ib_pkey_t)EIB_ADMIN_PKEY;
726*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_join_state = IB_MC_JSTATE_FULL;
727*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_flow = info->ti_advertise_mcg->mc_adds_vect.av_flow;
728*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_tclass = info->ti_advertise_mcg->mc_adds_vect.av_tclass;
729*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_sl = info->ti_advertise_mcg->mc_adds_vect.av_srvl;
730*13101SVenki.Rajagopalan@Sun.COM mcg_attr.mc_scope = IB_MC_SCOPE_SUBNET_LOCAL;
731*13101SVenki.Rajagopalan@Sun.COM
732*13101SVenki.Rajagopalan@Sun.COM ret = ibt_join_mcg(rgid, &mcg_attr, &mcg_info, NULL, NULL);
733*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
734*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_join_mcg() failed for advertise "
735*13101SVenki.Rajagopalan@Sun.COM "mgid=%llx.%llx, ret=%x", enx_advertise_mgid.gid_prefix,
736*13101SVenki.Rajagopalan@Sun.COM enx_advertise_mgid.gid_guid, ret);
737*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
738*13101SVenki.Rajagopalan@Sun.COM }
739*13101SVenki.Rajagopalan@Sun.COM
740*13101SVenki.Rajagopalan@Sun.COM /*
741*13101SVenki.Rajagopalan@Sun.COM * We can throw away the old mcg info we got when we queried
742*13101SVenki.Rajagopalan@Sun.COM * for the mcg and use the new one. They both should be the
743*13101SVenki.Rajagopalan@Sun.COM * same, really.
744*13101SVenki.Rajagopalan@Sun.COM */
745*13101SVenki.Rajagopalan@Sun.COM if (info->ti_advertise_mcg) {
746*13101SVenki.Rajagopalan@Sun.COM bcopy(&mcg_info, info->ti_advertise_mcg,
747*13101SVenki.Rajagopalan@Sun.COM sizeof (ibt_mcg_info_t));
748*13101SVenki.Rajagopalan@Sun.COM }
749*13101SVenki.Rajagopalan@Sun.COM
750*13101SVenki.Rajagopalan@Sun.COM /*
751*13101SVenki.Rajagopalan@Sun.COM * Since we need to receive advertisements, we'll attach our qp
752*13101SVenki.Rajagopalan@Sun.COM * to the advertise mcg
753*13101SVenki.Rajagopalan@Sun.COM */
754*13101SVenki.Rajagopalan@Sun.COM ret = ibt_attach_mcg(info->ti_chan, info->ti_advertise_mcg);
755*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
756*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_attach_mcg(chan_hdl=0x%llx, "
757*13101SVenki.Rajagopalan@Sun.COM "advt_mcg=0x%llx) failed, ret=%d", info->ti_chan,
758*13101SVenki.Rajagopalan@Sun.COM info->ti_advertise_mcg, ret);
759*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
760*13101SVenki.Rajagopalan@Sun.COM }
761*13101SVenki.Rajagopalan@Sun.COM
762*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
763*13101SVenki.Rajagopalan@Sun.COM }
764*13101SVenki.Rajagopalan@Sun.COM
765*13101SVenki.Rajagopalan@Sun.COM /*
766*13101SVenki.Rajagopalan@Sun.COM * Join the multicast groups we're interested in
767*13101SVenki.Rajagopalan@Sun.COM */
768*13101SVenki.Rajagopalan@Sun.COM int
eibnx_join_mcgs(eibnx_thr_info_t * info)769*13101SVenki.Rajagopalan@Sun.COM eibnx_join_mcgs(eibnx_thr_info_t *info)
770*13101SVenki.Rajagopalan@Sun.COM {
771*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&info->ti_mcg_lock);
772*13101SVenki.Rajagopalan@Sun.COM
773*13101SVenki.Rajagopalan@Sun.COM /*
774*13101SVenki.Rajagopalan@Sun.COM * We should've located the mcg first
775*13101SVenki.Rajagopalan@Sun.COM */
776*13101SVenki.Rajagopalan@Sun.COM if ((info->ti_mcg_status & ENX_MCGS_FOUND) == 0) {
777*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
778*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
779*13101SVenki.Rajagopalan@Sun.COM }
780*13101SVenki.Rajagopalan@Sun.COM
781*13101SVenki.Rajagopalan@Sun.COM /*
782*13101SVenki.Rajagopalan@Sun.COM * If we're already joined to the mcgs, we must leave first
783*13101SVenki.Rajagopalan@Sun.COM */
784*13101SVenki.Rajagopalan@Sun.COM if ((info->ti_mcg_status & ENX_MCGS_JOINED) == ENX_MCGS_JOINED) {
785*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
786*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
787*13101SVenki.Rajagopalan@Sun.COM }
788*13101SVenki.Rajagopalan@Sun.COM
789*13101SVenki.Rajagopalan@Sun.COM /*
790*13101SVenki.Rajagopalan@Sun.COM * Join the two mcgs
791*13101SVenki.Rajagopalan@Sun.COM */
792*13101SVenki.Rajagopalan@Sun.COM if (eibnx_join_advertise_mcg(info) != ENX_E_SUCCESS) {
793*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
794*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
795*13101SVenki.Rajagopalan@Sun.COM }
796*13101SVenki.Rajagopalan@Sun.COM if (eibnx_join_solicit_mcg(info) != ENX_E_SUCCESS) {
797*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_join_advertise_mcg(info);
798*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
799*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
800*13101SVenki.Rajagopalan@Sun.COM }
801*13101SVenki.Rajagopalan@Sun.COM
802*13101SVenki.Rajagopalan@Sun.COM info->ti_mcg_status |= ENX_MCGS_JOINED;
803*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
804*13101SVenki.Rajagopalan@Sun.COM
805*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
806*13101SVenki.Rajagopalan@Sun.COM }
807*13101SVenki.Rajagopalan@Sun.COM
808*13101SVenki.Rajagopalan@Sun.COM int
eibnx_rejoin_mcgs(eibnx_thr_info_t * info)809*13101SVenki.Rajagopalan@Sun.COM eibnx_rejoin_mcgs(eibnx_thr_info_t *info)
810*13101SVenki.Rajagopalan@Sun.COM {
811*13101SVenki.Rajagopalan@Sun.COM /*
812*13101SVenki.Rajagopalan@Sun.COM * Lookup the MCGs again and join them
813*13101SVenki.Rajagopalan@Sun.COM */
814*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_join_mcgs(info);
815*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_find_mgroups(info);
816*13101SVenki.Rajagopalan@Sun.COM
817*13101SVenki.Rajagopalan@Sun.COM if (eibnx_find_mgroups(info) != ENX_E_SUCCESS)
818*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
819*13101SVenki.Rajagopalan@Sun.COM
820*13101SVenki.Rajagopalan@Sun.COM if (eibnx_join_mcgs(info) != ENX_E_SUCCESS)
821*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
822*13101SVenki.Rajagopalan@Sun.COM
823*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
824*13101SVenki.Rajagopalan@Sun.COM }
825*13101SVenki.Rajagopalan@Sun.COM
826*13101SVenki.Rajagopalan@Sun.COM int
eibnx_ibt_fini(eibnx_t * ss)827*13101SVenki.Rajagopalan@Sun.COM eibnx_ibt_fini(eibnx_t *ss)
828*13101SVenki.Rajagopalan@Sun.COM {
829*13101SVenki.Rajagopalan@Sun.COM return (eibnx_rb_ibt_init(ss));
830*13101SVenki.Rajagopalan@Sun.COM }
831*13101SVenki.Rajagopalan@Sun.COM
832*13101SVenki.Rajagopalan@Sun.COM static int
eibnx_rb_ibt_init(eibnx_t * ss)833*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_ibt_init(eibnx_t *ss)
834*13101SVenki.Rajagopalan@Sun.COM {
835*13101SVenki.Rajagopalan@Sun.COM eibnx_hca_t *hca;
836*13101SVenki.Rajagopalan@Sun.COM eibnx_hca_t *hca_next;
837*13101SVenki.Rajagopalan@Sun.COM eibnx_hca_t *hca_list;
838*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
839*13101SVenki.Rajagopalan@Sun.COM
840*13101SVenki.Rajagopalan@Sun.COM /*
841*13101SVenki.Rajagopalan@Sun.COM * Disable subnet notices callbacks
842*13101SVenki.Rajagopalan@Sun.COM */
843*13101SVenki.Rajagopalan@Sun.COM ibt_register_subnet_notices(ss->nx_ibt_hdl, NULL, NULL);
844*13101SVenki.Rajagopalan@Sun.COM
845*13101SVenki.Rajagopalan@Sun.COM /*
846*13101SVenki.Rajagopalan@Sun.COM * Remove the hca list from the state structure
847*13101SVenki.Rajagopalan@Sun.COM */
848*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_lock);
849*13101SVenki.Rajagopalan@Sun.COM hca_list = ss->nx_hca;
850*13101SVenki.Rajagopalan@Sun.COM ss->nx_hca = NULL;
851*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_lock);
852*13101SVenki.Rajagopalan@Sun.COM
853*13101SVenki.Rajagopalan@Sun.COM /*
854*13101SVenki.Rajagopalan@Sun.COM * For each HCA in the list, free up the portinfo/port structs,
855*13101SVenki.Rajagopalan@Sun.COM * free the pd, close the hca handle and release the hca struct.
856*13101SVenki.Rajagopalan@Sun.COM * If something goes wrong, try to put back whatever good remains
857*13101SVenki.Rajagopalan@Sun.COM * back on the hca list and return failure.
858*13101SVenki.Rajagopalan@Sun.COM */
859*13101SVenki.Rajagopalan@Sun.COM for (hca = hca_list; hca; hca = hca_next) {
860*13101SVenki.Rajagopalan@Sun.COM hca_next = hca->hc_next;
861*13101SVenki.Rajagopalan@Sun.COM if (eibnx_cleanup_hca(hca) != ENX_E_SUCCESS) {
862*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_lock);
863*13101SVenki.Rajagopalan@Sun.COM ss->nx_hca = hca_next;
864*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_lock);
865*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
866*13101SVenki.Rajagopalan@Sun.COM }
867*13101SVenki.Rajagopalan@Sun.COM }
868*13101SVenki.Rajagopalan@Sun.COM
869*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_detach(ss->nx_ibt_hdl)) != IBT_SUCCESS) {
870*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_detach(ibt_hdl=0x%llx) "
871*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", ss->nx_ibt_hdl, ret);
872*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
873*13101SVenki.Rajagopalan@Sun.COM }
874*13101SVenki.Rajagopalan@Sun.COM ss->nx_ibt_hdl = NULL;
875*13101SVenki.Rajagopalan@Sun.COM
876*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_state_init();
877*13101SVenki.Rajagopalan@Sun.COM
878*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
879*13101SVenki.Rajagopalan@Sun.COM }
880*13101SVenki.Rajagopalan@Sun.COM
881*13101SVenki.Rajagopalan@Sun.COM static void
eibnx_rb_state_init(void)882*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_state_init(void)
883*13101SVenki.Rajagopalan@Sun.COM {
884*13101SVenki.Rajagopalan@Sun.COM eibnx_t *ss = enx_global_ss;
885*13101SVenki.Rajagopalan@Sun.COM kt_did_t thr_id;
886*13101SVenki.Rajagopalan@Sun.COM
887*13101SVenki.Rajagopalan@Sun.COM /*
888*13101SVenki.Rajagopalan@Sun.COM * Ask the eoib node creation thread to die and wait for
889*13101SVenki.Rajagopalan@Sun.COM * it to happen
890*13101SVenki.Rajagopalan@Sun.COM */
891*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_nodeq_lock);
892*13101SVenki.Rajagopalan@Sun.COM
893*13101SVenki.Rajagopalan@Sun.COM thr_id = ss->nx_nodeq_kt_did;
894*13101SVenki.Rajagopalan@Sun.COM ss->nx_nodeq_thr_die = 1;
895*13101SVenki.Rajagopalan@Sun.COM ss->nx_nodeq_kt_did = 0;
896*13101SVenki.Rajagopalan@Sun.COM
897*13101SVenki.Rajagopalan@Sun.COM cv_signal(&ss->nx_nodeq_cv);
898*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_nodeq_lock);
899*13101SVenki.Rajagopalan@Sun.COM
900*13101SVenki.Rajagopalan@Sun.COM if (thr_id) {
901*13101SVenki.Rajagopalan@Sun.COM thread_join(thr_id);
902*13101SVenki.Rajagopalan@Sun.COM }
903*13101SVenki.Rajagopalan@Sun.COM
904*13101SVenki.Rajagopalan@Sun.COM cv_destroy(&ss->nx_busop_cv);
905*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ss->nx_busop_lock);
906*13101SVenki.Rajagopalan@Sun.COM cv_destroy(&ss->nx_nodeq_cv);
907*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ss->nx_nodeq_lock);
908*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ss->nx_lock);
909*13101SVenki.Rajagopalan@Sun.COM }
910*13101SVenki.Rajagopalan@Sun.COM
911*13101SVenki.Rajagopalan@Sun.COM void
eibnx_rb_find_mgroups(eibnx_thr_info_t * info)912*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_find_mgroups(eibnx_thr_info_t *info)
913*13101SVenki.Rajagopalan@Sun.COM {
914*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&info->ti_mcg_lock);
915*13101SVenki.Rajagopalan@Sun.COM if ((info->ti_mcg_status & ENX_MCGS_FOUND) == ENX_MCGS_FOUND) {
916*13101SVenki.Rajagopalan@Sun.COM if (info->ti_advertise_mcg) {
917*13101SVenki.Rajagopalan@Sun.COM ibt_free_mcg_info(info->ti_advertise_mcg, 1);
918*13101SVenki.Rajagopalan@Sun.COM info->ti_advertise_mcg = NULL;
919*13101SVenki.Rajagopalan@Sun.COM }
920*13101SVenki.Rajagopalan@Sun.COM if (info->ti_solicit_mcg) {
921*13101SVenki.Rajagopalan@Sun.COM ibt_free_mcg_info(info->ti_solicit_mcg, 1);
922*13101SVenki.Rajagopalan@Sun.COM info->ti_solicit_mcg = NULL;
923*13101SVenki.Rajagopalan@Sun.COM }
924*13101SVenki.Rajagopalan@Sun.COM info->ti_mcg_status &= (~ENX_MCGS_FOUND);
925*13101SVenki.Rajagopalan@Sun.COM }
926*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
927*13101SVenki.Rajagopalan@Sun.COM }
928*13101SVenki.Rajagopalan@Sun.COM
929*13101SVenki.Rajagopalan@Sun.COM void
eibnx_rb_setup_cq(eibnx_thr_info_t * info)930*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_cq(eibnx_thr_info_t *info)
931*13101SVenki.Rajagopalan@Sun.COM {
932*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
933*13101SVenki.Rajagopalan@Sun.COM
934*13101SVenki.Rajagopalan@Sun.COM if (info->ti_wc && info->ti_cq_sz)
935*13101SVenki.Rajagopalan@Sun.COM kmem_free(info->ti_wc, sizeof (ibt_wc_t) * info->ti_cq_sz);
936*13101SVenki.Rajagopalan@Sun.COM
937*13101SVenki.Rajagopalan@Sun.COM info->ti_cq_sz = 0;
938*13101SVenki.Rajagopalan@Sun.COM info->ti_wc = NULL;
939*13101SVenki.Rajagopalan@Sun.COM
940*13101SVenki.Rajagopalan@Sun.COM if (info->ti_cq_hdl) {
941*13101SVenki.Rajagopalan@Sun.COM ret = ibt_free_cq(info->ti_cq_hdl);
942*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
943*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_free_cq(cq_hdl=0x%llx) "
944*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", info->ti_cq_hdl, ret);
945*13101SVenki.Rajagopalan@Sun.COM }
946*13101SVenki.Rajagopalan@Sun.COM info->ti_cq_hdl = NULL;
947*13101SVenki.Rajagopalan@Sun.COM }
948*13101SVenki.Rajagopalan@Sun.COM }
949*13101SVenki.Rajagopalan@Sun.COM
950*13101SVenki.Rajagopalan@Sun.COM void
eibnx_rb_setup_ud_channel(eibnx_thr_info_t * info)951*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_ud_channel(eibnx_thr_info_t *info)
952*13101SVenki.Rajagopalan@Sun.COM {
953*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
954*13101SVenki.Rajagopalan@Sun.COM
955*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_free_channel(info->ti_chan)) != IBT_SUCCESS) {
956*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_free_channel(chan=0x%llx) "
957*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", info->ti_chan, ret);
958*13101SVenki.Rajagopalan@Sun.COM }
959*13101SVenki.Rajagopalan@Sun.COM info->ti_chan = NULL;
960*13101SVenki.Rajagopalan@Sun.COM info->ti_qpn = 0;
961*13101SVenki.Rajagopalan@Sun.COM }
962*13101SVenki.Rajagopalan@Sun.COM
963*13101SVenki.Rajagopalan@Sun.COM static void
eibnx_rb_setup_txbufs(eibnx_thr_info_t * info)964*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_txbufs(eibnx_thr_info_t *info)
965*13101SVenki.Rajagopalan@Sun.COM {
966*13101SVenki.Rajagopalan@Sun.COM eibnx_tx_t *snd_p = &info->ti_snd;
967*13101SVenki.Rajagopalan@Sun.COM eibnx_wqe_t *swqe;
968*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
969*13101SVenki.Rajagopalan@Sun.COM int i;
970*13101SVenki.Rajagopalan@Sun.COM uint_t mtu = (128 << info->ti_pi->p_mtu);
971*13101SVenki.Rajagopalan@Sun.COM
972*13101SVenki.Rajagopalan@Sun.COM /*
973*13101SVenki.Rajagopalan@Sun.COM * Release any UD destination handle we may have allocated. Note that
974*13101SVenki.Rajagopalan@Sun.COM * the per swqe lock would've been initialized only if we were able to
975*13101SVenki.Rajagopalan@Sun.COM * allocate the UD dest handle.
976*13101SVenki.Rajagopalan@Sun.COM */
977*13101SVenki.Rajagopalan@Sun.COM for (i = 0; i < ENX_NUM_SWQE; i++) {
978*13101SVenki.Rajagopalan@Sun.COM swqe = &snd_p->tx_wqe[i];
979*13101SVenki.Rajagopalan@Sun.COM
980*13101SVenki.Rajagopalan@Sun.COM if (swqe->qe_wr.send.wr.ud.udwr_dest) {
981*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&swqe->qe_lock);
982*13101SVenki.Rajagopalan@Sun.COM
983*13101SVenki.Rajagopalan@Sun.COM ret =
984*13101SVenki.Rajagopalan@Sun.COM ibt_free_ud_dest(swqe->qe_wr.send.wr.ud.udwr_dest);
985*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
986*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_free_ud_dest(dest=0x%llx)"
987*13101SVenki.Rajagopalan@Sun.COM " failed, ret=%d",
988*13101SVenki.Rajagopalan@Sun.COM swqe->qe_wr.send.wr.ud.udwr_dest, ret);
989*13101SVenki.Rajagopalan@Sun.COM }
990*13101SVenki.Rajagopalan@Sun.COM }
991*13101SVenki.Rajagopalan@Sun.COM }
992*13101SVenki.Rajagopalan@Sun.COM
993*13101SVenki.Rajagopalan@Sun.COM /*
994*13101SVenki.Rajagopalan@Sun.COM * Clear all the workq entries
995*13101SVenki.Rajagopalan@Sun.COM */
996*13101SVenki.Rajagopalan@Sun.COM bzero(snd_p->tx_wqe, sizeof (eibnx_wqe_t) * ENX_NUM_SWQE);
997*13101SVenki.Rajagopalan@Sun.COM
998*13101SVenki.Rajagopalan@Sun.COM /*
999*13101SVenki.Rajagopalan@Sun.COM * Clear Lkey and deregister any memory region we may have
1000*13101SVenki.Rajagopalan@Sun.COM * registered earlier
1001*13101SVenki.Rajagopalan@Sun.COM */
1002*13101SVenki.Rajagopalan@Sun.COM snd_p->tx_lkey = 0;
1003*13101SVenki.Rajagopalan@Sun.COM if (snd_p->tx_mr) {
1004*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_deregister_mr(info->ti_hca,
1005*13101SVenki.Rajagopalan@Sun.COM snd_p->tx_mr)) != IBT_SUCCESS) {
1006*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_deregister_TXmr(hca_hdl=0x%llx,"
1007*13101SVenki.Rajagopalan@Sun.COM "mr=0x%llx) failed, ret=%d", info->ti_hca,
1008*13101SVenki.Rajagopalan@Sun.COM snd_p->tx_mr, ret);
1009*13101SVenki.Rajagopalan@Sun.COM }
1010*13101SVenki.Rajagopalan@Sun.COM snd_p->tx_mr = NULL;
1011*13101SVenki.Rajagopalan@Sun.COM }
1012*13101SVenki.Rajagopalan@Sun.COM
1013*13101SVenki.Rajagopalan@Sun.COM /*
1014*13101SVenki.Rajagopalan@Sun.COM * Release any memory allocated for the tx bufs
1015*13101SVenki.Rajagopalan@Sun.COM */
1016*13101SVenki.Rajagopalan@Sun.COM if (snd_p->tx_vaddr) {
1017*13101SVenki.Rajagopalan@Sun.COM kmem_free((void *)(uintptr_t)(snd_p->tx_vaddr),
1018*13101SVenki.Rajagopalan@Sun.COM ENX_NUM_SWQE * mtu);
1019*13101SVenki.Rajagopalan@Sun.COM snd_p->tx_vaddr = 0;
1020*13101SVenki.Rajagopalan@Sun.COM }
1021*13101SVenki.Rajagopalan@Sun.COM
1022*13101SVenki.Rajagopalan@Sun.COM }
1023*13101SVenki.Rajagopalan@Sun.COM
1024*13101SVenki.Rajagopalan@Sun.COM static void
eibnx_rb_setup_rxbufs(eibnx_thr_info_t * info)1025*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_rxbufs(eibnx_thr_info_t *info)
1026*13101SVenki.Rajagopalan@Sun.COM {
1027*13101SVenki.Rajagopalan@Sun.COM eibnx_rx_t *rcv_p = &info->ti_rcv;
1028*13101SVenki.Rajagopalan@Sun.COM eibnx_wqe_t *rwqe;
1029*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
1030*13101SVenki.Rajagopalan@Sun.COM uint_t mtu = (128 << info->ti_pi->p_mtu);
1031*13101SVenki.Rajagopalan@Sun.COM int i;
1032*13101SVenki.Rajagopalan@Sun.COM
1033*13101SVenki.Rajagopalan@Sun.COM for (i = 0; i < ENX_NUM_RWQE; i++) {
1034*13101SVenki.Rajagopalan@Sun.COM rwqe = &rcv_p->rx_wqe[i];
1035*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&rwqe->qe_lock);
1036*13101SVenki.Rajagopalan@Sun.COM }
1037*13101SVenki.Rajagopalan@Sun.COM bzero(rcv_p->rx_wqe, sizeof (eibnx_wqe_t) * ENX_NUM_RWQE);
1038*13101SVenki.Rajagopalan@Sun.COM
1039*13101SVenki.Rajagopalan@Sun.COM rcv_p->rx_lkey = 0;
1040*13101SVenki.Rajagopalan@Sun.COM
1041*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_deregister_mr(info->ti_hca,
1042*13101SVenki.Rajagopalan@Sun.COM rcv_p->rx_mr)) != IBT_SUCCESS) {
1043*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_deregister_RXmr(hca_hdl=0x%llx,"
1044*13101SVenki.Rajagopalan@Sun.COM "mr=0x%llx) failed, ret=%d", info->ti_hca,
1045*13101SVenki.Rajagopalan@Sun.COM rcv_p->rx_mr, ret);
1046*13101SVenki.Rajagopalan@Sun.COM }
1047*13101SVenki.Rajagopalan@Sun.COM rcv_p->rx_mr = NULL;
1048*13101SVenki.Rajagopalan@Sun.COM
1049*13101SVenki.Rajagopalan@Sun.COM kmem_free((void *)(uintptr_t)(rcv_p->rx_vaddr),
1050*13101SVenki.Rajagopalan@Sun.COM ENX_NUM_RWQE * (mtu + ENX_GRH_SZ));
1051*13101SVenki.Rajagopalan@Sun.COM rcv_p->rx_vaddr = 0;
1052*13101SVenki.Rajagopalan@Sun.COM }
1053*13101SVenki.Rajagopalan@Sun.COM
1054*13101SVenki.Rajagopalan@Sun.COM void
eibnx_rb_setup_bufs(eibnx_thr_info_t * info)1055*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_bufs(eibnx_thr_info_t *info)
1056*13101SVenki.Rajagopalan@Sun.COM {
1057*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
1058*13101SVenki.Rajagopalan@Sun.COM
1059*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_flush_channel(info->ti_chan)) != IBT_SUCCESS) {
1060*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_flush_channel(chan_hdl=0x%llx) "
1061*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", info->ti_chan, ret);
1062*13101SVenki.Rajagopalan@Sun.COM }
1063*13101SVenki.Rajagopalan@Sun.COM
1064*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_rxbufs(info);
1065*13101SVenki.Rajagopalan@Sun.COM
1066*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_txbufs(info);
1067*13101SVenki.Rajagopalan@Sun.COM }
1068*13101SVenki.Rajagopalan@Sun.COM
1069*13101SVenki.Rajagopalan@Sun.COM void
eibnx_rb_setup_cq_handler(eibnx_thr_info_t * info)1070*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_setup_cq_handler(eibnx_thr_info_t *info)
1071*13101SVenki.Rajagopalan@Sun.COM {
1072*13101SVenki.Rajagopalan@Sun.COM ibt_set_cq_handler(info->ti_cq_hdl, NULL, NULL);
1073*13101SVenki.Rajagopalan@Sun.COM
1074*13101SVenki.Rajagopalan@Sun.COM if (info->ti_softint_hdl) {
1075*13101SVenki.Rajagopalan@Sun.COM (void) ddi_intr_remove_softint(info->ti_softint_hdl);
1076*13101SVenki.Rajagopalan@Sun.COM info->ti_softint_hdl = NULL;
1077*13101SVenki.Rajagopalan@Sun.COM }
1078*13101SVenki.Rajagopalan@Sun.COM }
1079*13101SVenki.Rajagopalan@Sun.COM
1080*13101SVenki.Rajagopalan@Sun.COM static void
eibnx_rb_join_solicit_mcg(eibnx_thr_info_t * info)1081*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_join_solicit_mcg(eibnx_thr_info_t *info)
1082*13101SVenki.Rajagopalan@Sun.COM {
1083*13101SVenki.Rajagopalan@Sun.COM ib_gid_t rgid = info->ti_pi->p_sgid_tbl[0];
1084*13101SVenki.Rajagopalan@Sun.COM ib_gid_t rsvd_gid;
1085*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
1086*13101SVenki.Rajagopalan@Sun.COM
1087*13101SVenki.Rajagopalan@Sun.COM rsvd_gid.gid_prefix = 0;
1088*13101SVenki.Rajagopalan@Sun.COM rsvd_gid.gid_guid = 0;
1089*13101SVenki.Rajagopalan@Sun.COM
1090*13101SVenki.Rajagopalan@Sun.COM ret = ibt_leave_mcg(rgid, enx_solicit_mgid,
1091*13101SVenki.Rajagopalan@Sun.COM rsvd_gid, IB_MC_JSTATE_FULL);
1092*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
1093*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_leave_mcg(slct_mgid=%llx.%llx) "
1094*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", enx_solicit_mgid.gid_prefix,
1095*13101SVenki.Rajagopalan@Sun.COM enx_solicit_mgid.gid_guid, ret);
1096*13101SVenki.Rajagopalan@Sun.COM }
1097*13101SVenki.Rajagopalan@Sun.COM }
1098*13101SVenki.Rajagopalan@Sun.COM
1099*13101SVenki.Rajagopalan@Sun.COM static void
eibnx_rb_join_advertise_mcg(eibnx_thr_info_t * info)1100*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_join_advertise_mcg(eibnx_thr_info_t *info)
1101*13101SVenki.Rajagopalan@Sun.COM {
1102*13101SVenki.Rajagopalan@Sun.COM ib_gid_t rgid = info->ti_pi->p_sgid_tbl[0];
1103*13101SVenki.Rajagopalan@Sun.COM ib_gid_t rsvd_gid;
1104*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
1105*13101SVenki.Rajagopalan@Sun.COM
1106*13101SVenki.Rajagopalan@Sun.COM ret = ibt_detach_mcg(info->ti_chan, info->ti_advertise_mcg);
1107*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
1108*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_detach_mcg(chan_hdl=0x%llx, "
1109*13101SVenki.Rajagopalan@Sun.COM "advt_mcg=0x%llx) failed, ret=%d",
1110*13101SVenki.Rajagopalan@Sun.COM info->ti_chan, info->ti_advertise_mcg, ret);
1111*13101SVenki.Rajagopalan@Sun.COM }
1112*13101SVenki.Rajagopalan@Sun.COM
1113*13101SVenki.Rajagopalan@Sun.COM rsvd_gid.gid_prefix = 0;
1114*13101SVenki.Rajagopalan@Sun.COM rsvd_gid.gid_guid = 0;
1115*13101SVenki.Rajagopalan@Sun.COM
1116*13101SVenki.Rajagopalan@Sun.COM ret = ibt_leave_mcg(rgid, enx_advertise_mgid,
1117*13101SVenki.Rajagopalan@Sun.COM rsvd_gid, IB_MC_JSTATE_FULL);
1118*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
1119*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_leave_mcg(advt_mgid=%llx.%llx) "
1120*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", enx_advertise_mgid.gid_prefix,
1121*13101SVenki.Rajagopalan@Sun.COM enx_advertise_mgid.gid_guid, ret);
1122*13101SVenki.Rajagopalan@Sun.COM }
1123*13101SVenki.Rajagopalan@Sun.COM }
1124*13101SVenki.Rajagopalan@Sun.COM
1125*13101SVenki.Rajagopalan@Sun.COM void
eibnx_rb_join_mcgs(eibnx_thr_info_t * info)1126*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_join_mcgs(eibnx_thr_info_t *info)
1127*13101SVenki.Rajagopalan@Sun.COM {
1128*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&info->ti_mcg_lock);
1129*13101SVenki.Rajagopalan@Sun.COM if ((info->ti_mcg_status & ENX_MCGS_JOINED) == ENX_MCGS_JOINED) {
1130*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_join_solicit_mcg(info);
1131*13101SVenki.Rajagopalan@Sun.COM eibnx_rb_join_advertise_mcg(info);
1132*13101SVenki.Rajagopalan@Sun.COM
1133*13101SVenki.Rajagopalan@Sun.COM info->ti_mcg_status &= (~ENX_MCGS_JOINED);
1134*13101SVenki.Rajagopalan@Sun.COM }
1135*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_mcg_lock);
1136*13101SVenki.Rajagopalan@Sun.COM }
1137*13101SVenki.Rajagopalan@Sun.COM
1138*13101SVenki.Rajagopalan@Sun.COM eibnx_hca_t *
eibnx_prepare_hca(ib_guid_t hca_guid)1139*13101SVenki.Rajagopalan@Sun.COM eibnx_prepare_hca(ib_guid_t hca_guid)
1140*13101SVenki.Rajagopalan@Sun.COM {
1141*13101SVenki.Rajagopalan@Sun.COM eibnx_t *ss = enx_global_ss;
1142*13101SVenki.Rajagopalan@Sun.COM eibnx_hca_t *hca;
1143*13101SVenki.Rajagopalan@Sun.COM eibnx_port_t *port;
1144*13101SVenki.Rajagopalan@Sun.COM eibnx_port_t *port_tail;
1145*13101SVenki.Rajagopalan@Sun.COM ibt_hca_hdl_t hca_hdl;
1146*13101SVenki.Rajagopalan@Sun.COM ibt_pd_hdl_t pd_hdl;
1147*13101SVenki.Rajagopalan@Sun.COM ibt_hca_portinfo_t *pi;
1148*13101SVenki.Rajagopalan@Sun.COM uint_t num_pi;
1149*13101SVenki.Rajagopalan@Sun.COM uint_t size_pi;
1150*13101SVenki.Rajagopalan@Sun.COM ibt_hca_attr_t hca_attr;
1151*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
1152*13101SVenki.Rajagopalan@Sun.COM int i;
1153*13101SVenki.Rajagopalan@Sun.COM
1154*13101SVenki.Rajagopalan@Sun.COM ret = ibt_open_hca(ss->nx_ibt_hdl, hca_guid, &hca_hdl);
1155*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
1156*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_open_hca(hca_guid=0x%llx) "
1157*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", hca_guid, ret);
1158*13101SVenki.Rajagopalan@Sun.COM return (NULL);
1159*13101SVenki.Rajagopalan@Sun.COM }
1160*13101SVenki.Rajagopalan@Sun.COM
1161*13101SVenki.Rajagopalan@Sun.COM bzero(&hca_attr, sizeof (ibt_hca_attr_t));
1162*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_query_hca(hca_hdl, &hca_attr)) != IBT_SUCCESS) {
1163*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_query_hca(hca_hdl=0x%llx, "
1164*13101SVenki.Rajagopalan@Sun.COM "hca_guid=0x%llx) failed, ret=%d",
1165*13101SVenki.Rajagopalan@Sun.COM hca_hdl, hca_guid, ret);
1166*13101SVenki.Rajagopalan@Sun.COM
1167*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_close_hca(hca_hdl)) != IBT_SUCCESS) {
1168*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_close_hca(hca_hdl=0x%llx) "
1169*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", hca_hdl, ret);
1170*13101SVenki.Rajagopalan@Sun.COM }
1171*13101SVenki.Rajagopalan@Sun.COM return (NULL);
1172*13101SVenki.Rajagopalan@Sun.COM }
1173*13101SVenki.Rajagopalan@Sun.COM
1174*13101SVenki.Rajagopalan@Sun.COM ret = ibt_alloc_pd(hca_hdl, IBT_PD_NO_FLAGS, &pd_hdl);
1175*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
1176*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ibt_alloc_pd(hca_hdl=0x%llx, "
1177*13101SVenki.Rajagopalan@Sun.COM "hca_guid=0x%llx) failed, ret=%d",
1178*13101SVenki.Rajagopalan@Sun.COM hca_hdl, hca_guid, ret);
1179*13101SVenki.Rajagopalan@Sun.COM
1180*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_close_hca(hca_hdl)) != IBT_SUCCESS) {
1181*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_close_hca(hca_hdl=0x%llx) "
1182*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", hca_hdl, ret);
1183*13101SVenki.Rajagopalan@Sun.COM }
1184*13101SVenki.Rajagopalan@Sun.COM return (NULL);
1185*13101SVenki.Rajagopalan@Sun.COM }
1186*13101SVenki.Rajagopalan@Sun.COM
1187*13101SVenki.Rajagopalan@Sun.COM /*
1188*13101SVenki.Rajagopalan@Sun.COM * We have all the information we want about this hca, create
1189*13101SVenki.Rajagopalan@Sun.COM * a new struct and return it.
1190*13101SVenki.Rajagopalan@Sun.COM */
1191*13101SVenki.Rajagopalan@Sun.COM hca = kmem_zalloc(sizeof (eibnx_hca_t), KM_SLEEP);
1192*13101SVenki.Rajagopalan@Sun.COM hca->hc_next = NULL;
1193*13101SVenki.Rajagopalan@Sun.COM hca->hc_guid = hca_guid;
1194*13101SVenki.Rajagopalan@Sun.COM hca->hc_hdl = hca_hdl;
1195*13101SVenki.Rajagopalan@Sun.COM hca->hc_pd = pd_hdl;
1196*13101SVenki.Rajagopalan@Sun.COM hca->hc_port = port_tail = NULL;
1197*13101SVenki.Rajagopalan@Sun.COM
1198*13101SVenki.Rajagopalan@Sun.COM for (i = 0; i < hca_attr.hca_nports; i++) {
1199*13101SVenki.Rajagopalan@Sun.COM ret = ibt_query_hca_ports(hca_hdl, i + 1, &pi,
1200*13101SVenki.Rajagopalan@Sun.COM &num_pi, &size_pi);
1201*13101SVenki.Rajagopalan@Sun.COM if (ret != IBT_SUCCESS) {
1202*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_query_hca_ports(hca_hdl=0x%llx, "
1203*13101SVenki.Rajagopalan@Sun.COM "port=0x%x) failed, ret=%d", hca_hdl, i + 1, ret);
1204*13101SVenki.Rajagopalan@Sun.COM } else {
1205*13101SVenki.Rajagopalan@Sun.COM port = kmem_zalloc(sizeof (eibnx_port_t), KM_SLEEP);
1206*13101SVenki.Rajagopalan@Sun.COM port->po_next = NULL;
1207*13101SVenki.Rajagopalan@Sun.COM port->po_pi = pi;
1208*13101SVenki.Rajagopalan@Sun.COM port->po_pi_size = size_pi;
1209*13101SVenki.Rajagopalan@Sun.COM
1210*13101SVenki.Rajagopalan@Sun.COM if (port_tail) {
1211*13101SVenki.Rajagopalan@Sun.COM port_tail->po_next = port;
1212*13101SVenki.Rajagopalan@Sun.COM } else {
1213*13101SVenki.Rajagopalan@Sun.COM hca->hc_port = port;
1214*13101SVenki.Rajagopalan@Sun.COM }
1215*13101SVenki.Rajagopalan@Sun.COM port_tail = port;
1216*13101SVenki.Rajagopalan@Sun.COM }
1217*13101SVenki.Rajagopalan@Sun.COM }
1218*13101SVenki.Rajagopalan@Sun.COM
1219*13101SVenki.Rajagopalan@Sun.COM /*
1220*13101SVenki.Rajagopalan@Sun.COM * If we couldn't query about any ports on the HCA, return failure
1221*13101SVenki.Rajagopalan@Sun.COM */
1222*13101SVenki.Rajagopalan@Sun.COM if (hca->hc_port == NULL) {
1223*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("all hca port queries failed for "
1224*13101SVenki.Rajagopalan@Sun.COM "hca_guid=0x%llx", hca_guid);
1225*13101SVenki.Rajagopalan@Sun.COM (void) eibnx_cleanup_hca(hca);
1226*13101SVenki.Rajagopalan@Sun.COM return (NULL);
1227*13101SVenki.Rajagopalan@Sun.COM }
1228*13101SVenki.Rajagopalan@Sun.COM
1229*13101SVenki.Rajagopalan@Sun.COM return (hca);
1230*13101SVenki.Rajagopalan@Sun.COM }
1231*13101SVenki.Rajagopalan@Sun.COM
1232*13101SVenki.Rajagopalan@Sun.COM int
eibnx_cleanup_hca(eibnx_hca_t * hca)1233*13101SVenki.Rajagopalan@Sun.COM eibnx_cleanup_hca(eibnx_hca_t *hca)
1234*13101SVenki.Rajagopalan@Sun.COM {
1235*13101SVenki.Rajagopalan@Sun.COM eibnx_port_t *port;
1236*13101SVenki.Rajagopalan@Sun.COM eibnx_port_t *port_next;
1237*13101SVenki.Rajagopalan@Sun.COM ibt_status_t ret;
1238*13101SVenki.Rajagopalan@Sun.COM
1239*13101SVenki.Rajagopalan@Sun.COM for (port = hca->hc_port; port; port = port_next) {
1240*13101SVenki.Rajagopalan@Sun.COM port_next = port->po_next;
1241*13101SVenki.Rajagopalan@Sun.COM
1242*13101SVenki.Rajagopalan@Sun.COM ibt_free_portinfo(port->po_pi, port->po_pi_size);
1243*13101SVenki.Rajagopalan@Sun.COM kmem_free(port, sizeof (eibnx_port_t));
1244*13101SVenki.Rajagopalan@Sun.COM }
1245*13101SVenki.Rajagopalan@Sun.COM
1246*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_free_pd(hca->hc_hdl, hca->hc_pd)) != IBT_SUCCESS) {
1247*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_free_pd(hca_hdl=0x%lx, pd_hd=0x%lx) "
1248*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", hca->hc_hdl, hca->hc_pd, ret);
1249*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
1250*13101SVenki.Rajagopalan@Sun.COM }
1251*13101SVenki.Rajagopalan@Sun.COM
1252*13101SVenki.Rajagopalan@Sun.COM if ((ret = ibt_close_hca(hca->hc_hdl)) != IBT_SUCCESS) {
1253*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibt_close_hca(hca_hdl=0x%lx) failed, "
1254*13101SVenki.Rajagopalan@Sun.COM "ret=%d", hca->hc_hdl, ret);
1255*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
1256*13101SVenki.Rajagopalan@Sun.COM }
1257*13101SVenki.Rajagopalan@Sun.COM
1258*13101SVenki.Rajagopalan@Sun.COM kmem_free(hca, sizeof (eibnx_hca_t));
1259*13101SVenki.Rajagopalan@Sun.COM
1260*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
1261*13101SVenki.Rajagopalan@Sun.COM }
1262