Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ib/clients/eoib/eib_main.c
+++ new/usr/src/uts/common/io/ib/clients/eoib/eib_main.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * The Ethernet Over Infiniband driver
28 28 */
29 29
30 30 #include <sys/types.h>
31 31 #include <sys/conf.h>
32 32 #include <sys/devops.h>
33 33 #include <sys/kmem.h>
34 34 #include <sys/ksynch.h>
35 35 #include <sys/modctl.h>
36 36 #include <sys/stat.h>
37 37 #include <sys/ddi.h>
38 38 #include <sys/sunddi.h>
39 39
40 40 #include <sys/mac_provider.h>
41 41 #include <sys/mac_ether.h>
42 42
43 43 #include <sys/ib/clients/eoib/eib_impl.h>
44 44
45 45 /*
46 46 * Driver entry point declarations
47 47 */
48 48 static int eib_attach(dev_info_t *, ddi_attach_cmd_t);
49 49 static int eib_detach(dev_info_t *, ddi_detach_cmd_t);
50 50
51 51 /*
52 52 * MAC callbacks
53 53 */
54 54 static int eib_m_stat(void *, uint_t, uint64_t *);
55 55 static int eib_m_start(void *);
56 56 static void eib_m_stop(void *);
57 57 static int eib_m_promisc(void *, boolean_t);
58 58 static int eib_m_multicast(void *, boolean_t, const uint8_t *);
59 59 static int eib_m_unicast(void *, const uint8_t *);
60 60 static mblk_t *eib_m_tx(void *, mblk_t *);
61 61 static boolean_t eib_m_getcapab(void *, mac_capab_t, void *);
62 62 static int eib_m_setprop(void *, const char *, mac_prop_id_t, uint_t,
63 63 const void *);
64 64 static int eib_m_getprop(void *, const char *, mac_prop_id_t, uint_t, void *);
65 65 static void eib_m_propinfo(void *, const char *, mac_prop_id_t,
66 66 mac_prop_info_handle_t);
67 67
68 68 /*
69 69 * Devops definition
70 70 */
71 71 DDI_DEFINE_STREAM_OPS(eib_ops, nulldev, nulldev, eib_attach, eib_detach,
72 72 nodev, NULL, D_MP, NULL, ddi_quiesce_not_needed);
73 73
74 74 /*
75 75 * Module Driver Info
76 76 */
↓ open down ↓ |
76 lines elided |
↑ open up ↑ |
77 77 static struct modldrv eib_modldrv = {
78 78 &mod_driverops, /* Driver module */
79 79 "EoIB Driver", /* Driver name and version */
80 80 &eib_ops, /* Driver ops */
81 81 };
82 82
83 83 /*
84 84 * Module Linkage
85 85 */
86 86 static struct modlinkage eib_modlinkage = {
87 - MODREV_1, (void *)&eib_modldrv, NULL
87 + MODREV_1, { (void *)&eib_modldrv, NULL }
88 88 };
89 89
90 90 /*
91 91 * GLDv3 entry points
92 92 */
93 93 #define EIB_M_CALLBACK_FLAGS \
94 94 (MC_GETCAPAB | MC_SETPROP | MC_GETPROP | MC_PROPINFO)
95 95 static mac_callbacks_t eib_m_callbacks = {
96 96 EIB_M_CALLBACK_FLAGS,
97 97 eib_m_stat,
98 98 eib_m_start,
99 99 eib_m_stop,
100 100 eib_m_promisc,
101 101 eib_m_multicast,
102 102 eib_m_unicast,
103 103 eib_m_tx,
104 104 NULL,
105 105 NULL,
106 106 eib_m_getcapab,
107 107 NULL,
108 108 NULL,
109 109 eib_m_setprop,
110 110 eib_m_getprop,
111 111 eib_m_propinfo
112 112 };
113 113
114 114 /*
115 115 * Async handler callback for ibt events
116 116 */
117 117 static ibt_clnt_modinfo_t eib_clnt_modinfo = {
118 118 IBTI_V_CURR,
119 119 IBT_NETWORK,
120 120 eib_ibt_async_handler,
121 121 NULL,
122 122 EIB_DRV_NAME
123 123 };
124 124
125 125 /*
126 126 * Driver State Pointer
127 127 */
128 128 void *eib_state;
129 129
130 130 /*
131 131 * Declarations private to this file
132 132 */
133 133 static int eib_state_init(eib_t *);
134 134 static int eib_add_event_callbacks(eib_t *);
135 135 static int eib_register_with_mac(eib_t *, dev_info_t *);
136 136 static void eib_rb_attach(eib_t *, uint_t);
137 137 static void eib_rb_state_init(eib_t *);
138 138 static void eib_rb_add_event_callbacks(eib_t *);
139 139 static void eib_rb_register_with_mac(eib_t *);
140 140
141 141 /*
142 142 * Definitions private to this file
143 143 */
144 144 #define EIB_ATTACH_STATE_ALLOCD 0x01
145 145 #define EIB_ATTACH_PROPS_PARSED 0x02
146 146 #define EIB_ATTACH_STATE_INIT_DONE 0x04
147 147 #define EIB_ATTACH_IBT_ATT_DONE 0x08
148 148 #define EIB_ATTACH_EV_CBS_ADDED 0x10
149 149 #define EIB_ATTACH_REGISTER_MAC_DONE 0x20
150 150
151 151 int
152 152 _init()
153 153 {
154 154 int ret;
155 155
156 156 if (ddi_name_to_major(EIB_DRV_NAME) == (major_t)-1)
157 157 return (ENODEV);
158 158
159 159 if ((ret = ddi_soft_state_init(&eib_state, sizeof (eib_t), 0)) != 0)
160 160 return (ret);
161 161
162 162 mac_init_ops(&eib_ops, EIB_DRV_NAME);
163 163 if ((ret = mod_install(&eib_modlinkage)) != 0) {
164 164 mac_fini_ops(&eib_ops);
165 165 ddi_soft_state_fini(&eib_state);
166 166 return (ret);
167 167 }
168 168
169 169 eib_debug_init();
170 170
171 171 return (ret);
172 172 }
173 173
174 174 int
175 175 _info(struct modinfo *modinfop)
176 176 {
177 177 return (mod_info(&eib_modlinkage, modinfop));
178 178 }
179 179
180 180 int
181 181 _fini()
182 182 {
183 183 int ret;
184 184
185 185 if ((ret = mod_remove(&eib_modlinkage)) != 0)
186 186 return (ret);
187 187
188 188 eib_debug_fini();
189 189
190 190 mac_fini_ops(&eib_ops);
191 191 ddi_soft_state_fini(&eib_state);
192 192
193 193 return (ret);
194 194 }
195 195
196 196 static int
197 197 eib_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
198 198 {
199 199 eib_t *ss;
200 200 ibt_status_t ret;
201 201 int instance;
202 202 uint_t progress = 0;
203 203
204 204 if (cmd != DDI_ATTACH)
205 205 return (DDI_FAILURE);
206 206
207 207 /*
208 208 * Allocate softstate for this instance
209 209 */
210 210 instance = ddi_get_instance(dip);
211 211 if (ddi_soft_state_zalloc(eib_state, instance) == DDI_FAILURE)
212 212 goto attach_fail;
213 213
214 214 progress |= EIB_ATTACH_STATE_ALLOCD;
215 215
216 216 ss = ddi_get_soft_state(eib_state, instance);
217 217 ss->ei_dip = dip;
218 218 ss->ei_instance = (uint_t)instance;
219 219
220 220 /*
221 221 * Parse the node properties and get the gateway parameters
222 222 * for this instance
223 223 */
224 224 if (eib_get_props(ss) != EIB_E_SUCCESS) {
225 225 EIB_DPRINTF_ERR(ss->ei_instance,
226 226 "eib_attach: eib_get_props() failed");
227 227 goto attach_fail;
228 228 }
229 229 progress |= EIB_ATTACH_PROPS_PARSED;
230 230
231 231 /*
232 232 * Do per-state initialization
233 233 */
234 234 if (eib_state_init(ss) != EIB_E_SUCCESS) {
235 235 EIB_DPRINTF_ERR(ss->ei_instance,
236 236 "eib_attach: eib_state_init() failed");
237 237 goto attach_fail;
238 238 }
239 239 progress |= EIB_ATTACH_STATE_INIT_DONE;
240 240
241 241 /*
242 242 * Attach to IBTL
243 243 */
244 244 if ((ret = ibt_attach(&eib_clnt_modinfo, ss->ei_dip, ss,
245 245 &ss->ei_ibt_hdl)) != IBT_SUCCESS) {
246 246 EIB_DPRINTF_ERR(ss->ei_instance,
247 247 "eib_attach: ibt_attach() failed, ret=%d", ret);
248 248 goto attach_fail;
249 249 }
250 250 progress |= EIB_ATTACH_IBT_ATT_DONE;
251 251
252 252 /*
253 253 * Register NDI event callbacks with EoIB nexus
254 254 */
255 255 if (eib_add_event_callbacks(ss) != EIB_E_SUCCESS) {
256 256 EIB_DPRINTF_ERR(ss->ei_instance,
257 257 "eib_attach: eib_add_event_callbacks() failed");
258 258 goto attach_fail;
259 259 }
260 260 progress |= EIB_ATTACH_EV_CBS_ADDED;
261 261
262 262 /*
263 263 * Register with mac layer
264 264 */
265 265 if (eib_register_with_mac(ss, dip) != EIB_E_SUCCESS) {
266 266 EIB_DPRINTF_ERR(ss->ei_instance,
267 267 "eib_attach: eib_register_with_mac() failed");
268 268 goto attach_fail;
269 269 }
270 270 progress |= EIB_ATTACH_REGISTER_MAC_DONE;
271 271
272 272 return (DDI_SUCCESS);
273 273
274 274 attach_fail:
275 275 eib_rb_attach(ss, progress);
276 276 return (DDI_FAILURE);
277 277 }
278 278
279 279 static int
280 280 eib_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
281 281 {
282 282 eib_t *ss;
283 283 int instance;
284 284
285 285 if (cmd != DDI_DETACH)
286 286 return (DDI_FAILURE);
287 287
288 288 instance = ddi_get_instance(dip);
289 289 ss = ddi_get_soft_state(eib_state, instance);
290 290
291 291 /*
292 292 * If we had not cleaned up rx buffers (and hca resources) during
293 293 * unplumb because they were stuck with the nw layer at the time,
294 294 * we can try to clean them up now before doing the detach.
295 295 */
296 296 eib_mac_set_nic_state(ss, EIB_NIC_STOPPING);
297 297
298 298 eib_rb_rsrc_setup_bufs(ss, B_FALSE);
299 299 if (ss->ei_tx || ss->ei_rx || ss->ei_lso) {
300 300 EIB_DPRINTF_WARN(ss->ei_instance,
301 301 "eib_detach: buffers still not returned "
302 302 "(tx=0x%llx, rx=0x%llx, lso=0x%llx), could "
303 303 "not detach", ss->ei_tx, ss->ei_rx, ss->ei_lso);
304 304 eib_mac_clr_nic_state(ss, EIB_NIC_STOPPING);
305 305 return (DDI_FAILURE);
306 306 }
307 307 if (ss->ei_hca_hdl) {
308 308 eib_rb_ibt_hca_init(ss, ~0);
309 309 }
310 310 eib_mac_clr_nic_state(ss, EIB_NIC_STOPPING);
311 311
312 312 eib_rb_attach(ss, ~0);
313 313
314 314 return (DDI_SUCCESS);
315 315 }
316 316
317 317 static int
318 318 eib_m_stat(void *arg, uint_t stat, uint64_t *val)
319 319 {
320 320 eib_t *ss = arg;
321 321 eib_stats_t *stats = ss->ei_stats;
322 322
323 323 switch (stat) {
324 324 case MAC_STAT_IFSPEED:
325 325 *val = ss->ei_props->ep_ifspeed;
326 326 break;
327 327
328 328 case MAC_STAT_OBYTES:
329 329 *val = stats->st_obytes;
330 330 break;
331 331
332 332 case MAC_STAT_OPACKETS:
333 333 *val = stats->st_opkts;
334 334 break;
335 335
336 336 case MAC_STAT_BRDCSTXMT:
337 337 *val = stats->st_brdcstxmit;
338 338 break;
339 339
340 340 case MAC_STAT_MULTIXMT:
341 341 *val = stats->st_multixmit;
342 342 break;
343 343
344 344 case MAC_STAT_OERRORS:
345 345 *val = stats->st_oerrors;
346 346 break;
347 347
348 348 case MAC_STAT_NOXMTBUF:
349 349 *val = stats->st_noxmitbuf;
350 350 break;
351 351
352 352 case MAC_STAT_RBYTES:
353 353 *val = stats->st_rbytes;
354 354 break;
355 355
356 356 case MAC_STAT_IPACKETS:
357 357 *val = stats->st_ipkts;
358 358 break;
359 359
360 360 case MAC_STAT_BRDCSTRCV:
361 361 *val = stats->st_brdcstrcv;
362 362 break;
363 363
364 364 case MAC_STAT_MULTIRCV:
365 365 *val = stats->st_multircv;
366 366 break;
367 367
368 368 case MAC_STAT_IERRORS:
369 369 *val = stats->st_ierrors;
370 370 break;
371 371
372 372 case MAC_STAT_NORCVBUF:
373 373 *val = stats->st_norcvbuf;
374 374 break;
375 375
376 376 case ETHER_STAT_LINK_DUPLEX:
377 377 *val = LINK_DUPLEX_FULL;
378 378 break;
379 379
380 380 default:
381 381 return (ENOTSUP);
382 382 }
383 383
384 384 return (0);
385 385 }
386 386
387 387 static int
388 388 eib_m_start(void *arg)
389 389 {
390 390 eib_t *ss = arg;
391 391 int ret = -1;
392 392
393 393 eib_mac_set_nic_state(ss, EIB_NIC_STARTING);
394 394
395 395 if ((ss->ei_node_state->ns_nic_state & EIB_NIC_STARTED) == 0)
396 396 ret = eib_mac_start(ss);
397 397
398 398 if (ret == 0)
399 399 eib_mac_upd_nic_state(ss, EIB_NIC_STARTING, EIB_NIC_STARTED);
400 400 else
401 401 eib_mac_clr_nic_state(ss, EIB_NIC_STARTING);
402 402
403 403 return (ret);
404 404 }
405 405
406 406 static void
407 407 eib_m_stop(void *arg)
408 408 {
409 409 eib_t *ss = arg;
410 410
411 411 eib_mac_set_nic_state(ss, EIB_NIC_STOPPING);
412 412
413 413 if ((ss->ei_node_state->ns_nic_state & EIB_NIC_STARTED) != 0)
414 414 eib_mac_stop(ss);
415 415
416 416 eib_mac_clr_nic_state(ss, EIB_NIC_STARTED|EIB_NIC_STOPPING);
417 417 }
418 418
419 419 static int
420 420 eib_m_promisc(void *arg, boolean_t flag)
421 421 {
422 422 eib_t *ss = arg;
423 423
424 424 if ((ss->ei_node_state->ns_nic_state & EIB_NIC_STARTED) == 0)
425 425 return (0);
426 426
427 427 return (eib_mac_promisc(ss, flag));
428 428 }
429 429
430 430 static int
431 431 eib_m_multicast(void *arg, boolean_t add, const uint8_t *mcast_mac)
432 432 {
433 433 eib_t *ss = arg;
434 434
435 435 if ((ss->ei_node_state->ns_nic_state & EIB_NIC_STARTED) == 0)
436 436 return (0);
437 437
438 438 /*
439 439 * We don't have any knowledge which of the vnics built on top of
440 440 * the physlink is this multicast group relevant for. We'll join
441 441 * it for vnic0 for now.
442 442 *
443 443 * Since the tx routine in EoIB currently piggy backs all multicast
444 444 * traffic over the broadcast channel, and all vnics are joined to
445 445 * the broadcast address when they're created, everyone should receive
446 446 * all multicast traffic anyway.
447 447 *
448 448 * On the rx side, we'll check if the incoming multicast address is
449 449 * either on the vnic's list of mcgs joined to (which will only be the
450 450 * broadcast address) or on vnic0's list of mcgs. If we find a match,
451 451 * we let the packet come through.
452 452 *
453 453 * This isn't perfect, but it's the best we can do given that we don't
454 454 * have any vlan information corresponding to this multicast address.
455 455 *
456 456 * Also, for now we'll use the synchronous multicast joins and
457 457 * leaves instead of the asynchronous mechanism provided by
458 458 * ibt_join_mcg() since that involves additional complexity for failed
459 459 * joins and removals.
460 460 */
461 461 return (eib_mac_multicast(ss, add, (uint8_t *)mcast_mac));
462 462 }
463 463
464 464 static int
465 465 eib_m_unicast(void *arg, const uint8_t *macaddr)
466 466 {
467 467 eib_t *ss = arg;
468 468 eib_vnic_t *vnic;
469 469
470 470 if ((ss->ei_node_state->ns_nic_state & EIB_NIC_STARTED) == 0)
471 471 return (0);
472 472
473 473 mutex_enter(&ss->ei_vnic_lock);
474 474
475 475 vnic = ss->ei_vnic[0];
476 476 if (bcmp(macaddr, vnic->vn_login_data.ld_assigned_mac,
477 477 ETHERADDRL) == 0) {
478 478 mutex_exit(&ss->ei_vnic_lock);
479 479 return (0);
480 480 }
481 481
482 482 mutex_exit(&ss->ei_vnic_lock);
483 483
484 484 return (EINVAL);
485 485 }
486 486
487 487 static mblk_t *
488 488 eib_m_tx(void *arg, mblk_t *mp)
489 489 {
490 490 eib_t *ss = arg;
491 491 mblk_t *next;
492 492
493 493 /*
494 494 * If the nic hasn't been started, drop the message(s)
495 495 */
496 496 if ((ss->ei_node_state->ns_nic_state & EIB_NIC_STARTED) == 0) {
497 497 freemsgchain(mp);
498 498 return (NULL);
499 499 }
500 500
501 501 for (; mp != NULL; mp = next) {
502 502 /*
503 503 * Detach this message from the message chain
504 504 */
505 505 next = mp->b_next;
506 506 mp->b_next = NULL;
507 507
508 508 /*
509 509 * Attempt to send the message; if we fail (likely due
510 510 * to lack of resources), reattach this message to the
511 511 * chain and return the unsent chain back. When we're
512 512 * ready to send again, we'll issue a mac_tx_update().
513 513 */
514 514 if (eib_mac_tx(ss, mp) != EIB_E_SUCCESS) {
515 515 mp->b_next = next;
516 516 break;
517 517 }
518 518 }
519 519
520 520 return (mp);
521 521 }
522 522
523 523 static boolean_t
524 524 eib_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
525 525 {
526 526 eib_t *ss = arg;
527 527 eib_caps_t *caps = ss->ei_caps;
528 528 eib_caps_t s_caps;
529 529 ibt_hca_attr_t hca_attrs;
530 530 ibt_status_t ret;
531 531
532 532 /*
533 533 * If we haven't been plumbed yet, try getting the hca attributes
534 534 * and figure out the capabilities now
535 535 */
536 536 if (caps == NULL) {
537 537 ASSERT(ss->ei_props != NULL);
538 538
539 539 ret = ibt_query_hca_byguid(ss->ei_props->ep_hca_guid,
540 540 &hca_attrs);
541 541 if (ret == IBT_SUCCESS) {
542 542 eib_ibt_record_capab(ss, &hca_attrs, &s_caps);
543 543 caps = &s_caps;
544 544 }
545 545 }
546 546
547 547 if ((caps != NULL) && (cap == MAC_CAPAB_HCKSUM)) {
548 548 uint32_t *tx_flags = cap_data;
549 549
550 550 if (caps->cp_cksum_flags == 0) {
551 551 EIB_DPRINTF_VERBOSE(ss->ei_instance,
552 552 "eib_m_getcapab: hw cksum disabled, cksum_flags=0");
553 553 return (B_FALSE);
554 554 }
555 555
556 556 *tx_flags = caps->cp_cksum_flags;
557 557
558 558 return (B_TRUE);
559 559
560 560 } else if ((caps != NULL) && (cap == MAC_CAPAB_LSO)) {
561 561 mac_capab_lso_t *cap_lso = cap_data;
562 562
563 563 /*
564 564 * If the HCA supports LSO, it will advertise a non-zero
565 565 * "max lso size" parameter. Also, LSO relies on hw
566 566 * checksum being available. Finally, if the HCA
567 567 * doesn't provide the reserved-lkey capability, LSO
568 568 * will adversely affect the performance. So, we'll
569 569 * enable LSO only if we have a non-zero max lso size,
570 570 * support checksum offload and provide reserved lkey.
571 571 */
572 572 if (caps->cp_lso_maxlen == 0 ||
573 573 caps->cp_cksum_flags == 0 ||
574 574 caps->cp_resv_lkey_capab == 0) {
575 575 EIB_DPRINTF_VERBOSE(ss->ei_instance, "eib_m_getcapab: "
576 576 "LSO disabled, lso_maxlen=0x%lx, "
577 577 "cksum_flags=0x%lx, resv_lkey_capab=%d",
578 578 caps->cp_lso_maxlen,
579 579 caps->cp_cksum_flags,
580 580 caps->cp_resv_lkey_capab);
581 581 return (B_FALSE);
582 582 }
583 583
584 584 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
585 585 cap_lso->lso_basic_tcp_ipv4.lso_max = caps->cp_lso_maxlen - 1;
586 586
587 587 return (B_TRUE);
588 588 }
589 589
590 590 return (B_FALSE);
591 591 }
592 592
593 593 /*ARGSUSED*/
594 594 static int
595 595 eib_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
596 596 uint_t pr_valsize, const void *pr_val)
597 597 {
598 598 return (ENOTSUP);
599 599 }
600 600
601 601 static int
602 602 eib_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
603 603 uint_t pr_valsize, void *pr_val)
604 604 {
605 605 eib_t *ss = arg;
606 606 link_duplex_t duplex = LINK_DUPLEX_FULL;
607 607 uint64_t speed = ss->ei_props->ep_ifspeed;
608 608 int err = 0;
609 609
610 610 switch (pr_num) {
611 611 case MAC_PROP_DUPLEX:
612 612 ASSERT(pr_valsize >= sizeof (link_duplex_t));
613 613 bcopy(&duplex, pr_val, sizeof (link_duplex_t));
614 614 break;
615 615
616 616 case MAC_PROP_SPEED:
617 617 ASSERT(pr_valsize >= sizeof (uint64_t));
618 618 bcopy(&speed, pr_val, sizeof (speed));
619 619 break;
620 620
621 621 case MAC_PROP_PRIVATE:
622 622 if (strcmp(pr_name, EIB_DLPROP_GW_EPORT_STATE) == 0) {
623 623 if (ss->ei_gw_eport_state == FIP_EPORT_UP) {
624 624 (void) snprintf(pr_val, pr_valsize,
625 625 "%s", "up");
626 626 } else {
627 627 (void) snprintf(pr_val, pr_valsize,
628 628 "%s", "down");
629 629 }
630 630 } else if (strcmp(pr_name, EIB_DLPROP_HCA_GUID) == 0) {
631 631 (void) snprintf(pr_val, pr_valsize, "%llX",
632 632 (u_longlong_t)ss->ei_props->ep_hca_guid);
633 633
634 634 } else if (strcmp(pr_name, EIB_DLPROP_PORT_GUID) == 0) {
635 635 (void) snprintf(pr_val, pr_valsize, "%llX",
636 636 (u_longlong_t)((ss->ei_props->ep_sgid).gid_guid));
637 637 }
638 638 break;
639 639
640 640 default:
641 641 err = ENOTSUP;
642 642 break;
643 643 }
644 644
645 645 return (err);
646 646 }
647 647
648 648 /*ARGSUSED*/
649 649 static void
650 650 eib_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
651 651 mac_prop_info_handle_t prh)
652 652 {
653 653 switch (pr_num) {
654 654 case MAC_PROP_DUPLEX:
655 655 case MAC_PROP_SPEED:
656 656 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
657 657 break;
658 658
659 659 case MAC_PROP_MTU:
660 660 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
661 661 mac_prop_info_set_range_uint32(prh, ETHERMTU, ETHERMTU);
662 662 break;
663 663
664 664 case MAC_PROP_PRIVATE:
665 665 if (strcmp(pr_name, EIB_DLPROP_GW_EPORT_STATE) == 0) {
666 666 mac_prop_info_set_default_str(prh, "up ");
667 667 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
668 668 } else if (strcmp(pr_name, EIB_DLPROP_HCA_GUID) == 0) {
669 669 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
670 670 } else if (strcmp(pr_name, EIB_DLPROP_PORT_GUID) == 0) {
671 671 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
672 672 }
673 673 break;
674 674 }
675 675 }
676 676
677 677 static int
678 678 eib_state_init(eib_t *ss)
679 679 {
680 680 kthread_t *kt;
681 681
682 682 /*
683 683 * Initialize synchronization primitives
684 684 */
685 685 mutex_init(&ss->ei_vnic_lock, NULL, MUTEX_DRIVER, NULL);
686 686 mutex_init(&ss->ei_av_lock, NULL, MUTEX_DRIVER, NULL);
687 687 mutex_init(&ss->ei_ev_lock, NULL, MUTEX_DRIVER, NULL);
688 688 mutex_init(&ss->ei_rxpost_lock, NULL, MUTEX_DRIVER, NULL);
689 689 mutex_init(&ss->ei_vnic_req_lock, NULL, MUTEX_DRIVER, NULL);
690 690 mutex_init(&ss->ei_ka_vnics_lock, NULL, MUTEX_DRIVER, NULL);
691 691 cv_init(&ss->ei_vnic_cv, NULL, CV_DEFAULT, NULL);
692 692 cv_init(&ss->ei_ev_cv, NULL, CV_DEFAULT, NULL);
693 693 cv_init(&ss->ei_rxpost_cv, NULL, CV_DEFAULT, NULL);
694 694 cv_init(&ss->ei_vnic_req_cv, NULL, CV_DEFAULT, NULL);
695 695 cv_init(&ss->ei_ka_vnics_cv, NULL, CV_DEFAULT, NULL);
696 696
697 697 /*
698 698 * Create a node state structure and initialize
699 699 */
700 700 ss->ei_node_state = kmem_zalloc(sizeof (eib_node_state_t), KM_SLEEP);
701 701 ss->ei_node_state->ns_link_state = LINK_STATE_UNKNOWN;
702 702 mutex_init(&ss->ei_node_state->ns_lock, NULL, MUTEX_DRIVER, NULL);
703 703 cv_init(&ss->ei_node_state->ns_cv, NULL, CV_DEFAULT, NULL);
704 704
705 705 /*
706 706 * Allocate for gathering statistics
707 707 */
708 708 ss->ei_stats = kmem_zalloc(sizeof (eib_stats_t), KM_SLEEP);
709 709
710 710 /*
711 711 * Start up service threads
712 712 */
713 713 kt = thread_create(NULL, 0, eib_events_handler, ss, 0,
714 714 &p0, TS_RUN, minclsyspri);
715 715 ss->ei_events_handler = kt->t_did;
716 716
717 717 kt = thread_create(NULL, 0, eib_refill_rwqes, ss, 0,
718 718 &p0, TS_RUN, minclsyspri);
719 719 ss->ei_rwqes_refiller = kt->t_did;
720 720
721 721 kt = thread_create(NULL, 0, eib_vnic_creator, ss, 0,
722 722 &p0, TS_RUN, minclsyspri);
723 723 ss->ei_vnic_creator = kt->t_did;
724 724
725 725 kt = thread_create(NULL, 0, eib_manage_keepalives, ss, 0,
726 726 &p0, TS_RUN, minclsyspri);
727 727 ss->ei_keepalives_manager = kt->t_did;
728 728
729 729 /*
730 730 * Set default state of gw eport
731 731 */
732 732 ss->ei_gw_eport_state = FIP_EPORT_UP;
733 733
734 734 /*
735 735 * Do static initializations of common structures
736 736 */
737 737 eib_reserved_gid.gid_prefix = 0;
738 738 eib_reserved_gid.gid_guid = 0;
739 739
740 740 return (EIB_E_SUCCESS);
741 741 }
742 742
743 743 static int
744 744 eib_add_event_callbacks(eib_t *ss)
745 745 {
746 746 int ret;
747 747 ddi_eventcookie_t login_ack_evc;
748 748 ddi_eventcookie_t gw_alive_evc;
749 749 ddi_eventcookie_t gw_info_evc;
750 750
751 751 /*
752 752 * Add callback for receiving vnic login acks from the gateway
753 753 */
754 754 if ((ret = ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_LOGIN_ACK,
755 755 &login_ack_evc)) != DDI_SUCCESS) {
756 756 EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
757 757 "ddi_get_eventcookie(LOGIN_ACK) failed, ret=%d", ret);
758 758 return (EIB_E_FAILURE);
759 759 }
760 760 if ((ret = ddi_add_event_handler(ss->ei_dip, login_ack_evc,
761 761 eib_login_ack_cb, ss, &ss->ei_login_ack_cb)) != DDI_SUCCESS) {
762 762 EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
763 763 "ddi_add_event_handler(LOGIN_ACK) failed, ret=%d", ret);
764 764 return (EIB_E_FAILURE);
765 765 }
766 766
767 767 /*
768 768 * Add callback for receiving status on gateway transitioning from
769 769 * not-available to available
770 770 */
771 771 if ((ret = ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_GW_AVAILABLE,
772 772 &gw_alive_evc)) != DDI_SUCCESS) {
773 773 EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
774 774 "ddi_get_eventcookie(GW_AVAILABLE) failed, ret=%d", ret);
775 775 (void) ddi_remove_event_handler(ss->ei_login_ack_cb);
776 776 return (EIB_E_FAILURE);
777 777 }
778 778 if ((ret = ddi_add_event_handler(ss->ei_dip, gw_alive_evc,
779 779 eib_gw_alive_cb, ss, &ss->ei_gw_alive_cb)) != DDI_SUCCESS) {
780 780 EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
781 781 "ddi_add_event_handler(GW_AVAILABLE) failed, ret=%d", ret);
782 782 (void) ddi_remove_event_handler(ss->ei_login_ack_cb);
783 783 return (EIB_E_FAILURE);
784 784 }
785 785
786 786 /*
787 787 * Add callback for receiving gateway info update
788 788 */
789 789 if ((ret = ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_GW_INFO_UPDATE,
790 790 &gw_info_evc)) != DDI_SUCCESS) {
791 791 EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
792 792 "ddi_get_eventcookie(GW_INFO_UPDATE) failed, ret=%d", ret);
793 793 (void) ddi_remove_event_handler(ss->ei_gw_alive_cb);
794 794 (void) ddi_remove_event_handler(ss->ei_login_ack_cb);
795 795 return (EIB_E_FAILURE);
796 796 }
797 797 if ((ret = ddi_add_event_handler(ss->ei_dip, gw_info_evc,
798 798 eib_gw_info_cb, ss, &ss->ei_gw_info_cb)) != DDI_SUCCESS) {
799 799 EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
800 800 "ddi_add_event_handler(GW_INFO) failed, ret=%d", ret);
801 801 (void) ddi_remove_event_handler(ss->ei_gw_alive_cb);
802 802 (void) ddi_remove_event_handler(ss->ei_login_ack_cb);
803 803 return (EIB_E_FAILURE);
804 804 }
805 805
806 806 return (EIB_E_SUCCESS);
807 807 }
808 808
809 809 static int
810 810 eib_register_with_mac(eib_t *ss, dev_info_t *dip)
811 811 {
812 812 mac_register_t *macp;
813 813 int ret;
814 814
815 815 if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
816 816 EIB_DPRINTF_ERR(ss->ei_instance, "eib_register_with_mac: "
817 817 "mac_alloc(MAC_VERSION=%d) failed", MAC_VERSION);
818 818 return (EIB_E_FAILURE);
819 819 }
820 820
821 821 /*
822 822 * Note that when we register with mac during attach, we don't
823 823 * have the mac address yet (we'll get that after we login into
824 824 * the gateway) so we'll simply register a zero macaddr that
825 825 * we'll overwrite later during plumb, in eib_m_start(). Likewise,
826 826 * we'll also update the max-sdu with the correct MTU after we
827 827 * figure it out when we login to the gateway during plumb.
828 828 */
829 829 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
830 830 macp->m_driver = ss;
831 831 macp->m_dip = dip;
832 832 macp->m_src_addr = eib_zero_mac;
833 833 macp->m_callbacks = &eib_m_callbacks;
834 834 macp->m_min_sdu = 0;
835 835 macp->m_max_sdu = ETHERMTU;
836 836 macp->m_margin = VLAN_TAGSZ;
837 837 macp->m_priv_props = eib_pvt_props;
838 838
839 839 ret = mac_register(macp, &ss->ei_mac_hdl);
840 840 mac_free(macp);
841 841
842 842 if (ret != 0) {
843 843 EIB_DPRINTF_ERR(ss->ei_instance, "eib_register_with_mac: "
844 844 "mac_register() failed, ret=%d", ret);
845 845 return (EIB_E_FAILURE);
846 846 }
847 847
848 848 return (EIB_E_SUCCESS);
849 849 }
850 850
851 851 static void
852 852 eib_rb_attach(eib_t *ss, uint_t progress)
853 853 {
854 854 ibt_status_t ret;
855 855 int instance;
856 856
857 857 if (progress & EIB_ATTACH_REGISTER_MAC_DONE)
858 858 eib_rb_register_with_mac(ss);
859 859
860 860 if (progress & EIB_ATTACH_EV_CBS_ADDED)
861 861 eib_rb_add_event_callbacks(ss);
862 862
863 863 if (progress & EIB_ATTACH_IBT_ATT_DONE) {
864 864 ret = ibt_detach(ss->ei_ibt_hdl);
865 865 if (ret != IBT_SUCCESS) {
866 866 EIB_DPRINTF_WARN(ss->ei_instance, "eib_rb_attach: "
867 867 "ibt_detach() failed, ret=%d", ret);
868 868 }
869 869 ss->ei_ibt_hdl = NULL;
870 870 }
871 871
872 872 if (progress & EIB_ATTACH_STATE_INIT_DONE)
873 873 eib_rb_state_init(ss);
874 874
875 875 if (progress & EIB_ATTACH_PROPS_PARSED)
876 876 eib_rb_get_props(ss);
877 877
878 878 if (progress & EIB_ATTACH_STATE_ALLOCD) {
879 879 instance = ddi_get_instance(ss->ei_dip);
880 880 ddi_soft_state_free(eib_state, instance);
881 881 }
882 882 }
883 883
884 884 static void
885 885 eib_rb_state_init(eib_t *ss)
886 886 {
887 887 /*
888 888 * Terminate service threads
889 889 */
890 890 if (ss->ei_keepalives_manager) {
891 891 eib_stop_manage_keepalives(ss);
892 892 ss->ei_keepalives_manager = 0;
893 893 }
894 894 if (ss->ei_vnic_creator) {
895 895 eib_stop_vnic_creator(ss);
896 896 ss->ei_vnic_creator = 0;
897 897 }
898 898 if (ss->ei_rwqes_refiller) {
899 899 eib_stop_refill_rwqes(ss);
900 900 ss->ei_rwqes_refiller = 0;
901 901 }
902 902 if (ss->ei_events_handler) {
903 903 eib_stop_events_handler(ss);
904 904 ss->ei_events_handler = 0;
905 905 }
906 906
907 907 /*
908 908 * Remove space allocated for gathering statistics
909 909 */
910 910 if (ss->ei_stats) {
911 911 kmem_free(ss->ei_stats, sizeof (eib_stats_t));
912 912 ss->ei_stats = NULL;
913 913 }
914 914
915 915 /*
916 916 * Remove space allocated for keeping node state
917 917 */
918 918 if (ss->ei_node_state) {
919 919 cv_destroy(&ss->ei_node_state->ns_cv);
920 920 mutex_destroy(&ss->ei_node_state->ns_lock);
921 921 kmem_free(ss->ei_node_state, sizeof (eib_node_state_t));
922 922 ss->ei_node_state = NULL;
923 923 }
924 924
925 925 /*
926 926 * Finally, destroy all synchronization resources
927 927 */
928 928 cv_destroy(&ss->ei_ka_vnics_cv);
929 929 cv_destroy(&ss->ei_vnic_req_cv);
930 930 cv_destroy(&ss->ei_rxpost_cv);
931 931 cv_destroy(&ss->ei_ev_cv);
932 932 cv_destroy(&ss->ei_vnic_cv);
933 933 mutex_destroy(&ss->ei_ka_vnics_lock);
934 934 mutex_destroy(&ss->ei_vnic_req_lock);
935 935 mutex_destroy(&ss->ei_rxpost_lock);
936 936 mutex_destroy(&ss->ei_ev_lock);
937 937 mutex_destroy(&ss->ei_av_lock);
938 938 mutex_destroy(&ss->ei_vnic_lock);
939 939 }
940 940
941 941 static void
942 942 eib_rb_add_event_callbacks(eib_t *ss)
943 943 {
944 944 ddi_eventcookie_t evc;
945 945
946 946 if (ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_GW_INFO_UPDATE,
947 947 &evc) == DDI_SUCCESS) {
948 948 (void) ddi_remove_event_handler(ss->ei_gw_info_cb);
949 949 ss->ei_gw_info_cb = NULL;
950 950 }
951 951
952 952 if (ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_GW_AVAILABLE,
953 953 &evc) == DDI_SUCCESS) {
954 954 (void) ddi_remove_event_handler(ss->ei_gw_alive_cb);
955 955 ss->ei_gw_alive_cb = NULL;
956 956 }
957 957
958 958 if (ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_LOGIN_ACK,
959 959 &evc) == DDI_SUCCESS) {
960 960 (void) ddi_remove_event_handler(ss->ei_login_ack_cb);
961 961 ss->ei_login_ack_cb = NULL;
962 962 }
963 963 }
964 964
965 965 static void
966 966 eib_rb_register_with_mac(eib_t *ss)
967 967 {
968 968 int ret;
969 969
970 970 if ((ret = mac_unregister(ss->ei_mac_hdl)) != 0) {
971 971 EIB_DPRINTF_WARN(ss->ei_instance,
972 972 "eib_rb_register_with_mac: "
973 973 "mac_unregister() failed, ret=%d", ret);
974 974 }
975 975
976 976 ss->ei_mac_hdl = NULL;
977 977 }
↓ open down ↓ |
880 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX