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 #include <sys/callb.h>
33*13101SVenki.Rajagopalan@Sun.COM #include <sys/mac_provider.h>
34*13101SVenki.Rajagopalan@Sun.COM
35*13101SVenki.Rajagopalan@Sun.COM #include <sys/ib/clients/eoib/eib_impl.h>
36*13101SVenki.Rajagopalan@Sun.COM
37*13101SVenki.Rajagopalan@Sun.COM /*
38*13101SVenki.Rajagopalan@Sun.COM * Thread to handle EoIB events asynchronously
39*13101SVenki.Rajagopalan@Sun.COM */
40*13101SVenki.Rajagopalan@Sun.COM void
eib_events_handler(eib_t * ss)41*13101SVenki.Rajagopalan@Sun.COM eib_events_handler(eib_t *ss)
42*13101SVenki.Rajagopalan@Sun.COM {
43*13101SVenki.Rajagopalan@Sun.COM eib_event_t *evi;
44*13101SVenki.Rajagopalan@Sun.COM eib_event_t *nxt;
45*13101SVenki.Rajagopalan@Sun.COM kmutex_t ci_lock;
46*13101SVenki.Rajagopalan@Sun.COM callb_cpr_t ci;
47*13101SVenki.Rajagopalan@Sun.COM
48*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ci_lock, NULL, MUTEX_DRIVER, NULL);
49*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_INIT(&ci, &ci_lock, callb_generic_cpr, EIB_EVENTS_HDLR);
50*13101SVenki.Rajagopalan@Sun.COM
51*13101SVenki.Rajagopalan@Sun.COM wait_for_event:
52*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_ev_lock);
53*13101SVenki.Rajagopalan@Sun.COM while ((evi = ss->ei_event) == NULL) {
54*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
55*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_BEGIN(&ci);
56*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
57*13101SVenki.Rajagopalan@Sun.COM
58*13101SVenki.Rajagopalan@Sun.COM cv_wait(&ss->ei_ev_cv, &ss->ei_ev_lock);
59*13101SVenki.Rajagopalan@Sun.COM
60*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
61*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_END(&ci, &ci_lock);
62*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
63*13101SVenki.Rajagopalan@Sun.COM }
64*13101SVenki.Rajagopalan@Sun.COM
65*13101SVenki.Rajagopalan@Sun.COM /*
66*13101SVenki.Rajagopalan@Sun.COM * Are we being asked to die ?
67*13101SVenki.Rajagopalan@Sun.COM */
68*13101SVenki.Rajagopalan@Sun.COM if (evi->ev_code == EIB_EV_SHUTDOWN) {
69*13101SVenki.Rajagopalan@Sun.COM while (evi) {
70*13101SVenki.Rajagopalan@Sun.COM nxt = evi->ev_next;
71*13101SVenki.Rajagopalan@Sun.COM kmem_free(evi, sizeof (eib_event_t));
72*13101SVenki.Rajagopalan@Sun.COM evi = nxt;
73*13101SVenki.Rajagopalan@Sun.COM }
74*13101SVenki.Rajagopalan@Sun.COM ss->ei_event = NULL;
75*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_ev_lock);
76*13101SVenki.Rajagopalan@Sun.COM
77*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
78*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_EXIT(&ci);
79*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ci_lock);
80*13101SVenki.Rajagopalan@Sun.COM
81*13101SVenki.Rajagopalan@Sun.COM return;
82*13101SVenki.Rajagopalan@Sun.COM }
83*13101SVenki.Rajagopalan@Sun.COM
84*13101SVenki.Rajagopalan@Sun.COM /*
85*13101SVenki.Rajagopalan@Sun.COM * Otherwise, pull out the first entry from our work queue
86*13101SVenki.Rajagopalan@Sun.COM */
87*13101SVenki.Rajagopalan@Sun.COM ss->ei_event = evi->ev_next;
88*13101SVenki.Rajagopalan@Sun.COM evi->ev_next = NULL;
89*13101SVenki.Rajagopalan@Sun.COM
90*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_ev_lock);
91*13101SVenki.Rajagopalan@Sun.COM
92*13101SVenki.Rajagopalan@Sun.COM /*
93*13101SVenki.Rajagopalan@Sun.COM * Process this event
94*13101SVenki.Rajagopalan@Sun.COM *
95*13101SVenki.Rajagopalan@Sun.COM * Note that we don't want to race with plumb/unplumb in this
96*13101SVenki.Rajagopalan@Sun.COM * handler, since we may have to restart vnics or do stuff that
97*13101SVenki.Rajagopalan@Sun.COM * may get re-initialized or released if we allowed plumb/unplumb
98*13101SVenki.Rajagopalan@Sun.COM * to happen in parallel.
99*13101SVenki.Rajagopalan@Sun.COM */
100*13101SVenki.Rajagopalan@Sun.COM eib_mac_set_nic_state(ss, EIB_NIC_RESTARTING);
101*13101SVenki.Rajagopalan@Sun.COM
102*13101SVenki.Rajagopalan@Sun.COM switch (evi->ev_code) {
103*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_PORT_DOWN:
104*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
105*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin EIB_EV_PORT_DOWN");
106*13101SVenki.Rajagopalan@Sun.COM
107*13101SVenki.Rajagopalan@Sun.COM eib_mac_link_down(ss, B_FALSE);
108*13101SVenki.Rajagopalan@Sun.COM
109*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
110*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: End EIB_EV_PORT_DOWN");
111*13101SVenki.Rajagopalan@Sun.COM break;
112*13101SVenki.Rajagopalan@Sun.COM
113*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_PORT_UP:
114*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
115*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin EIB_EV_PORT_UP");
116*13101SVenki.Rajagopalan@Sun.COM
117*13101SVenki.Rajagopalan@Sun.COM eib_ibt_link_mod(ss);
118*13101SVenki.Rajagopalan@Sun.COM
119*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
120*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: End EIB_EV_PORT_UP");
121*13101SVenki.Rajagopalan@Sun.COM break;
122*13101SVenki.Rajagopalan@Sun.COM
123*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_PKEY_CHANGE:
124*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
125*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin EIB_EV_PKEY_CHANGE");
126*13101SVenki.Rajagopalan@Sun.COM
127*13101SVenki.Rajagopalan@Sun.COM eib_ibt_link_mod(ss);
128*13101SVenki.Rajagopalan@Sun.COM
129*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
130*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: End EIB_EV_PKEY_CHANGE");
131*13101SVenki.Rajagopalan@Sun.COM break;
132*13101SVenki.Rajagopalan@Sun.COM
133*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_SGID_CHANGE:
134*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
135*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin EIB_EV_SGID_CHANGE");
136*13101SVenki.Rajagopalan@Sun.COM
137*13101SVenki.Rajagopalan@Sun.COM eib_ibt_link_mod(ss);
138*13101SVenki.Rajagopalan@Sun.COM
139*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
140*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: End EIB_EV_SGID_CHANGE");
141*13101SVenki.Rajagopalan@Sun.COM break;
142*13101SVenki.Rajagopalan@Sun.COM
143*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_CLNT_REREG:
144*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
145*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin EIB_EV_CLNT_REREG");
146*13101SVenki.Rajagopalan@Sun.COM
147*13101SVenki.Rajagopalan@Sun.COM eib_ibt_link_mod(ss);
148*13101SVenki.Rajagopalan@Sun.COM
149*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
150*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: End EIB_EV_CLNT_REREG");
151*13101SVenki.Rajagopalan@Sun.COM break;
152*13101SVenki.Rajagopalan@Sun.COM
153*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_GW_UP:
154*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
155*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin EIB_EV_GW_UP");
156*13101SVenki.Rajagopalan@Sun.COM
157*13101SVenki.Rajagopalan@Sun.COM /*
158*13101SVenki.Rajagopalan@Sun.COM * EoIB nexus has notified us that our gateway is now
159*13101SVenki.Rajagopalan@Sun.COM * reachable. Unless we already think it is reachable,
160*13101SVenki.Rajagopalan@Sun.COM * mark it so in our records and try to resurrect dead
161*13101SVenki.Rajagopalan@Sun.COM * vnics.
162*13101SVenki.Rajagopalan@Sun.COM */
163*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_vnic_lock);
164*13101SVenki.Rajagopalan@Sun.COM if (ss->ei_gw_unreachable == B_FALSE) {
165*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
166*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: gw reachable");
167*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_vnic_lock);
168*13101SVenki.Rajagopalan@Sun.COM
169*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
170*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: End EIB_EV_GW_UP");
171*13101SVenki.Rajagopalan@Sun.COM break;
172*13101SVenki.Rajagopalan@Sun.COM }
173*13101SVenki.Rajagopalan@Sun.COM ss->ei_gw_unreachable = B_FALSE;
174*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_vnic_lock);
175*13101SVenki.Rajagopalan@Sun.COM
176*13101SVenki.Rajagopalan@Sun.COM /*
177*13101SVenki.Rajagopalan@Sun.COM * If we've not even started yet, we have nothing to do.
178*13101SVenki.Rajagopalan@Sun.COM */
179*13101SVenki.Rajagopalan@Sun.COM if ((ss->ei_node_state->ns_nic_state & EIB_NIC_STARTED) == 0) {
180*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
181*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: End EIB_EV_GW_UP");
182*13101SVenki.Rajagopalan@Sun.COM break;
183*13101SVenki.Rajagopalan@Sun.COM }
184*13101SVenki.Rajagopalan@Sun.COM
185*13101SVenki.Rajagopalan@Sun.COM if (eib_mac_hca_portstate(ss, NULL, NULL) != EIB_E_SUCCESS) {
186*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
187*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: "
188*13101SVenki.Rajagopalan@Sun.COM "HCA portstate failed, marking link down");
189*13101SVenki.Rajagopalan@Sun.COM
190*13101SVenki.Rajagopalan@Sun.COM eib_mac_link_down(ss, B_FALSE);
191*13101SVenki.Rajagopalan@Sun.COM } else {
192*13101SVenki.Rajagopalan@Sun.COM uint8_t vn0_mac[ETHERADDRL];
193*13101SVenki.Rajagopalan@Sun.COM
194*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
195*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: "
196*13101SVenki.Rajagopalan@Sun.COM "HCA portstate ok, resurrecting zombies");
197*13101SVenki.Rajagopalan@Sun.COM
198*13101SVenki.Rajagopalan@Sun.COM bcopy(eib_zero_mac, vn0_mac, ETHERADDRL);
199*13101SVenki.Rajagopalan@Sun.COM eib_vnic_resurrect_zombies(ss, vn0_mac);
200*13101SVenki.Rajagopalan@Sun.COM
201*13101SVenki.Rajagopalan@Sun.COM /*
202*13101SVenki.Rajagopalan@Sun.COM * If we've resurrected the zombies because the gateway
203*13101SVenki.Rajagopalan@Sun.COM * went down and came back, it is possible our unicast
204*13101SVenki.Rajagopalan@Sun.COM * mac address changed from what it was earlier. If
205*13101SVenki.Rajagopalan@Sun.COM * so, we need to update our unicast address with the
206*13101SVenki.Rajagopalan@Sun.COM * mac layer before marking the link up.
207*13101SVenki.Rajagopalan@Sun.COM */
208*13101SVenki.Rajagopalan@Sun.COM if (bcmp(vn0_mac, eib_zero_mac, ETHERADDRL) != 0) {
209*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
210*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: updating unicast "
211*13101SVenki.Rajagopalan@Sun.COM "addr to %x:%x:%x:%x:%x:%x", vn0_mac[0],
212*13101SVenki.Rajagopalan@Sun.COM vn0_mac[1], vn0_mac[2], vn0_mac[3],
213*13101SVenki.Rajagopalan@Sun.COM vn0_mac[4], vn0_mac[5]);
214*13101SVenki.Rajagopalan@Sun.COM
215*13101SVenki.Rajagopalan@Sun.COM mac_unicst_update(ss->ei_mac_hdl, vn0_mac);
216*13101SVenki.Rajagopalan@Sun.COM }
217*13101SVenki.Rajagopalan@Sun.COM
218*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
219*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: eib_mac_link_up(B_FALSE)");
220*13101SVenki.Rajagopalan@Sun.COM
221*13101SVenki.Rajagopalan@Sun.COM eib_mac_link_up(ss, B_FALSE);
222*13101SVenki.Rajagopalan@Sun.COM }
223*13101SVenki.Rajagopalan@Sun.COM
224*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
225*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: End EIB_EV_GW_UP");
226*13101SVenki.Rajagopalan@Sun.COM break;
227*13101SVenki.Rajagopalan@Sun.COM
228*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_GW_INFO_UPDATE:
229*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
230*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin EIB_EV_GW_INFO_UPDATE");
231*13101SVenki.Rajagopalan@Sun.COM
232*13101SVenki.Rajagopalan@Sun.COM if (evi->ev_arg) {
233*13101SVenki.Rajagopalan@Sun.COM eib_update_props(ss, (eib_gw_info_t *)(evi->ev_arg));
234*13101SVenki.Rajagopalan@Sun.COM kmem_free(evi->ev_arg, sizeof (eib_gw_info_t));
235*13101SVenki.Rajagopalan@Sun.COM }
236*13101SVenki.Rajagopalan@Sun.COM
237*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
238*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: End EIB_EV_GW_INFO_UPDATE");
239*13101SVenki.Rajagopalan@Sun.COM break;
240*13101SVenki.Rajagopalan@Sun.COM
241*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_MCG_DELETED:
242*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
243*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin-End EIB_EV_MCG_DELETED");
244*13101SVenki.Rajagopalan@Sun.COM break;
245*13101SVenki.Rajagopalan@Sun.COM
246*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_MCG_CREATED:
247*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
248*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin-End EIB_EV_MCG_CREATED");
249*13101SVenki.Rajagopalan@Sun.COM break;
250*13101SVenki.Rajagopalan@Sun.COM
251*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_GW_EPORT_DOWN:
252*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
253*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin-End EIB_EV_GW_EPORT_DOWN");
254*13101SVenki.Rajagopalan@Sun.COM break;
255*13101SVenki.Rajagopalan@Sun.COM
256*13101SVenki.Rajagopalan@Sun.COM case EIB_EV_GW_DOWN:
257*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
258*13101SVenki.Rajagopalan@Sun.COM "eib_events_handler: Begin-End EIB_EV_GW_DOWN");
259*13101SVenki.Rajagopalan@Sun.COM break;
260*13101SVenki.Rajagopalan@Sun.COM }
261*13101SVenki.Rajagopalan@Sun.COM
262*13101SVenki.Rajagopalan@Sun.COM eib_mac_clr_nic_state(ss, EIB_NIC_RESTARTING);
263*13101SVenki.Rajagopalan@Sun.COM
264*13101SVenki.Rajagopalan@Sun.COM kmem_free(evi, sizeof (eib_event_t));
265*13101SVenki.Rajagopalan@Sun.COM goto wait_for_event;
266*13101SVenki.Rajagopalan@Sun.COM
267*13101SVenki.Rajagopalan@Sun.COM /*NOTREACHED*/
268*13101SVenki.Rajagopalan@Sun.COM }
269*13101SVenki.Rajagopalan@Sun.COM
270*13101SVenki.Rajagopalan@Sun.COM void
eib_svc_enqueue_event(eib_t * ss,eib_event_t * evi)271*13101SVenki.Rajagopalan@Sun.COM eib_svc_enqueue_event(eib_t *ss, eib_event_t *evi)
272*13101SVenki.Rajagopalan@Sun.COM {
273*13101SVenki.Rajagopalan@Sun.COM eib_event_t *elem = NULL;
274*13101SVenki.Rajagopalan@Sun.COM eib_event_t *tail = NULL;
275*13101SVenki.Rajagopalan@Sun.COM
276*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_ev_lock);
277*13101SVenki.Rajagopalan@Sun.COM
278*13101SVenki.Rajagopalan@Sun.COM /*
279*13101SVenki.Rajagopalan@Sun.COM * Notice to shutdown has a higher priority than the
280*13101SVenki.Rajagopalan@Sun.COM * rest and goes to the head of the list. Everything
281*13101SVenki.Rajagopalan@Sun.COM * else goes at the end.
282*13101SVenki.Rajagopalan@Sun.COM */
283*13101SVenki.Rajagopalan@Sun.COM if (evi->ev_code == EIB_EV_SHUTDOWN) {
284*13101SVenki.Rajagopalan@Sun.COM evi->ev_next = ss->ei_event;
285*13101SVenki.Rajagopalan@Sun.COM ss->ei_event = evi;
286*13101SVenki.Rajagopalan@Sun.COM } else {
287*13101SVenki.Rajagopalan@Sun.COM for (elem = ss->ei_event; elem; elem = elem->ev_next)
288*13101SVenki.Rajagopalan@Sun.COM tail = elem;
289*13101SVenki.Rajagopalan@Sun.COM
290*13101SVenki.Rajagopalan@Sun.COM if (tail)
291*13101SVenki.Rajagopalan@Sun.COM tail->ev_next = evi;
292*13101SVenki.Rajagopalan@Sun.COM else
293*13101SVenki.Rajagopalan@Sun.COM ss->ei_event = evi;
294*13101SVenki.Rajagopalan@Sun.COM }
295*13101SVenki.Rajagopalan@Sun.COM
296*13101SVenki.Rajagopalan@Sun.COM cv_signal(&ss->ei_ev_cv);
297*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_ev_lock);
298*13101SVenki.Rajagopalan@Sun.COM }
299*13101SVenki.Rajagopalan@Sun.COM
300*13101SVenki.Rajagopalan@Sun.COM /*
301*13101SVenki.Rajagopalan@Sun.COM * Thread to refill channels with rwqes whenever they get low.
302*13101SVenki.Rajagopalan@Sun.COM */
303*13101SVenki.Rajagopalan@Sun.COM void
eib_refill_rwqes(eib_t * ss)304*13101SVenki.Rajagopalan@Sun.COM eib_refill_rwqes(eib_t *ss)
305*13101SVenki.Rajagopalan@Sun.COM {
306*13101SVenki.Rajagopalan@Sun.COM eib_chan_t *chan;
307*13101SVenki.Rajagopalan@Sun.COM kmutex_t ci_lock;
308*13101SVenki.Rajagopalan@Sun.COM callb_cpr_t ci;
309*13101SVenki.Rajagopalan@Sun.COM
310*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ci_lock, NULL, MUTEX_DRIVER, NULL);
311*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_INIT(&ci, &ci_lock, callb_generic_cpr, EIB_RWQES_REFILLER);
312*13101SVenki.Rajagopalan@Sun.COM
313*13101SVenki.Rajagopalan@Sun.COM wait_for_refill_work:
314*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_rxpost_lock);
315*13101SVenki.Rajagopalan@Sun.COM
316*13101SVenki.Rajagopalan@Sun.COM while ((ss->ei_rxpost == NULL) && (ss->ei_rxpost_die == 0)) {
317*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
318*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_BEGIN(&ci);
319*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
320*13101SVenki.Rajagopalan@Sun.COM
321*13101SVenki.Rajagopalan@Sun.COM cv_wait(&ss->ei_rxpost_cv, &ss->ei_rxpost_lock);
322*13101SVenki.Rajagopalan@Sun.COM
323*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
324*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_END(&ci, &ci_lock);
325*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
326*13101SVenki.Rajagopalan@Sun.COM }
327*13101SVenki.Rajagopalan@Sun.COM
328*13101SVenki.Rajagopalan@Sun.COM /*
329*13101SVenki.Rajagopalan@Sun.COM * Discard all requests for refill if we're being asked to die
330*13101SVenki.Rajagopalan@Sun.COM */
331*13101SVenki.Rajagopalan@Sun.COM if (ss->ei_rxpost_die) {
332*13101SVenki.Rajagopalan@Sun.COM ss->ei_rxpost = NULL;
333*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_rxpost_lock);
334*13101SVenki.Rajagopalan@Sun.COM
335*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
336*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_EXIT(&ci);
337*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ci_lock);
338*13101SVenki.Rajagopalan@Sun.COM
339*13101SVenki.Rajagopalan@Sun.COM return;
340*13101SVenki.Rajagopalan@Sun.COM }
341*13101SVenki.Rajagopalan@Sun.COM ASSERT(ss->ei_rxpost != NULL);
342*13101SVenki.Rajagopalan@Sun.COM
343*13101SVenki.Rajagopalan@Sun.COM /*
344*13101SVenki.Rajagopalan@Sun.COM * Take the first element out of the queue
345*13101SVenki.Rajagopalan@Sun.COM */
346*13101SVenki.Rajagopalan@Sun.COM chan = ss->ei_rxpost;
347*13101SVenki.Rajagopalan@Sun.COM ss->ei_rxpost = chan->ch_rxpost_next;
348*13101SVenki.Rajagopalan@Sun.COM chan->ch_rxpost_next = NULL;
349*13101SVenki.Rajagopalan@Sun.COM
350*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_rxpost_lock);
351*13101SVenki.Rajagopalan@Sun.COM
352*13101SVenki.Rajagopalan@Sun.COM /*
353*13101SVenki.Rajagopalan@Sun.COM * Try to post a bunch of recv wqes into this channel. If we
354*13101SVenki.Rajagopalan@Sun.COM * fail, it means that we haven't even been able to post a
355*13101SVenki.Rajagopalan@Sun.COM * single recv wqe. This is alarming, but there's nothing
356*13101SVenki.Rajagopalan@Sun.COM * we can do. We just move on to the next channel needing
357*13101SVenki.Rajagopalan@Sun.COM * our service.
358*13101SVenki.Rajagopalan@Sun.COM */
359*13101SVenki.Rajagopalan@Sun.COM if (eib_chan_post_rx(ss, chan, NULL) != EIB_E_SUCCESS) {
360*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_ERR(ss->ei_instance,
361*13101SVenki.Rajagopalan@Sun.COM "eib_refill_rwqes: eib_chan_post_rx() failed");
362*13101SVenki.Rajagopalan@Sun.COM }
363*13101SVenki.Rajagopalan@Sun.COM
364*13101SVenki.Rajagopalan@Sun.COM /*
365*13101SVenki.Rajagopalan@Sun.COM * Mark it to indicate that the refilling is done
366*13101SVenki.Rajagopalan@Sun.COM */
367*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&chan->ch_rx_lock);
368*13101SVenki.Rajagopalan@Sun.COM chan->ch_rx_refilling = B_FALSE;
369*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&chan->ch_rx_lock);
370*13101SVenki.Rajagopalan@Sun.COM
371*13101SVenki.Rajagopalan@Sun.COM goto wait_for_refill_work;
372*13101SVenki.Rajagopalan@Sun.COM
373*13101SVenki.Rajagopalan@Sun.COM /*NOTREACHED*/
374*13101SVenki.Rajagopalan@Sun.COM }
375*13101SVenki.Rajagopalan@Sun.COM
376*13101SVenki.Rajagopalan@Sun.COM /*
377*13101SVenki.Rajagopalan@Sun.COM * Thread to create or restart vnics when required
378*13101SVenki.Rajagopalan@Sun.COM */
379*13101SVenki.Rajagopalan@Sun.COM void
eib_vnic_creator(eib_t * ss)380*13101SVenki.Rajagopalan@Sun.COM eib_vnic_creator(eib_t *ss)
381*13101SVenki.Rajagopalan@Sun.COM {
382*13101SVenki.Rajagopalan@Sun.COM eib_vnic_req_t *vrq;
383*13101SVenki.Rajagopalan@Sun.COM eib_vnic_req_t *elem;
384*13101SVenki.Rajagopalan@Sun.COM eib_vnic_req_t *nxt;
385*13101SVenki.Rajagopalan@Sun.COM kmutex_t ci_lock;
386*13101SVenki.Rajagopalan@Sun.COM callb_cpr_t ci;
387*13101SVenki.Rajagopalan@Sun.COM uint_t vr_req;
388*13101SVenki.Rajagopalan@Sun.COM uint8_t *vr_mac;
389*13101SVenki.Rajagopalan@Sun.COM int ret;
390*13101SVenki.Rajagopalan@Sun.COM int err;
391*13101SVenki.Rajagopalan@Sun.COM
392*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ci_lock, NULL, MUTEX_DRIVER, NULL);
393*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_INIT(&ci, &ci_lock, callb_generic_cpr, EIB_VNIC_CREATOR);
394*13101SVenki.Rajagopalan@Sun.COM
395*13101SVenki.Rajagopalan@Sun.COM wait_for_vnic_req:
396*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_vnic_req_lock);
397*13101SVenki.Rajagopalan@Sun.COM
398*13101SVenki.Rajagopalan@Sun.COM while ((vrq = ss->ei_vnic_req) == NULL) {
399*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
400*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_BEGIN(&ci);
401*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
402*13101SVenki.Rajagopalan@Sun.COM
403*13101SVenki.Rajagopalan@Sun.COM cv_wait(&ss->ei_vnic_req_cv, &ss->ei_vnic_req_lock);
404*13101SVenki.Rajagopalan@Sun.COM
405*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
406*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_END(&ci, &ci_lock);
407*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
408*13101SVenki.Rajagopalan@Sun.COM }
409*13101SVenki.Rajagopalan@Sun.COM
410*13101SVenki.Rajagopalan@Sun.COM /*
411*13101SVenki.Rajagopalan@Sun.COM * Pull out the first request
412*13101SVenki.Rajagopalan@Sun.COM */
413*13101SVenki.Rajagopalan@Sun.COM ss->ei_vnic_req = vrq->vr_next;
414*13101SVenki.Rajagopalan@Sun.COM vrq->vr_next = NULL;
415*13101SVenki.Rajagopalan@Sun.COM
416*13101SVenki.Rajagopalan@Sun.COM vr_req = vrq->vr_req;
417*13101SVenki.Rajagopalan@Sun.COM vr_mac = vrq->vr_mac;
418*13101SVenki.Rajagopalan@Sun.COM
419*13101SVenki.Rajagopalan@Sun.COM switch (vr_req) {
420*13101SVenki.Rajagopalan@Sun.COM case EIB_CR_REQ_DIE:
421*13101SVenki.Rajagopalan@Sun.COM case EIB_CR_REQ_FLUSH:
422*13101SVenki.Rajagopalan@Sun.COM /*
423*13101SVenki.Rajagopalan@Sun.COM * Cleanup all pending reqs and failed reqs
424*13101SVenki.Rajagopalan@Sun.COM */
425*13101SVenki.Rajagopalan@Sun.COM for (elem = ss->ei_vnic_req; elem; elem = nxt) {
426*13101SVenki.Rajagopalan@Sun.COM nxt = elem->vr_next;
427*13101SVenki.Rajagopalan@Sun.COM kmem_free(elem, sizeof (eib_vnic_req_t));
428*13101SVenki.Rajagopalan@Sun.COM }
429*13101SVenki.Rajagopalan@Sun.COM for (elem = ss->ei_failed_vnic_req; elem; elem = nxt) {
430*13101SVenki.Rajagopalan@Sun.COM nxt = elem->vr_next;
431*13101SVenki.Rajagopalan@Sun.COM kmem_free(elem, sizeof (eib_vnic_req_t));
432*13101SVenki.Rajagopalan@Sun.COM }
433*13101SVenki.Rajagopalan@Sun.COM ss->ei_vnic_req = NULL;
434*13101SVenki.Rajagopalan@Sun.COM ss->ei_failed_vnic_req = NULL;
435*13101SVenki.Rajagopalan@Sun.COM ss->ei_pending_vnic_req = NULL;
436*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_vnic_req_lock);
437*13101SVenki.Rajagopalan@Sun.COM
438*13101SVenki.Rajagopalan@Sun.COM break;
439*13101SVenki.Rajagopalan@Sun.COM
440*13101SVenki.Rajagopalan@Sun.COM case EIB_CR_REQ_NEW_VNIC:
441*13101SVenki.Rajagopalan@Sun.COM ss->ei_pending_vnic_req = vrq;
442*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_vnic_req_lock);
443*13101SVenki.Rajagopalan@Sun.COM
444*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance, "eib_vnic_creator: "
445*13101SVenki.Rajagopalan@Sun.COM "new vnic creation request for %x:%x:%x:%x:%x:%x, 0x%x",
446*13101SVenki.Rajagopalan@Sun.COM vr_mac[0], vr_mac[1], vr_mac[2], vr_mac[3], vr_mac[4],
447*13101SVenki.Rajagopalan@Sun.COM vr_mac[5], vrq->vr_vlan);
448*13101SVenki.Rajagopalan@Sun.COM
449*13101SVenki.Rajagopalan@Sun.COM /*
450*13101SVenki.Rajagopalan@Sun.COM * Make sure we don't race with the plumb/unplumb code. If
451*13101SVenki.Rajagopalan@Sun.COM * the eoib instance has been unplumbed already, we ignore any
452*13101SVenki.Rajagopalan@Sun.COM * creation requests that may have been pending.
453*13101SVenki.Rajagopalan@Sun.COM */
454*13101SVenki.Rajagopalan@Sun.COM eib_mac_set_nic_state(ss, EIB_NIC_STARTING);
455*13101SVenki.Rajagopalan@Sun.COM
456*13101SVenki.Rajagopalan@Sun.COM if ((ss->ei_node_state->ns_nic_state & EIB_NIC_STARTED) !=
457*13101SVenki.Rajagopalan@Sun.COM EIB_NIC_STARTED) {
458*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_vnic_req_lock);
459*13101SVenki.Rajagopalan@Sun.COM ss->ei_pending_vnic_req = NULL;
460*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_vnic_req_lock);
461*13101SVenki.Rajagopalan@Sun.COM eib_mac_clr_nic_state(ss, EIB_NIC_STARTING);
462*13101SVenki.Rajagopalan@Sun.COM break;
463*13101SVenki.Rajagopalan@Sun.COM }
464*13101SVenki.Rajagopalan@Sun.COM
465*13101SVenki.Rajagopalan@Sun.COM /*
466*13101SVenki.Rajagopalan@Sun.COM * Try to create a new vnic with the supplied parameters.
467*13101SVenki.Rajagopalan@Sun.COM */
468*13101SVenki.Rajagopalan@Sun.COM err = 0;
469*13101SVenki.Rajagopalan@Sun.COM if ((ret = eib_vnic_create(ss, vrq->vr_mac, vrq->vr_vlan,
470*13101SVenki.Rajagopalan@Sun.COM NULL, &err)) != EIB_E_SUCCESS) {
471*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_WARN(ss->ei_instance, "eib_vnic_creator: "
472*13101SVenki.Rajagopalan@Sun.COM "eib_vnic_create(mac=%x:%x:%x:%x:%x:%x, vlan=0x%x) "
473*13101SVenki.Rajagopalan@Sun.COM "failed, ret=%d", vr_mac[0], vr_mac[1], vr_mac[2],
474*13101SVenki.Rajagopalan@Sun.COM vr_mac[3], vr_mac[4], vr_mac[5], vrq->vr_vlan, err);
475*13101SVenki.Rajagopalan@Sun.COM }
476*13101SVenki.Rajagopalan@Sun.COM
477*13101SVenki.Rajagopalan@Sun.COM /*
478*13101SVenki.Rajagopalan@Sun.COM * If we failed, add this vnic req to our failed list (unless
479*13101SVenki.Rajagopalan@Sun.COM * it already exists there), so we won't try to create this
480*13101SVenki.Rajagopalan@Sun.COM * vnic again. Whether we fail or succeed, we're done with
481*13101SVenki.Rajagopalan@Sun.COM * processing this req, so clear the pending req.
482*13101SVenki.Rajagopalan@Sun.COM */
483*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_vnic_req_lock);
484*13101SVenki.Rajagopalan@Sun.COM if ((ret != EIB_E_SUCCESS) && (err != EEXIST)) {
485*13101SVenki.Rajagopalan@Sun.COM vrq->vr_next = ss->ei_failed_vnic_req;
486*13101SVenki.Rajagopalan@Sun.COM ss->ei_failed_vnic_req = vrq;
487*13101SVenki.Rajagopalan@Sun.COM vrq = NULL;
488*13101SVenki.Rajagopalan@Sun.COM }
489*13101SVenki.Rajagopalan@Sun.COM ss->ei_pending_vnic_req = NULL;
490*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_vnic_req_lock);
491*13101SVenki.Rajagopalan@Sun.COM
492*13101SVenki.Rajagopalan@Sun.COM /*
493*13101SVenki.Rajagopalan@Sun.COM * Notify the mac layer that it should retry its tx again. If we
494*13101SVenki.Rajagopalan@Sun.COM * had created the vnic successfully, we'll be able to send the
495*13101SVenki.Rajagopalan@Sun.COM * packets; if we had not been successful, we'll drop packets on
496*13101SVenki.Rajagopalan@Sun.COM * this vnic.
497*13101SVenki.Rajagopalan@Sun.COM */
498*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance,
499*13101SVenki.Rajagopalan@Sun.COM "eib_vnic_creator: calling mac_tx_update()");
500*13101SVenki.Rajagopalan@Sun.COM mac_tx_update(ss->ei_mac_hdl);
501*13101SVenki.Rajagopalan@Sun.COM
502*13101SVenki.Rajagopalan@Sun.COM eib_mac_clr_nic_state(ss, EIB_NIC_STARTING);
503*13101SVenki.Rajagopalan@Sun.COM break;
504*13101SVenki.Rajagopalan@Sun.COM
505*13101SVenki.Rajagopalan@Sun.COM default:
506*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_DEBUG(ss->ei_instance, "eib_vnic_creator: "
507*13101SVenki.Rajagopalan@Sun.COM "unknown request 0x%lx, ignoring", vrq->vr_req);
508*13101SVenki.Rajagopalan@Sun.COM break;
509*13101SVenki.Rajagopalan@Sun.COM }
510*13101SVenki.Rajagopalan@Sun.COM
511*13101SVenki.Rajagopalan@Sun.COM /*
512*13101SVenki.Rajagopalan@Sun.COM * Free the current req and quit if we have to
513*13101SVenki.Rajagopalan@Sun.COM */
514*13101SVenki.Rajagopalan@Sun.COM if (vrq) {
515*13101SVenki.Rajagopalan@Sun.COM kmem_free(vrq, sizeof (eib_vnic_req_t));
516*13101SVenki.Rajagopalan@Sun.COM }
517*13101SVenki.Rajagopalan@Sun.COM
518*13101SVenki.Rajagopalan@Sun.COM if (vr_req == EIB_CR_REQ_DIE) {
519*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
520*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_EXIT(&ci);
521*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ci_lock);
522*13101SVenki.Rajagopalan@Sun.COM
523*13101SVenki.Rajagopalan@Sun.COM return;
524*13101SVenki.Rajagopalan@Sun.COM }
525*13101SVenki.Rajagopalan@Sun.COM
526*13101SVenki.Rajagopalan@Sun.COM goto wait_for_vnic_req;
527*13101SVenki.Rajagopalan@Sun.COM /*NOTREACHED*/
528*13101SVenki.Rajagopalan@Sun.COM }
529*13101SVenki.Rajagopalan@Sun.COM
530*13101SVenki.Rajagopalan@Sun.COM /*
531*13101SVenki.Rajagopalan@Sun.COM * Thread to monitor tx wqes and update the mac layer when needed.
532*13101SVenki.Rajagopalan@Sun.COM * Note that this thread can only be started after the tx wqe pool
533*13101SVenki.Rajagopalan@Sun.COM * has been allocated and initialized.
534*13101SVenki.Rajagopalan@Sun.COM */
535*13101SVenki.Rajagopalan@Sun.COM void
eib_monitor_tx_wqes(eib_t * ss)536*13101SVenki.Rajagopalan@Sun.COM eib_monitor_tx_wqes(eib_t *ss)
537*13101SVenki.Rajagopalan@Sun.COM {
538*13101SVenki.Rajagopalan@Sun.COM eib_wqe_pool_t *wp = ss->ei_tx;
539*13101SVenki.Rajagopalan@Sun.COM kmutex_t ci_lock;
540*13101SVenki.Rajagopalan@Sun.COM callb_cpr_t ci;
541*13101SVenki.Rajagopalan@Sun.COM
542*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ci_lock, NULL, MUTEX_DRIVER, NULL);
543*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_INIT(&ci, &ci_lock, callb_generic_cpr, EIB_TXWQES_MONITOR);
544*13101SVenki.Rajagopalan@Sun.COM
545*13101SVenki.Rajagopalan@Sun.COM ASSERT(wp != NULL);
546*13101SVenki.Rajagopalan@Sun.COM
547*13101SVenki.Rajagopalan@Sun.COM monitor_wqe_status:
548*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&wp->wp_lock);
549*13101SVenki.Rajagopalan@Sun.COM
550*13101SVenki.Rajagopalan@Sun.COM /*
551*13101SVenki.Rajagopalan@Sun.COM * Wait till someone falls short of wqes
552*13101SVenki.Rajagopalan@Sun.COM */
553*13101SVenki.Rajagopalan@Sun.COM while (wp->wp_status == 0) {
554*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
555*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_BEGIN(&ci);
556*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
557*13101SVenki.Rajagopalan@Sun.COM
558*13101SVenki.Rajagopalan@Sun.COM cv_wait(&wp->wp_cv, &wp->wp_lock);
559*13101SVenki.Rajagopalan@Sun.COM
560*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
561*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_END(&ci, &ci_lock);
562*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
563*13101SVenki.Rajagopalan@Sun.COM }
564*13101SVenki.Rajagopalan@Sun.COM
565*13101SVenki.Rajagopalan@Sun.COM /*
566*13101SVenki.Rajagopalan@Sun.COM * Have we been asked to die ?
567*13101SVenki.Rajagopalan@Sun.COM */
568*13101SVenki.Rajagopalan@Sun.COM if (wp->wp_status & EIB_TXWQE_MONITOR_DIE) {
569*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&wp->wp_lock);
570*13101SVenki.Rajagopalan@Sun.COM
571*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
572*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_EXIT(&ci);
573*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ci_lock);
574*13101SVenki.Rajagopalan@Sun.COM
575*13101SVenki.Rajagopalan@Sun.COM return;
576*13101SVenki.Rajagopalan@Sun.COM }
577*13101SVenki.Rajagopalan@Sun.COM
578*13101SVenki.Rajagopalan@Sun.COM ASSERT((wp->wp_status & EIB_TXWQE_SHORT) != 0);
579*13101SVenki.Rajagopalan@Sun.COM
580*13101SVenki.Rajagopalan@Sun.COM /*
581*13101SVenki.Rajagopalan@Sun.COM * Start monitoring free wqes till they cross min threshold
582*13101SVenki.Rajagopalan@Sun.COM */
583*13101SVenki.Rajagopalan@Sun.COM while ((wp->wp_nfree < EIB_NFREE_SWQES_HWM) &&
584*13101SVenki.Rajagopalan@Sun.COM ((wp->wp_status & EIB_TXWQE_MONITOR_DIE) == 0)) {
585*13101SVenki.Rajagopalan@Sun.COM
586*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
587*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_BEGIN(&ci);
588*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
589*13101SVenki.Rajagopalan@Sun.COM
590*13101SVenki.Rajagopalan@Sun.COM cv_wait(&wp->wp_cv, &wp->wp_lock);
591*13101SVenki.Rajagopalan@Sun.COM
592*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
593*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_END(&ci, &ci_lock);
594*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
595*13101SVenki.Rajagopalan@Sun.COM }
596*13101SVenki.Rajagopalan@Sun.COM
597*13101SVenki.Rajagopalan@Sun.COM /*
598*13101SVenki.Rajagopalan@Sun.COM * Have we been asked to die ?
599*13101SVenki.Rajagopalan@Sun.COM */
600*13101SVenki.Rajagopalan@Sun.COM if (wp->wp_status & EIB_TXWQE_MONITOR_DIE) {
601*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&wp->wp_lock);
602*13101SVenki.Rajagopalan@Sun.COM
603*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
604*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_EXIT(&ci);
605*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ci_lock);
606*13101SVenki.Rajagopalan@Sun.COM
607*13101SVenki.Rajagopalan@Sun.COM return;
608*13101SVenki.Rajagopalan@Sun.COM }
609*13101SVenki.Rajagopalan@Sun.COM
610*13101SVenki.Rajagopalan@Sun.COM ASSERT(wp->wp_nfree >= EIB_NFREE_SWQES_HWM);
611*13101SVenki.Rajagopalan@Sun.COM wp->wp_status &= (~EIB_TXWQE_SHORT);
612*13101SVenki.Rajagopalan@Sun.COM
613*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&wp->wp_lock);
614*13101SVenki.Rajagopalan@Sun.COM
615*13101SVenki.Rajagopalan@Sun.COM /*
616*13101SVenki.Rajagopalan@Sun.COM * Inform the mac layer that tx resources are now available
617*13101SVenki.Rajagopalan@Sun.COM * and go back to monitoring
618*13101SVenki.Rajagopalan@Sun.COM */
619*13101SVenki.Rajagopalan@Sun.COM if (ss->ei_mac_hdl) {
620*13101SVenki.Rajagopalan@Sun.COM mac_tx_update(ss->ei_mac_hdl);
621*13101SVenki.Rajagopalan@Sun.COM }
622*13101SVenki.Rajagopalan@Sun.COM goto monitor_wqe_status;
623*13101SVenki.Rajagopalan@Sun.COM
624*13101SVenki.Rajagopalan@Sun.COM /*NOTREACHED*/
625*13101SVenki.Rajagopalan@Sun.COM }
626*13101SVenki.Rajagopalan@Sun.COM
627*13101SVenki.Rajagopalan@Sun.COM /*
628*13101SVenki.Rajagopalan@Sun.COM * Thread to monitor lso bufs and update the mac layer as needed.
629*13101SVenki.Rajagopalan@Sun.COM * Note that this thread can only be started after the lso buckets
630*13101SVenki.Rajagopalan@Sun.COM * have been allocated and initialized.
631*13101SVenki.Rajagopalan@Sun.COM */
632*13101SVenki.Rajagopalan@Sun.COM void
eib_monitor_lso_bufs(eib_t * ss)633*13101SVenki.Rajagopalan@Sun.COM eib_monitor_lso_bufs(eib_t *ss)
634*13101SVenki.Rajagopalan@Sun.COM {
635*13101SVenki.Rajagopalan@Sun.COM eib_lsobkt_t *bkt = ss->ei_lso;
636*13101SVenki.Rajagopalan@Sun.COM kmutex_t ci_lock;
637*13101SVenki.Rajagopalan@Sun.COM callb_cpr_t ci;
638*13101SVenki.Rajagopalan@Sun.COM
639*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ci_lock, NULL, MUTEX_DRIVER, NULL);
640*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_INIT(&ci, &ci_lock, callb_generic_cpr, EIB_LSOBUFS_MONITOR);
641*13101SVenki.Rajagopalan@Sun.COM
642*13101SVenki.Rajagopalan@Sun.COM ASSERT(bkt != NULL);
643*13101SVenki.Rajagopalan@Sun.COM
644*13101SVenki.Rajagopalan@Sun.COM monitor_lso_status:
645*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&bkt->bk_lock);
646*13101SVenki.Rajagopalan@Sun.COM
647*13101SVenki.Rajagopalan@Sun.COM /*
648*13101SVenki.Rajagopalan@Sun.COM * Wait till someone falls short of LSO buffers or we're asked
649*13101SVenki.Rajagopalan@Sun.COM * to die
650*13101SVenki.Rajagopalan@Sun.COM */
651*13101SVenki.Rajagopalan@Sun.COM while (bkt->bk_status == 0) {
652*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
653*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_BEGIN(&ci);
654*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
655*13101SVenki.Rajagopalan@Sun.COM
656*13101SVenki.Rajagopalan@Sun.COM cv_wait(&bkt->bk_cv, &bkt->bk_lock);
657*13101SVenki.Rajagopalan@Sun.COM
658*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
659*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_END(&ci, &ci_lock);
660*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
661*13101SVenki.Rajagopalan@Sun.COM }
662*13101SVenki.Rajagopalan@Sun.COM
663*13101SVenki.Rajagopalan@Sun.COM if (bkt->bk_status & EIB_LBUF_MONITOR_DIE) {
664*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&bkt->bk_lock);
665*13101SVenki.Rajagopalan@Sun.COM
666*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
667*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_EXIT(&ci);
668*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ci_lock);
669*13101SVenki.Rajagopalan@Sun.COM
670*13101SVenki.Rajagopalan@Sun.COM return;
671*13101SVenki.Rajagopalan@Sun.COM }
672*13101SVenki.Rajagopalan@Sun.COM
673*13101SVenki.Rajagopalan@Sun.COM ASSERT((bkt->bk_status & EIB_LBUF_SHORT) != 0);
674*13101SVenki.Rajagopalan@Sun.COM
675*13101SVenki.Rajagopalan@Sun.COM /*
676*13101SVenki.Rajagopalan@Sun.COM * Start monitoring free LSO buffers till there are enough
677*13101SVenki.Rajagopalan@Sun.COM * free buffers available
678*13101SVenki.Rajagopalan@Sun.COM */
679*13101SVenki.Rajagopalan@Sun.COM while ((bkt->bk_nfree < EIB_LSO_FREE_BUFS_THRESH) &&
680*13101SVenki.Rajagopalan@Sun.COM ((bkt->bk_status & EIB_LBUF_MONITOR_DIE) == 0)) {
681*13101SVenki.Rajagopalan@Sun.COM
682*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
683*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_BEGIN(&ci);
684*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
685*13101SVenki.Rajagopalan@Sun.COM
686*13101SVenki.Rajagopalan@Sun.COM cv_wait(&bkt->bk_cv, &bkt->bk_lock);
687*13101SVenki.Rajagopalan@Sun.COM
688*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
689*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_END(&ci, &ci_lock);
690*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
691*13101SVenki.Rajagopalan@Sun.COM }
692*13101SVenki.Rajagopalan@Sun.COM
693*13101SVenki.Rajagopalan@Sun.COM if (bkt->bk_status & EIB_LBUF_MONITOR_DIE) {
694*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&bkt->bk_lock);
695*13101SVenki.Rajagopalan@Sun.COM
696*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
697*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_EXIT(&ci);
698*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ci_lock);
699*13101SVenki.Rajagopalan@Sun.COM
700*13101SVenki.Rajagopalan@Sun.COM return;
701*13101SVenki.Rajagopalan@Sun.COM }
702*13101SVenki.Rajagopalan@Sun.COM
703*13101SVenki.Rajagopalan@Sun.COM /*
704*13101SVenki.Rajagopalan@Sun.COM * We have enough lso buffers available now
705*13101SVenki.Rajagopalan@Sun.COM */
706*13101SVenki.Rajagopalan@Sun.COM ASSERT(bkt->bk_nfree >= EIB_LSO_FREE_BUFS_THRESH);
707*13101SVenki.Rajagopalan@Sun.COM bkt->bk_status &= (~EIB_LBUF_SHORT);
708*13101SVenki.Rajagopalan@Sun.COM
709*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&bkt->bk_lock);
710*13101SVenki.Rajagopalan@Sun.COM
711*13101SVenki.Rajagopalan@Sun.COM /*
712*13101SVenki.Rajagopalan@Sun.COM * Inform the mac layer that tx lso resources are now available
713*13101SVenki.Rajagopalan@Sun.COM * and go back to monitoring
714*13101SVenki.Rajagopalan@Sun.COM */
715*13101SVenki.Rajagopalan@Sun.COM if (ss->ei_mac_hdl) {
716*13101SVenki.Rajagopalan@Sun.COM mac_tx_update(ss->ei_mac_hdl);
717*13101SVenki.Rajagopalan@Sun.COM }
718*13101SVenki.Rajagopalan@Sun.COM goto monitor_lso_status;
719*13101SVenki.Rajagopalan@Sun.COM
720*13101SVenki.Rajagopalan@Sun.COM /*NOTREACHED*/
721*13101SVenki.Rajagopalan@Sun.COM }
722*13101SVenki.Rajagopalan@Sun.COM
723*13101SVenki.Rajagopalan@Sun.COM /*
724*13101SVenki.Rajagopalan@Sun.COM * Thread to manage the keepalive requirements for vnics and the gateway.
725*13101SVenki.Rajagopalan@Sun.COM */
726*13101SVenki.Rajagopalan@Sun.COM void
eib_manage_keepalives(eib_t * ss)727*13101SVenki.Rajagopalan@Sun.COM eib_manage_keepalives(eib_t *ss)
728*13101SVenki.Rajagopalan@Sun.COM {
729*13101SVenki.Rajagopalan@Sun.COM eib_ka_vnics_t *elem;
730*13101SVenki.Rajagopalan@Sun.COM eib_ka_vnics_t *nxt;
731*13101SVenki.Rajagopalan@Sun.COM clock_t deadline;
732*13101SVenki.Rajagopalan@Sun.COM int64_t lbolt64;
733*13101SVenki.Rajagopalan@Sun.COM int err;
734*13101SVenki.Rajagopalan@Sun.COM kmutex_t ci_lock;
735*13101SVenki.Rajagopalan@Sun.COM callb_cpr_t ci;
736*13101SVenki.Rajagopalan@Sun.COM
737*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ci_lock, NULL, MUTEX_DRIVER, NULL);
738*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_INIT(&ci, &ci_lock, callb_generic_cpr, EIB_EVENTS_HDLR);
739*13101SVenki.Rajagopalan@Sun.COM
740*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_ka_vnics_lock);
741*13101SVenki.Rajagopalan@Sun.COM
742*13101SVenki.Rajagopalan@Sun.COM periodic_keepalive:
743*13101SVenki.Rajagopalan@Sun.COM deadline = ddi_get_lbolt() + ss->ei_gw_props->pp_vnic_ka_ticks;
744*13101SVenki.Rajagopalan@Sun.COM
745*13101SVenki.Rajagopalan@Sun.COM while ((ss->ei_ka_vnics_event &
746*13101SVenki.Rajagopalan@Sun.COM (EIB_KA_VNICS_DIE | EIB_KA_VNICS_TIMED_OUT)) == 0) {
747*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
748*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_BEGIN(&ci);
749*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
750*13101SVenki.Rajagopalan@Sun.COM
751*13101SVenki.Rajagopalan@Sun.COM if (cv_timedwait(&ss->ei_ka_vnics_cv, &ss->ei_ka_vnics_lock,
752*13101SVenki.Rajagopalan@Sun.COM deadline) == -1) {
753*13101SVenki.Rajagopalan@Sun.COM ss->ei_ka_vnics_event |= EIB_KA_VNICS_TIMED_OUT;
754*13101SVenki.Rajagopalan@Sun.COM }
755*13101SVenki.Rajagopalan@Sun.COM
756*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
757*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_SAFE_END(&ci, &ci_lock);
758*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ci_lock);
759*13101SVenki.Rajagopalan@Sun.COM }
760*13101SVenki.Rajagopalan@Sun.COM
761*13101SVenki.Rajagopalan@Sun.COM if (ss->ei_ka_vnics_event & EIB_KA_VNICS_DIE) {
762*13101SVenki.Rajagopalan@Sun.COM for (elem = ss->ei_ka_vnics; elem; elem = nxt) {
763*13101SVenki.Rajagopalan@Sun.COM nxt = elem->ka_next;
764*13101SVenki.Rajagopalan@Sun.COM kmem_free(elem, sizeof (eib_ka_vnics_t));
765*13101SVenki.Rajagopalan@Sun.COM }
766*13101SVenki.Rajagopalan@Sun.COM ss->ei_ka_vnics = NULL;
767*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_ka_vnics_lock);
768*13101SVenki.Rajagopalan@Sun.COM
769*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ci_lock);
770*13101SVenki.Rajagopalan@Sun.COM CALLB_CPR_EXIT(&ci);
771*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ci_lock);
772*13101SVenki.Rajagopalan@Sun.COM
773*13101SVenki.Rajagopalan@Sun.COM return;
774*13101SVenki.Rajagopalan@Sun.COM }
775*13101SVenki.Rajagopalan@Sun.COM
776*13101SVenki.Rajagopalan@Sun.COM /*
777*13101SVenki.Rajagopalan@Sun.COM * Are there any vnics that need keepalive management ?
778*13101SVenki.Rajagopalan@Sun.COM */
779*13101SVenki.Rajagopalan@Sun.COM ss->ei_ka_vnics_event &= ~EIB_KA_VNICS_TIMED_OUT;
780*13101SVenki.Rajagopalan@Sun.COM if (ss->ei_ka_vnics == NULL)
781*13101SVenki.Rajagopalan@Sun.COM goto periodic_keepalive;
782*13101SVenki.Rajagopalan@Sun.COM
783*13101SVenki.Rajagopalan@Sun.COM /*
784*13101SVenki.Rajagopalan@Sun.COM * Ok, we need to send vnic keepalives to our gateway. But first
785*13101SVenki.Rajagopalan@Sun.COM * check if the gateway heartbeat is good as of this moment. Note
786*13101SVenki.Rajagopalan@Sun.COM * that we need do get the lbolt value after acquiring ei_vnic_lock
787*13101SVenki.Rajagopalan@Sun.COM * to ensure that ei_gw_last_heartbeat does not change before the
788*13101SVenki.Rajagopalan@Sun.COM * comparison (to avoid a negative value in the comparison result
789*13101SVenki.Rajagopalan@Sun.COM * causing us to incorrectly assume that the gateway heartbeat has
790*13101SVenki.Rajagopalan@Sun.COM * stopped).
791*13101SVenki.Rajagopalan@Sun.COM */
792*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_vnic_lock);
793*13101SVenki.Rajagopalan@Sun.COM
794*13101SVenki.Rajagopalan@Sun.COM lbolt64 = ddi_get_lbolt64();
795*13101SVenki.Rajagopalan@Sun.COM
796*13101SVenki.Rajagopalan@Sun.COM if (ss->ei_gw_last_heartbeat != 0) {
797*13101SVenki.Rajagopalan@Sun.COM if ((lbolt64 - ss->ei_gw_last_heartbeat) >
798*13101SVenki.Rajagopalan@Sun.COM ss->ei_gw_props->pp_gw_ka_ticks) {
799*13101SVenki.Rajagopalan@Sun.COM
800*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_WARN(ss->ei_instance,
801*13101SVenki.Rajagopalan@Sun.COM "eib_manage_keepalives: no keepalives from gateway "
802*13101SVenki.Rajagopalan@Sun.COM "0x%x for hca_guid=0x%llx, port=0x%x, "
803*13101SVenki.Rajagopalan@Sun.COM "last_gw_ka=0x%llx", ss->ei_gw_props->pp_gw_portid,
804*13101SVenki.Rajagopalan@Sun.COM ss->ei_props->ep_hca_guid,
805*13101SVenki.Rajagopalan@Sun.COM ss->ei_props->ep_port_num,
806*13101SVenki.Rajagopalan@Sun.COM ss->ei_gw_last_heartbeat);
807*13101SVenki.Rajagopalan@Sun.COM
808*13101SVenki.Rajagopalan@Sun.COM for (elem = ss->ei_ka_vnics; elem; elem = nxt) {
809*13101SVenki.Rajagopalan@Sun.COM nxt = elem->ka_next;
810*13101SVenki.Rajagopalan@Sun.COM ss->ei_zombie_vnics |=
811*13101SVenki.Rajagopalan@Sun.COM ((uint64_t)1 << elem->ka_vnic->vn_instance);
812*13101SVenki.Rajagopalan@Sun.COM kmem_free(elem, sizeof (eib_ka_vnics_t));
813*13101SVenki.Rajagopalan@Sun.COM }
814*13101SVenki.Rajagopalan@Sun.COM ss->ei_ka_vnics = NULL;
815*13101SVenki.Rajagopalan@Sun.COM ss->ei_gw_unreachable = B_TRUE;
816*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_vnic_lock);
817*13101SVenki.Rajagopalan@Sun.COM
818*13101SVenki.Rajagopalan@Sun.COM eib_mac_link_down(ss, B_FALSE);
819*13101SVenki.Rajagopalan@Sun.COM
820*13101SVenki.Rajagopalan@Sun.COM goto periodic_keepalive;
821*13101SVenki.Rajagopalan@Sun.COM }
822*13101SVenki.Rajagopalan@Sun.COM }
823*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_vnic_lock);
824*13101SVenki.Rajagopalan@Sun.COM
825*13101SVenki.Rajagopalan@Sun.COM for (elem = ss->ei_ka_vnics; elem; elem = elem->ka_next)
826*13101SVenki.Rajagopalan@Sun.COM (void) eib_fip_heartbeat(ss, elem->ka_vnic, &err);
827*13101SVenki.Rajagopalan@Sun.COM
828*13101SVenki.Rajagopalan@Sun.COM goto periodic_keepalive;
829*13101SVenki.Rajagopalan@Sun.COM /*NOTREACHED*/
830*13101SVenki.Rajagopalan@Sun.COM }
831*13101SVenki.Rajagopalan@Sun.COM
832*13101SVenki.Rajagopalan@Sun.COM void
eib_stop_events_handler(eib_t * ss)833*13101SVenki.Rajagopalan@Sun.COM eib_stop_events_handler(eib_t *ss)
834*13101SVenki.Rajagopalan@Sun.COM {
835*13101SVenki.Rajagopalan@Sun.COM eib_event_t *evi;
836*13101SVenki.Rajagopalan@Sun.COM
837*13101SVenki.Rajagopalan@Sun.COM evi = kmem_zalloc(sizeof (eib_event_t), KM_SLEEP);
838*13101SVenki.Rajagopalan@Sun.COM evi->ev_code = EIB_EV_SHUTDOWN;
839*13101SVenki.Rajagopalan@Sun.COM evi->ev_arg = NULL;
840*13101SVenki.Rajagopalan@Sun.COM
841*13101SVenki.Rajagopalan@Sun.COM eib_svc_enqueue_event(ss, evi);
842*13101SVenki.Rajagopalan@Sun.COM
843*13101SVenki.Rajagopalan@Sun.COM thread_join(ss->ei_events_handler);
844*13101SVenki.Rajagopalan@Sun.COM }
845*13101SVenki.Rajagopalan@Sun.COM
846*13101SVenki.Rajagopalan@Sun.COM void
eib_stop_refill_rwqes(eib_t * ss)847*13101SVenki.Rajagopalan@Sun.COM eib_stop_refill_rwqes(eib_t *ss)
848*13101SVenki.Rajagopalan@Sun.COM {
849*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_rxpost_lock);
850*13101SVenki.Rajagopalan@Sun.COM
851*13101SVenki.Rajagopalan@Sun.COM ss->ei_rxpost_die = 1;
852*13101SVenki.Rajagopalan@Sun.COM
853*13101SVenki.Rajagopalan@Sun.COM cv_signal(&ss->ei_rxpost_cv);
854*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_rxpost_lock);
855*13101SVenki.Rajagopalan@Sun.COM
856*13101SVenki.Rajagopalan@Sun.COM thread_join(ss->ei_rwqes_refiller);
857*13101SVenki.Rajagopalan@Sun.COM }
858*13101SVenki.Rajagopalan@Sun.COM
859*13101SVenki.Rajagopalan@Sun.COM void
eib_stop_vnic_creator(eib_t * ss)860*13101SVenki.Rajagopalan@Sun.COM eib_stop_vnic_creator(eib_t *ss)
861*13101SVenki.Rajagopalan@Sun.COM {
862*13101SVenki.Rajagopalan@Sun.COM eib_vnic_req_t *vrq;
863*13101SVenki.Rajagopalan@Sun.COM
864*13101SVenki.Rajagopalan@Sun.COM vrq = kmem_zalloc(sizeof (eib_vnic_req_t), KM_SLEEP);
865*13101SVenki.Rajagopalan@Sun.COM vrq->vr_req = EIB_CR_REQ_DIE;
866*13101SVenki.Rajagopalan@Sun.COM vrq->vr_next = NULL;
867*13101SVenki.Rajagopalan@Sun.COM
868*13101SVenki.Rajagopalan@Sun.COM eib_vnic_enqueue_req(ss, vrq);
869*13101SVenki.Rajagopalan@Sun.COM
870*13101SVenki.Rajagopalan@Sun.COM thread_join(ss->ei_vnic_creator);
871*13101SVenki.Rajagopalan@Sun.COM }
872*13101SVenki.Rajagopalan@Sun.COM
873*13101SVenki.Rajagopalan@Sun.COM void
eib_stop_monitor_tx_wqes(eib_t * ss)874*13101SVenki.Rajagopalan@Sun.COM eib_stop_monitor_tx_wqes(eib_t *ss)
875*13101SVenki.Rajagopalan@Sun.COM {
876*13101SVenki.Rajagopalan@Sun.COM eib_wqe_pool_t *wp = ss->ei_tx;
877*13101SVenki.Rajagopalan@Sun.COM
878*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&wp->wp_lock);
879*13101SVenki.Rajagopalan@Sun.COM
880*13101SVenki.Rajagopalan@Sun.COM wp->wp_status |= EIB_TXWQE_MONITOR_DIE;
881*13101SVenki.Rajagopalan@Sun.COM
882*13101SVenki.Rajagopalan@Sun.COM cv_signal(&wp->wp_cv);
883*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&wp->wp_lock);
884*13101SVenki.Rajagopalan@Sun.COM
885*13101SVenki.Rajagopalan@Sun.COM thread_join(ss->ei_txwqe_monitor);
886*13101SVenki.Rajagopalan@Sun.COM }
887*13101SVenki.Rajagopalan@Sun.COM
888*13101SVenki.Rajagopalan@Sun.COM int
eib_stop_monitor_lso_bufs(eib_t * ss,boolean_t force)889*13101SVenki.Rajagopalan@Sun.COM eib_stop_monitor_lso_bufs(eib_t *ss, boolean_t force)
890*13101SVenki.Rajagopalan@Sun.COM {
891*13101SVenki.Rajagopalan@Sun.COM eib_lsobkt_t *bkt = ss->ei_lso;
892*13101SVenki.Rajagopalan@Sun.COM
893*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&bkt->bk_lock);
894*13101SVenki.Rajagopalan@Sun.COM
895*13101SVenki.Rajagopalan@Sun.COM /*
896*13101SVenki.Rajagopalan@Sun.COM * If there are some buffers still not reaped and the force
897*13101SVenki.Rajagopalan@Sun.COM * flag is not set, return without doing anything. Otherwise,
898*13101SVenki.Rajagopalan@Sun.COM * stop the lso bufs monitor and wait for it to die.
899*13101SVenki.Rajagopalan@Sun.COM */
900*13101SVenki.Rajagopalan@Sun.COM if ((bkt->bk_nelem != bkt->bk_nfree) && (force == B_FALSE)) {
901*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&bkt->bk_lock);
902*13101SVenki.Rajagopalan@Sun.COM return (EIB_E_FAILURE);
903*13101SVenki.Rajagopalan@Sun.COM }
904*13101SVenki.Rajagopalan@Sun.COM
905*13101SVenki.Rajagopalan@Sun.COM bkt->bk_status |= EIB_LBUF_MONITOR_DIE;
906*13101SVenki.Rajagopalan@Sun.COM
907*13101SVenki.Rajagopalan@Sun.COM cv_signal(&bkt->bk_cv);
908*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&bkt->bk_lock);
909*13101SVenki.Rajagopalan@Sun.COM
910*13101SVenki.Rajagopalan@Sun.COM thread_join(ss->ei_lsobufs_monitor);
911*13101SVenki.Rajagopalan@Sun.COM return (EIB_E_SUCCESS);
912*13101SVenki.Rajagopalan@Sun.COM }
913*13101SVenki.Rajagopalan@Sun.COM
914*13101SVenki.Rajagopalan@Sun.COM void
eib_stop_manage_keepalives(eib_t * ss)915*13101SVenki.Rajagopalan@Sun.COM eib_stop_manage_keepalives(eib_t *ss)
916*13101SVenki.Rajagopalan@Sun.COM {
917*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->ei_ka_vnics_lock);
918*13101SVenki.Rajagopalan@Sun.COM
919*13101SVenki.Rajagopalan@Sun.COM ss->ei_ka_vnics_event |= EIB_KA_VNICS_DIE;
920*13101SVenki.Rajagopalan@Sun.COM
921*13101SVenki.Rajagopalan@Sun.COM cv_signal(&ss->ei_ka_vnics_cv);
922*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->ei_ka_vnics_lock);
923*13101SVenki.Rajagopalan@Sun.COM
924*13101SVenki.Rajagopalan@Sun.COM thread_join(ss->ei_keepalives_manager);
925*13101SVenki.Rajagopalan@Sun.COM }
926*13101SVenki.Rajagopalan@Sun.COM
927*13101SVenki.Rajagopalan@Sun.COM void
eib_flush_vnic_reqs(eib_t * ss)928*13101SVenki.Rajagopalan@Sun.COM eib_flush_vnic_reqs(eib_t *ss)
929*13101SVenki.Rajagopalan@Sun.COM {
930*13101SVenki.Rajagopalan@Sun.COM eib_vnic_req_t *vrq;
931*13101SVenki.Rajagopalan@Sun.COM
932*13101SVenki.Rajagopalan@Sun.COM vrq = kmem_zalloc(sizeof (eib_vnic_req_t), KM_SLEEP);
933*13101SVenki.Rajagopalan@Sun.COM vrq->vr_req = EIB_CR_REQ_FLUSH;
934*13101SVenki.Rajagopalan@Sun.COM vrq->vr_next = NULL;
935*13101SVenki.Rajagopalan@Sun.COM
936*13101SVenki.Rajagopalan@Sun.COM eib_vnic_enqueue_req(ss, vrq);
937*13101SVenki.Rajagopalan@Sun.COM }
938*13101SVenki.Rajagopalan@Sun.COM
939*13101SVenki.Rajagopalan@Sun.COM /*ARGSUSED*/
940*13101SVenki.Rajagopalan@Sun.COM void
eib_gw_alive_cb(dev_info_t * dip,ddi_eventcookie_t cookie,void * arg,void * impl_data)941*13101SVenki.Rajagopalan@Sun.COM eib_gw_alive_cb(dev_info_t *dip, ddi_eventcookie_t cookie, void *arg,
942*13101SVenki.Rajagopalan@Sun.COM void *impl_data)
943*13101SVenki.Rajagopalan@Sun.COM {
944*13101SVenki.Rajagopalan@Sun.COM eib_t *ss = (eib_t *)arg;
945*13101SVenki.Rajagopalan@Sun.COM eib_event_t *evi;
946*13101SVenki.Rajagopalan@Sun.COM
947*13101SVenki.Rajagopalan@Sun.COM evi = kmem_zalloc(sizeof (eib_event_t), KM_NOSLEEP);
948*13101SVenki.Rajagopalan@Sun.COM if (evi == NULL) {
949*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_WARN(ss->ei_instance, "eib_gw_alive_cb: "
950*13101SVenki.Rajagopalan@Sun.COM "no memory, ignoring this gateway alive event");
951*13101SVenki.Rajagopalan@Sun.COM } else {
952*13101SVenki.Rajagopalan@Sun.COM evi->ev_code = EIB_EV_GW_UP;
953*13101SVenki.Rajagopalan@Sun.COM evi->ev_arg = NULL;
954*13101SVenki.Rajagopalan@Sun.COM eib_svc_enqueue_event(ss, evi);
955*13101SVenki.Rajagopalan@Sun.COM }
956*13101SVenki.Rajagopalan@Sun.COM }
957*13101SVenki.Rajagopalan@Sun.COM
958*13101SVenki.Rajagopalan@Sun.COM /*ARGSUSED*/
959*13101SVenki.Rajagopalan@Sun.COM void
eib_login_ack_cb(dev_info_t * dip,ddi_eventcookie_t cookie,void * arg,void * impl_data)960*13101SVenki.Rajagopalan@Sun.COM eib_login_ack_cb(dev_info_t *dip, ddi_eventcookie_t cookie, void *arg,
961*13101SVenki.Rajagopalan@Sun.COM void *impl_data)
962*13101SVenki.Rajagopalan@Sun.COM {
963*13101SVenki.Rajagopalan@Sun.COM eib_t *ss = (eib_t *)arg;
964*13101SVenki.Rajagopalan@Sun.COM uint8_t *pkt = (uint8_t *)impl_data;
965*13101SVenki.Rajagopalan@Sun.COM eib_login_data_t ld;
966*13101SVenki.Rajagopalan@Sun.COM
967*13101SVenki.Rajagopalan@Sun.COM /*
968*13101SVenki.Rajagopalan@Sun.COM * We have received a login ack message from the gateway via the EoIB
969*13101SVenki.Rajagopalan@Sun.COM * nexus (solicitation qpn). The packet is passed to us raw (unparsed)
970*13101SVenki.Rajagopalan@Sun.COM * and we have to figure out if this is a vnic login ack.
971*13101SVenki.Rajagopalan@Sun.COM */
972*13101SVenki.Rajagopalan@Sun.COM if (eib_fip_parse_login_ack(ss, pkt + EIB_GRH_SZ, &ld) == EIB_E_SUCCESS)
973*13101SVenki.Rajagopalan@Sun.COM eib_vnic_login_ack(ss, &ld);
974*13101SVenki.Rajagopalan@Sun.COM }
975*13101SVenki.Rajagopalan@Sun.COM
976*13101SVenki.Rajagopalan@Sun.COM /*ARGSUSED*/
977*13101SVenki.Rajagopalan@Sun.COM void
eib_gw_info_cb(dev_info_t * dip,ddi_eventcookie_t cookie,void * arg,void * impl_data)978*13101SVenki.Rajagopalan@Sun.COM eib_gw_info_cb(dev_info_t *dip, ddi_eventcookie_t cookie, void *arg,
979*13101SVenki.Rajagopalan@Sun.COM void *impl_data)
980*13101SVenki.Rajagopalan@Sun.COM {
981*13101SVenki.Rajagopalan@Sun.COM eib_t *ss = (eib_t *)arg;
982*13101SVenki.Rajagopalan@Sun.COM eib_event_t *evi;
983*13101SVenki.Rajagopalan@Sun.COM
984*13101SVenki.Rajagopalan@Sun.COM evi = kmem_zalloc(sizeof (eib_event_t), KM_NOSLEEP);
985*13101SVenki.Rajagopalan@Sun.COM if (evi == NULL) {
986*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_WARN(ss->ei_instance, "eib_gw_info_cb: "
987*13101SVenki.Rajagopalan@Sun.COM "no memory, ignoring this gateway props update event");
988*13101SVenki.Rajagopalan@Sun.COM return;
989*13101SVenki.Rajagopalan@Sun.COM }
990*13101SVenki.Rajagopalan@Sun.COM evi->ev_arg = kmem_zalloc(sizeof (eib_gw_info_t), KM_NOSLEEP);
991*13101SVenki.Rajagopalan@Sun.COM if (evi->ev_arg == NULL) {
992*13101SVenki.Rajagopalan@Sun.COM EIB_DPRINTF_WARN(ss->ei_instance, "eib_gw_info_cb: "
993*13101SVenki.Rajagopalan@Sun.COM "no memory, ignoring this gateway props update event");
994*13101SVenki.Rajagopalan@Sun.COM kmem_free(evi, sizeof (eib_event_t));
995*13101SVenki.Rajagopalan@Sun.COM return;
996*13101SVenki.Rajagopalan@Sun.COM }
997*13101SVenki.Rajagopalan@Sun.COM bcopy(impl_data, evi->ev_arg, sizeof (eib_gw_info_t));
998*13101SVenki.Rajagopalan@Sun.COM evi->ev_code = EIB_EV_GW_INFO_UPDATE;
999*13101SVenki.Rajagopalan@Sun.COM
1000*13101SVenki.Rajagopalan@Sun.COM eib_svc_enqueue_event(ss, evi);
1001*13101SVenki.Rajagopalan@Sun.COM }
1002