1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Data-Link Driver 30 */ 31 32 #include <sys/stropts.h> 33 #include <sys/strsun.h> 34 #include <sys/strsubr.h> 35 #include <sys/atomic.h> 36 #include <sys/mkdev.h> 37 #include <sys/vlan.h> 38 #include <sys/dld.h> 39 #include <sys/dld_impl.h> 40 #include <sys/dls_impl.h> 41 #include <inet/common.h> 42 43 static int str_constructor(void *, void *, int); 44 static void str_destructor(void *, void *); 45 static mblk_t *str_unitdata_ind(dld_str_t *, mblk_t *, boolean_t); 46 static void str_notify_promisc_on_phys(dld_str_t *); 47 static void str_notify_promisc_off_phys(dld_str_t *); 48 static void str_notify_phys_addr(dld_str_t *, const uint8_t *); 49 static void str_notify_link_up(dld_str_t *); 50 static void str_notify_link_down(dld_str_t *); 51 static void str_notify_capab_reneg(dld_str_t *); 52 static void str_notify_speed(dld_str_t *, uint32_t); 53 static void str_notify(void *, mac_notify_type_t); 54 55 static void ioc_native(dld_str_t *, mblk_t *); 56 static void ioc_raw(dld_str_t *, mblk_t *); 57 static void ioc_fast(dld_str_t *, mblk_t *); 58 static void ioc(dld_str_t *, mblk_t *); 59 static void dld_ioc(dld_str_t *, mblk_t *); 60 static void str_mdata_raw_put(dld_str_t *, mblk_t *); 61 static mblk_t *i_dld_ether_header_update_tag(mblk_t *, uint_t, uint16_t); 62 static mblk_t *i_dld_ether_header_strip_tag(mblk_t *); 63 64 static uint32_t str_count; 65 static kmem_cache_t *str_cachep; 66 static uint32_t minor_count; 67 static mod_hash_t *str_hashp; 68 69 #define STR_HASHSZ 64 70 #define STR_HASH_KEY(key) ((mod_hash_key_t)(uintptr_t)(key)) 71 72 /* 73 * Some notes on entry points, flow-control, queueing and locking: 74 * 75 * This driver exports the traditional STREAMS put entry point as well as 76 * the non-STREAMS fast-path transmit routine which is provided to IP via 77 * the DL_CAPAB_POLL negotiation. The put procedure handles all control 78 * and data operations, while the fast-path routine deals only with M_DATA 79 * fast-path packets. Regardless of the entry point, all outbound packets 80 * will end up in dld_tx_single(), where they will be delivered to the MAC 81 * driver. 82 * 83 * The transmit logic operates in two modes: a "not busy" mode where the 84 * packets will be delivered to the MAC for a send attempt, or "busy" mode 85 * where they will be enqueued in the internal queue because of flow-control. 86 * Flow-control happens when the MAC driver indicates the packets couldn't 87 * be transmitted due to lack of resources (e.g. running out of descriptors). 88 * In such case, the driver will place a dummy message on its write-side 89 * STREAMS queue so that the queue is marked as "full". Any subsequent 90 * packets arriving at the driver will be enqueued in the internal queue, 91 * which is drained in the context of the service thread that gets scheduled 92 * whenever the driver is in the "busy" mode. When all packets have been 93 * successfully delivered by MAC and the internal queue is empty, it will 94 * transition to the "not busy" mode by removing the dummy message from the 95 * write-side STREAMS queue; in effect this will trigger backenabling. 96 * The sizes of q_hiwat and q_lowat are set to 1 and 0, respectively, due 97 * to the above reasons. 98 * 99 * The driver implements an internal transmit queue independent of STREAMS. 100 * This allows for flexibility and provides a fast enqueue/dequeue mechanism 101 * compared to the putq() and get() STREAMS interfaces. The only putq() and 102 * getq() operations done by the driver are those related to placing and 103 * removing the dummy message to/from the write-side STREAMS queue for flow- 104 * control purposes. 105 * 106 * Locking is done independent of STREAMS due to the driver being fully MT. 107 * Threads entering the driver (either from put or service entry points) 108 * will most likely be readers, with the exception of a few writer cases 109 * such those handling DLPI attach/detach/bind/unbind/etc. or any of the 110 * DLD-related ioctl requests. The DLPI detach case is special, because 111 * it involves freeing resources and therefore must be single-threaded. 112 * Unfortunately the readers/writers lock can't be used to protect against 113 * it, because the lock is dropped prior to the driver calling places where 114 * putnext() may be invoked, and such places may depend on those resources 115 * to exist. Because of this, the driver always completes the DLPI detach 116 * process when there are no other threads running in the driver. This is 117 * done by keeping track of the number of threads, such that the the last 118 * thread leaving the driver will finish the pending DLPI detach operation. 119 */ 120 121 /* 122 * dld_max_q_count is the queue depth threshold used to limit the number of 123 * outstanding packets or bytes allowed in the queue; once this limit is 124 * reached the driver will free any incoming ones until the queue depth 125 * drops below the threshold. 126 * 127 * This buffering is provided to accomodate clients which do not employ 128 * their own buffering scheme, and to handle occasional packet bursts. 129 * Clients which handle their own buffering will receive positive feedback 130 * from this driver as soon as it transitions into the "busy" state, i.e. 131 * when the queue is initially filled up; they will get backenabled once 132 * the queue is empty. 133 * 134 * The value chosen here is rather arbitrary; in future some intelligent 135 * heuristics may be involved which could take into account the hardware's 136 * transmit ring size, etc. 137 */ 138 uint_t dld_max_q_count = (16 * 1024 *1024); 139 140 /* 141 * dld_finddevinfo() returns the dev_info_t * corresponding to a particular 142 * dev_t. It searches str_hashp (a table of dld_str_t's) for streams that 143 * match dev_t. If a stream is found and it is attached, its dev_info_t * 144 * is returned. 145 */ 146 typedef struct i_dld_str_state_s { 147 major_t ds_major; 148 minor_t ds_minor; 149 dev_info_t *ds_dip; 150 } i_dld_str_state_t; 151 152 /* ARGSUSED */ 153 static uint_t 154 i_dld_str_walker(mod_hash_key_t key, mod_hash_val_t *val, void *arg) 155 { 156 i_dld_str_state_t *statep = arg; 157 dld_str_t *dsp = (dld_str_t *)val; 158 159 if (statep->ds_major != dsp->ds_major) 160 return (MH_WALK_CONTINUE); 161 162 ASSERT(statep->ds_minor != 0); 163 164 /* 165 * Access to ds_ppa and ds_mh need to be protected by ds_lock. 166 */ 167 rw_enter(&dsp->ds_lock, RW_READER); 168 if (statep->ds_minor <= DLD_MAX_MINOR) { 169 /* 170 * Style 1: minor can be derived from the ppa. we 171 * continue to walk until we find a matching stream 172 * in attached state. 173 */ 174 if (statep->ds_minor == DLS_PPA2MINOR(dsp->ds_ppa) && 175 dsp->ds_mh != NULL) { 176 statep->ds_dip = mac_devinfo_get(dsp->ds_mh); 177 rw_exit(&dsp->ds_lock); 178 return (MH_WALK_TERMINATE); 179 } 180 } else { 181 /* 182 * Clone: a clone minor is unique. we can terminate the 183 * walk if we find a matching stream -- even if we fail 184 * to obtain the devinfo. 185 */ 186 if (statep->ds_minor == dsp->ds_minor) { 187 if (dsp->ds_mh != NULL) 188 statep->ds_dip = mac_devinfo_get(dsp->ds_mh); 189 rw_exit(&dsp->ds_lock); 190 return (MH_WALK_TERMINATE); 191 } 192 } 193 rw_exit(&dsp->ds_lock); 194 return (MH_WALK_CONTINUE); 195 } 196 197 static dev_info_t * 198 dld_finddevinfo(dev_t dev) 199 { 200 i_dld_str_state_t state; 201 202 state.ds_minor = getminor(dev); 203 state.ds_major = getmajor(dev); 204 state.ds_dip = NULL; 205 206 if (state.ds_minor == 0) 207 return (NULL); 208 209 mod_hash_walk(str_hashp, i_dld_str_walker, &state); 210 if (state.ds_dip != NULL || state.ds_minor <= DLD_MAX_MINOR) 211 return (state.ds_dip); 212 213 /* See if it's a minor node of a VLAN */ 214 return (dls_finddevinfo(dev)); 215 } 216 217 /* 218 * devo_getinfo: getinfo(9e) 219 */ 220 /*ARGSUSED*/ 221 int 222 dld_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resp) 223 { 224 dev_info_t *devinfo; 225 minor_t minor = getminor((dev_t)arg); 226 int rc = DDI_FAILURE; 227 228 switch (cmd) { 229 case DDI_INFO_DEVT2DEVINFO: 230 if ((devinfo = dld_finddevinfo((dev_t)arg)) != NULL) { 231 *(dev_info_t **)resp = devinfo; 232 rc = DDI_SUCCESS; 233 } 234 break; 235 case DDI_INFO_DEVT2INSTANCE: 236 if (minor > 0 && minor <= DLD_MAX_MINOR) { 237 *resp = (void *)(uintptr_t)DLS_MINOR2INST(minor); 238 rc = DDI_SUCCESS; 239 } else if (minor > DLD_MAX_MINOR && 240 (devinfo = dld_finddevinfo((dev_t)arg)) != NULL) { 241 *resp = (void *)(uintptr_t)ddi_get_instance(devinfo); 242 rc = DDI_SUCCESS; 243 } 244 break; 245 } 246 return (rc); 247 } 248 249 /* 250 * qi_qopen: open(9e) 251 */ 252 /*ARGSUSED*/ 253 int 254 dld_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp) 255 { 256 dld_str_t *dsp; 257 major_t major; 258 minor_t minor; 259 int err; 260 261 if (sflag == MODOPEN) 262 return (ENOTSUP); 263 264 /* 265 * This is a cloning driver and therefore each queue should only 266 * ever get opened once. 267 */ 268 if (rq->q_ptr != NULL) 269 return (EBUSY); 270 271 major = getmajor(*devp); 272 minor = getminor(*devp); 273 274 /* 275 * Create a new dld_str_t for the stream. This will grab a new minor 276 * number that will be handed back in the cloned dev_t. Creation may 277 * fail if we can't allocate the dummy mblk used for flow-control. 278 */ 279 dsp = dld_str_create(rq, DLD_DLPI, major, 280 ((minor == 0) ? DL_STYLE2 : DL_STYLE1)); 281 if (dsp == NULL) 282 return (ENOSR); 283 284 ASSERT(dsp->ds_dlstate == DL_UNATTACHED); 285 if (minor != 0) { 286 /* 287 * Style 1 open 288 */ 289 t_uscalar_t ppa; 290 291 if ((err = dls_ppa_from_minor(minor, &ppa)) != 0) 292 goto failed; 293 294 if ((err = dld_str_attach(dsp, ppa)) != 0) 295 goto failed; 296 ASSERT(dsp->ds_dlstate == DL_UNBOUND); 297 } else { 298 (void) qassociate(rq, -1); 299 } 300 301 /* 302 * Enable the queue srv(9e) routine. 303 */ 304 qprocson(rq); 305 306 /* 307 * Construct a cloned dev_t to hand back. 308 */ 309 *devp = makedevice(getmajor(*devp), dsp->ds_minor); 310 return (0); 311 312 failed: 313 dld_str_destroy(dsp); 314 return (err); 315 } 316 317 /* 318 * qi_qclose: close(9e) 319 */ 320 int 321 dld_close(queue_t *rq) 322 { 323 dld_str_t *dsp = rq->q_ptr; 324 325 /* 326 * Wait until pending requests are processed. 327 */ 328 mutex_enter(&dsp->ds_thr_lock); 329 while (dsp->ds_pending_cnt > 0) 330 cv_wait(&dsp->ds_pending_cv, &dsp->ds_thr_lock); 331 mutex_exit(&dsp->ds_thr_lock); 332 333 /* 334 * Disable the queue srv(9e) routine. 335 */ 336 qprocsoff(rq); 337 338 /* 339 * At this point we can not be entered by any threads via STREAMS 340 * or the direct call interface, which is available only to IP. 341 * After the interface is unplumbed, IP wouldn't have any reference 342 * to this instance, and therefore we are now effectively single 343 * threaded and don't require any lock protection. Flush all 344 * pending packets which are sitting in the transmit queue. 345 */ 346 ASSERT(dsp->ds_thr == 0); 347 dld_tx_flush(dsp); 348 349 /* 350 * This stream was open to a provider node. Check to see 351 * if it has been cleanly shut down. 352 */ 353 if (dsp->ds_dlstate != DL_UNATTACHED) { 354 /* 355 * The stream is either open to a style 1 provider or 356 * this is not clean shutdown. Detach from the PPA. 357 * (This is still ok even in the style 1 case). 358 */ 359 dld_str_detach(dsp); 360 } 361 362 dld_str_destroy(dsp); 363 return (0); 364 } 365 366 /* 367 * qi_qputp: put(9e) 368 */ 369 void 370 dld_wput(queue_t *wq, mblk_t *mp) 371 { 372 dld_str_t *dsp = (dld_str_t *)wq->q_ptr; 373 374 DLD_ENTER(dsp); 375 376 switch (DB_TYPE(mp)) { 377 case M_DATA: 378 rw_enter(&dsp->ds_lock, RW_READER); 379 if (dsp->ds_dlstate != DL_IDLE || 380 dsp->ds_mode == DLD_UNITDATA) { 381 freemsg(mp); 382 } else if (dsp->ds_mode == DLD_FASTPATH) { 383 str_mdata_fastpath_put(dsp, mp); 384 } else if (dsp->ds_mode == DLD_RAW) { 385 str_mdata_raw_put(dsp, mp); 386 } 387 rw_exit(&dsp->ds_lock); 388 break; 389 case M_PROTO: 390 case M_PCPROTO: 391 dld_proto(dsp, mp); 392 break; 393 case M_IOCTL: 394 dld_ioc(dsp, mp); 395 break; 396 case M_FLUSH: 397 if (*mp->b_rptr & FLUSHW) { 398 dld_tx_flush(dsp); 399 *mp->b_rptr &= ~FLUSHW; 400 } 401 402 if (*mp->b_rptr & FLUSHR) { 403 qreply(wq, mp); 404 } else { 405 freemsg(mp); 406 } 407 break; 408 default: 409 freemsg(mp); 410 break; 411 } 412 413 DLD_EXIT(dsp); 414 } 415 416 /* 417 * qi_srvp: srv(9e) 418 */ 419 void 420 dld_wsrv(queue_t *wq) 421 { 422 mblk_t *mp; 423 dld_str_t *dsp = wq->q_ptr; 424 425 DLD_ENTER(dsp); 426 rw_enter(&dsp->ds_lock, RW_READER); 427 /* 428 * Grab all packets (chained via b_next) off our transmit queue 429 * and try to send them all to the MAC layer. Since the queue 430 * is independent of streams, we are able to dequeue all messages 431 * at once without looping through getq() and manually chaining 432 * them. Note that the queue size parameters (byte and message 433 * counts) are cleared as well, but we postpone the backenabling 434 * until after the MAC transmit since some packets may end up 435 * back at our transmit queue. 436 */ 437 mutex_enter(&dsp->ds_tx_list_lock); 438 if ((mp = dsp->ds_tx_list_head) == NULL) { 439 ASSERT(!dsp->ds_tx_qbusy); 440 ASSERT(dsp->ds_tx_flow_mp != NULL); 441 ASSERT(dsp->ds_tx_list_head == NULL); 442 ASSERT(dsp->ds_tx_list_tail == NULL); 443 ASSERT(dsp->ds_tx_cnt == 0); 444 ASSERT(dsp->ds_tx_msgcnt == 0); 445 mutex_exit(&dsp->ds_tx_list_lock); 446 rw_exit(&dsp->ds_lock); 447 DLD_EXIT(dsp); 448 return; 449 } 450 dsp->ds_tx_list_head = dsp->ds_tx_list_tail = NULL; 451 dsp->ds_tx_cnt = dsp->ds_tx_msgcnt = 0; 452 mutex_exit(&dsp->ds_tx_list_lock); 453 454 /* 455 * Discard packets unless we are attached and bound; note that 456 * the driver mode (fastpath/raw/unitdata) is irrelevant here, 457 * because regardless of the mode all transmit will end up in 458 * dld_tx_single() where the packets may be queued. 459 */ 460 ASSERT(DB_TYPE(mp) == M_DATA); 461 if (dsp->ds_dlstate != DL_IDLE) { 462 freemsgchain(mp); 463 goto done; 464 } 465 466 /* 467 * Attempt to transmit one or more packets. If the MAC can't 468 * send them all, re-queue the packet(s) at the beginning of 469 * the transmit queue to avoid any re-ordering. 470 */ 471 if ((mp = dls_tx(dsp->ds_dc, mp)) != NULL) 472 dld_tx_enqueue(dsp, mp, B_TRUE); 473 474 done: 475 /* 476 * Grab the list lock again and check if the transmit queue is 477 * really empty; if so, lift up flow-control and backenable any 478 * writer queues. If the queue is not empty, schedule service 479 * thread to drain it. 480 */ 481 mutex_enter(&dsp->ds_tx_list_lock); 482 if (dsp->ds_tx_list_head == NULL) { 483 dsp->ds_tx_flow_mp = getq(wq); 484 ASSERT(dsp->ds_tx_flow_mp != NULL); 485 dsp->ds_tx_qbusy = B_FALSE; 486 } 487 mutex_exit(&dsp->ds_tx_list_lock); 488 489 rw_exit(&dsp->ds_lock); 490 DLD_EXIT(dsp); 491 } 492 493 void 494 dld_init_ops(struct dev_ops *ops, const char *name) 495 { 496 struct streamtab *stream; 497 struct qinit *rq, *wq; 498 struct module_info *modinfo; 499 500 modinfo = kmem_zalloc(sizeof (struct module_info), KM_SLEEP); 501 modinfo->mi_idname = kmem_zalloc(FMNAMESZ, KM_SLEEP); 502 (void) snprintf(modinfo->mi_idname, FMNAMESZ, "%s", name); 503 modinfo->mi_minpsz = 0; 504 modinfo->mi_maxpsz = 64*1024; 505 modinfo->mi_hiwat = 1; 506 modinfo->mi_lowat = 0; 507 508 rq = kmem_zalloc(sizeof (struct qinit), KM_SLEEP); 509 rq->qi_qopen = dld_open; 510 rq->qi_qclose = dld_close; 511 rq->qi_minfo = modinfo; 512 513 wq = kmem_zalloc(sizeof (struct qinit), KM_SLEEP); 514 wq->qi_putp = (pfi_t)dld_wput; 515 wq->qi_srvp = (pfi_t)dld_wsrv; 516 wq->qi_minfo = modinfo; 517 518 stream = kmem_zalloc(sizeof (struct streamtab), KM_SLEEP); 519 stream->st_rdinit = rq; 520 stream->st_wrinit = wq; 521 ops->devo_cb_ops->cb_str = stream; 522 523 ops->devo_getinfo = &dld_getinfo; 524 } 525 526 void 527 dld_fini_ops(struct dev_ops *ops) 528 { 529 struct streamtab *stream; 530 struct qinit *rq, *wq; 531 struct module_info *modinfo; 532 533 stream = ops->devo_cb_ops->cb_str; 534 rq = stream->st_rdinit; 535 wq = stream->st_wrinit; 536 modinfo = rq->qi_minfo; 537 ASSERT(wq->qi_minfo == modinfo); 538 539 kmem_free(stream, sizeof (struct streamtab)); 540 kmem_free(wq, sizeof (struct qinit)); 541 kmem_free(rq, sizeof (struct qinit)); 542 kmem_free(modinfo->mi_idname, FMNAMESZ); 543 kmem_free(modinfo, sizeof (struct module_info)); 544 } 545 546 /* 547 * Initialize this module's data structures. 548 */ 549 void 550 dld_str_init(void) 551 { 552 /* 553 * Create dld_str_t object cache. 554 */ 555 str_cachep = kmem_cache_create("dld_str_cache", sizeof (dld_str_t), 556 0, str_constructor, str_destructor, NULL, NULL, NULL, 0); 557 ASSERT(str_cachep != NULL); 558 559 /* 560 * Create a hash table for maintaining dld_str_t's. 561 * The ds_minor field (the clone minor number) of a dld_str_t 562 * is used as a key for this hash table because this number is 563 * globally unique (allocated from "dls_minor_arena"). 564 */ 565 str_hashp = mod_hash_create_idhash("dld_str_hash", STR_HASHSZ, 566 mod_hash_null_valdtor); 567 } 568 569 /* 570 * Tear down this module's data structures. 571 */ 572 int 573 dld_str_fini(void) 574 { 575 /* 576 * Make sure that there are no objects in use. 577 */ 578 if (str_count != 0) 579 return (EBUSY); 580 581 /* 582 * Check to see if there are any minor numbers still in use. 583 */ 584 if (minor_count != 0) 585 return (EBUSY); 586 587 /* 588 * Destroy object cache. 589 */ 590 kmem_cache_destroy(str_cachep); 591 mod_hash_destroy_idhash(str_hashp); 592 return (0); 593 } 594 595 /* 596 * Create a new dld_str_t object. 597 */ 598 dld_str_t * 599 dld_str_create(queue_t *rq, uint_t type, major_t major, t_uscalar_t style) 600 { 601 dld_str_t *dsp; 602 int err; 603 604 /* 605 * Allocate an object from the cache. 606 */ 607 atomic_add_32(&str_count, 1); 608 dsp = kmem_cache_alloc(str_cachep, KM_SLEEP); 609 610 /* 611 * Allocate the dummy mblk for flow-control. 612 */ 613 dsp->ds_tx_flow_mp = allocb(1, BPRI_HI); 614 if (dsp->ds_tx_flow_mp == NULL) { 615 kmem_cache_free(str_cachep, dsp); 616 atomic_add_32(&str_count, -1); 617 return (NULL); 618 } 619 dsp->ds_type = type; 620 dsp->ds_major = major; 621 dsp->ds_style = style; 622 623 /* 624 * Initialize the queue pointers. 625 */ 626 ASSERT(RD(rq) == rq); 627 dsp->ds_rq = rq; 628 dsp->ds_wq = WR(rq); 629 rq->q_ptr = WR(rq)->q_ptr = (void *)dsp; 630 631 /* 632 * We want explicit control over our write-side STREAMS queue 633 * where the dummy mblk gets added/removed for flow-control. 634 */ 635 noenable(WR(rq)); 636 637 err = mod_hash_insert(str_hashp, STR_HASH_KEY(dsp->ds_minor), 638 (mod_hash_val_t)dsp); 639 ASSERT(err == 0); 640 return (dsp); 641 } 642 643 /* 644 * Destroy a dld_str_t object. 645 */ 646 void 647 dld_str_destroy(dld_str_t *dsp) 648 { 649 queue_t *rq; 650 queue_t *wq; 651 mod_hash_val_t val; 652 /* 653 * Clear the queue pointers. 654 */ 655 rq = dsp->ds_rq; 656 wq = dsp->ds_wq; 657 ASSERT(wq == WR(rq)); 658 659 rq->q_ptr = wq->q_ptr = NULL; 660 dsp->ds_rq = dsp->ds_wq = NULL; 661 662 ASSERT(!RW_LOCK_HELD(&dsp->ds_lock)); 663 ASSERT(MUTEX_NOT_HELD(&dsp->ds_tx_list_lock)); 664 ASSERT(dsp->ds_tx_list_head == NULL); 665 ASSERT(dsp->ds_tx_list_tail == NULL); 666 ASSERT(dsp->ds_tx_cnt == 0); 667 ASSERT(dsp->ds_tx_msgcnt == 0); 668 ASSERT(!dsp->ds_tx_qbusy); 669 670 ASSERT(MUTEX_NOT_HELD(&dsp->ds_thr_lock)); 671 ASSERT(dsp->ds_thr == 0); 672 ASSERT(dsp->ds_pending_req == NULL); 673 674 /* 675 * Reinitialize all the flags. 676 */ 677 dsp->ds_notifications = 0; 678 dsp->ds_passivestate = DLD_UNINITIALIZED; 679 dsp->ds_mode = DLD_UNITDATA; 680 dsp->ds_native = B_FALSE; 681 682 /* 683 * Free the dummy mblk if exists. 684 */ 685 if (dsp->ds_tx_flow_mp != NULL) { 686 freeb(dsp->ds_tx_flow_mp); 687 dsp->ds_tx_flow_mp = NULL; 688 } 689 690 (void) mod_hash_remove(str_hashp, STR_HASH_KEY(dsp->ds_minor), &val); 691 ASSERT(dsp == (dld_str_t *)val); 692 693 /* 694 * Free the object back to the cache. 695 */ 696 kmem_cache_free(str_cachep, dsp); 697 atomic_add_32(&str_count, -1); 698 } 699 700 /* 701 * kmem_cache contructor function: see kmem_cache_create(9f). 702 */ 703 /*ARGSUSED*/ 704 static int 705 str_constructor(void *buf, void *cdrarg, int kmflags) 706 { 707 dld_str_t *dsp = buf; 708 709 bzero(buf, sizeof (dld_str_t)); 710 711 /* 712 * Allocate a new minor number. 713 */ 714 atomic_add_32(&minor_count, 1); 715 if ((dsp->ds_minor = dls_minor_hold(kmflags == KM_SLEEP)) == 0) { 716 atomic_add_32(&minor_count, -1); 717 return (-1); 718 } 719 720 /* 721 * Initialize the DLPI state machine. 722 */ 723 dsp->ds_dlstate = DL_UNATTACHED; 724 dsp->ds_ppa = (t_uscalar_t)-1; 725 726 mutex_init(&dsp->ds_thr_lock, NULL, MUTEX_DRIVER, NULL); 727 rw_init(&dsp->ds_lock, NULL, RW_DRIVER, NULL); 728 mutex_init(&dsp->ds_tx_list_lock, NULL, MUTEX_DRIVER, NULL); 729 cv_init(&dsp->ds_pending_cv, NULL, CV_DRIVER, NULL); 730 731 return (0); 732 } 733 734 /* 735 * kmem_cache destructor function. 736 */ 737 /*ARGSUSED*/ 738 static void 739 str_destructor(void *buf, void *cdrarg) 740 { 741 dld_str_t *dsp = buf; 742 743 /* 744 * Make sure the DLPI state machine was reset. 745 */ 746 ASSERT(dsp->ds_dlstate == DL_UNATTACHED); 747 748 /* 749 * Make sure the data-link interface was closed. 750 */ 751 ASSERT(dsp->ds_mh == NULL); 752 ASSERT(dsp->ds_dc == NULL); 753 754 /* 755 * Make sure enabled notifications are cleared. 756 */ 757 ASSERT(dsp->ds_notifications == 0); 758 759 /* 760 * Make sure polling is disabled. 761 */ 762 ASSERT(!dsp->ds_polling); 763 764 /* 765 * Release the minor number. 766 */ 767 dls_minor_rele(dsp->ds_minor); 768 atomic_add_32(&minor_count, -1); 769 770 ASSERT(!RW_LOCK_HELD(&dsp->ds_lock)); 771 rw_destroy(&dsp->ds_lock); 772 773 ASSERT(MUTEX_NOT_HELD(&dsp->ds_tx_list_lock)); 774 mutex_destroy(&dsp->ds_tx_list_lock); 775 ASSERT(dsp->ds_tx_flow_mp == NULL); 776 777 ASSERT(MUTEX_NOT_HELD(&dsp->ds_thr_lock)); 778 mutex_destroy(&dsp->ds_thr_lock); 779 ASSERT(dsp->ds_pending_req == NULL); 780 ASSERT(dsp->ds_pending_op == NULL); 781 ASSERT(dsp->ds_pending_cnt == 0); 782 cv_destroy(&dsp->ds_pending_cv); 783 } 784 785 /* 786 * M_DATA put. Note that mp is a single message, not a chained message. 787 */ 788 void 789 dld_tx_single(dld_str_t *dsp, mblk_t *mp) 790 { 791 /* 792 * This function can be called from within dld or from an upper 793 * layer protocol (currently only tcp). If we are in the busy 794 * mode enqueue the packet(s) and return. Otherwise hand them 795 * over to the MAC driver for transmission; any remaining one(s) 796 * which didn't get sent will be queued. 797 * 798 * Note here that we don't grab the list lock prior to checking 799 * the busy flag. This is okay, because a missed transition 800 * will not cause any packet reordering for any particular TCP 801 * connection (which is single-threaded). The enqueue routine 802 * will atomically set the busy flag and schedule the service 803 * thread to run; the flag is only cleared by the service thread 804 * when there is no more packet to be transmitted. 805 */ 806 if (dsp->ds_tx_qbusy || (mp = dls_tx(dsp->ds_dc, mp)) != NULL) 807 dld_tx_enqueue(dsp, mp, B_FALSE); 808 } 809 810 /* 811 * Update the priority bits and VID (may need to insert tag if mp points 812 * to an untagged packet. 813 * If vid is VLAN_ID_NONE, use the VID encoded in the packet. 814 */ 815 static mblk_t * 816 i_dld_ether_header_update_tag(mblk_t *mp, uint_t pri, uint16_t vid) 817 { 818 mblk_t *hmp; 819 struct ether_vlan_header *evhp; 820 struct ether_header *ehp; 821 uint16_t old_tci = 0; 822 size_t len; 823 824 ASSERT(pri != 0 || vid != VLAN_ID_NONE); 825 826 evhp = (struct ether_vlan_header *)mp->b_rptr; 827 if (ntohs(evhp->ether_tpid) == ETHERTYPE_VLAN) { 828 /* 829 * Tagged packet, update the priority bits. 830 */ 831 old_tci = ntohs(evhp->ether_tci); 832 len = sizeof (struct ether_vlan_header); 833 834 if ((DB_REF(mp) > 1) || (MBLKL(mp) < len)) { 835 /* 836 * In case some drivers only check the db_ref 837 * count of the first mblk, we pullup the 838 * message into a single mblk. 839 */ 840 hmp = msgpullup(mp, -1); 841 if ((hmp == NULL) || (MBLKL(hmp) < len)) { 842 freemsg(hmp); 843 return (NULL); 844 } else { 845 freemsg(mp); 846 mp = hmp; 847 } 848 } 849 850 evhp = (struct ether_vlan_header *)mp->b_rptr; 851 } else { 852 /* 853 * Untagged packet. Insert the special priority tag. 854 * First allocate a header mblk. 855 */ 856 hmp = allocb(sizeof (struct ether_vlan_header), BPRI_MED); 857 if (hmp == NULL) 858 return (NULL); 859 860 evhp = (struct ether_vlan_header *)hmp->b_rptr; 861 ehp = (struct ether_header *)mp->b_rptr; 862 863 /* 864 * Copy the MAC addresses and typelen 865 */ 866 bcopy(ehp, evhp, (ETHERADDRL * 2)); 867 evhp->ether_type = ehp->ether_type; 868 evhp->ether_tpid = htons(ETHERTYPE_VLAN); 869 870 hmp->b_wptr += sizeof (struct ether_vlan_header); 871 mp->b_rptr += sizeof (struct ether_header); 872 873 /* 874 * Free the original message if it's now empty. Link the 875 * rest of messages to the header message. 876 */ 877 if (MBLKL(mp) == 0) { 878 hmp->b_cont = mp->b_cont; 879 freeb(mp); 880 } else { 881 hmp->b_cont = mp; 882 } 883 mp = hmp; 884 } 885 886 if (pri == 0) 887 pri = VLAN_PRI(old_tci); 888 if (vid == VLAN_ID_NONE) 889 vid = VLAN_ID(old_tci); 890 evhp->ether_tci = htons(VLAN_TCI(pri, VLAN_CFI(old_tci), vid)); 891 return (mp); 892 } 893 894 /* 895 * M_DATA put (IP fast-path mode) 896 */ 897 void 898 str_mdata_fastpath_put(dld_str_t *dsp, mblk_t *mp) 899 { 900 boolean_t is_ethernet = (dsp->ds_mip->mi_media == DL_ETHER); 901 mblk_t *newmp; 902 uint_t pri; 903 904 if (is_ethernet) { 905 /* 906 * Update the priority bits to the assigned priority. 907 */ 908 pri = (VLAN_MBLKPRI(mp) == 0) ? dsp->ds_pri : VLAN_MBLKPRI(mp); 909 910 if (pri != 0) { 911 newmp = i_dld_ether_header_update_tag(mp, pri, 912 VLAN_ID_NONE); 913 if (newmp == NULL) 914 goto discard; 915 mp = newmp; 916 } 917 } 918 919 dld_tx_single(dsp, mp); 920 return; 921 922 discard: 923 /* TODO: bump kstat? */ 924 freemsg(mp); 925 } 926 927 /* 928 * M_DATA put (DLIOCRAW mode) 929 */ 930 static void 931 str_mdata_raw_put(dld_str_t *dsp, mblk_t *mp) 932 { 933 boolean_t is_ethernet = (dsp->ds_mip->mi_media == DL_ETHER); 934 mblk_t *bp, *newmp; 935 size_t size; 936 mac_header_info_t mhi; 937 uint_t pri, vid; 938 939 /* 940 * Certain MAC type plugins provide an illusion for raw DLPI 941 * consumers. They pretend that the MAC layer is something that 942 * it's not for the benefit of observability tools. For example, 943 * mac_wifi pretends that it's Ethernet for such consumers. 944 * Here, unless native mode is enabled, we call into the MAC layer so 945 * that this illusion can be maintained. The plugin will optionally 946 * transform the MAC header here into something that can be passed 947 * down. The header goes from raw mode to "cooked" mode. 948 */ 949 if (!dsp->ds_native) { 950 if ((newmp = mac_header_cook(dsp->ds_mh, mp)) == NULL) 951 goto discard; 952 mp = newmp; 953 } 954 955 size = MBLKL(mp); 956 957 /* 958 * Check the packet is not too big and that any remaining 959 * fragment list is composed entirely of M_DATA messages. (We 960 * know the first fragment was M_DATA otherwise we could not 961 * have got here). 962 */ 963 for (bp = mp->b_cont; bp != NULL; bp = bp->b_cont) { 964 if (DB_TYPE(bp) != M_DATA) 965 goto discard; 966 size += MBLKL(bp); 967 } 968 969 if (dls_header_info(dsp->ds_dc, mp, &mhi) != 0) 970 goto discard; 971 972 /* 973 * If LSO is enabled, check the size against lso_max. Otherwise, 974 * compare the packet size with sdu_max. 975 */ 976 if (size > (dsp->ds_lso ? dsp->ds_lso_max : dsp->ds_mip->mi_sdu_max) 977 + mhi.mhi_hdrsize) 978 goto discard; 979 980 if (is_ethernet) { 981 /* 982 * Discard the packet if this is a VLAN stream but the VID in 983 * the packet is not correct. 984 */ 985 vid = VLAN_ID(mhi.mhi_tci); 986 if ((dsp->ds_vid != VLAN_ID_NONE) && (vid != VLAN_ID_NONE)) 987 goto discard; 988 989 /* 990 * Discard the packet if this packet is a tagged packet 991 * but both pri and VID are 0. 992 */ 993 pri = VLAN_PRI(mhi.mhi_tci); 994 if (mhi.mhi_istagged && (pri == 0) && (vid == VLAN_ID_NONE)) 995 goto discard; 996 997 /* 998 * Update the priority bits to the per-stream priority if 999 * priority is not set in the packet. Update the VID for 1000 * packets on a VLAN stream. 1001 */ 1002 pri = (pri == 0) ? dsp->ds_pri : 0; 1003 if ((pri != 0) || (dsp->ds_vid != VLAN_ID_NONE)) { 1004 if ((newmp = i_dld_ether_header_update_tag(mp, 1005 pri, dsp->ds_vid)) == NULL) { 1006 goto discard; 1007 } 1008 mp = newmp; 1009 } 1010 } 1011 1012 dld_tx_single(dsp, mp); 1013 return; 1014 1015 discard: 1016 /* TODO: bump kstat? */ 1017 freemsg(mp); 1018 } 1019 1020 /* 1021 * Process DL_ATTACH_REQ (style 2) or open(2) (style 1). 1022 */ 1023 int 1024 dld_str_attach(dld_str_t *dsp, t_uscalar_t ppa) 1025 { 1026 int err; 1027 const char *drvname; 1028 char name[MAXNAMELEN]; 1029 dls_channel_t dc; 1030 uint_t addr_length; 1031 1032 ASSERT(dsp->ds_dc == NULL); 1033 1034 if ((drvname = ddi_major_to_name(dsp->ds_major)) == NULL) 1035 return (EINVAL); 1036 1037 (void) snprintf(name, MAXNAMELEN, "%s%u", drvname, ppa); 1038 1039 if (strcmp(drvname, "aggr") != 0 && strcmp(drvname, "vnic") != 0 && 1040 qassociate(dsp->ds_wq, DLS_PPA2INST(ppa)) != 0) 1041 return (EINVAL); 1042 1043 /* 1044 * Open a channel. 1045 */ 1046 if ((err = dls_open(name, &dc)) != 0) { 1047 (void) qassociate(dsp->ds_wq, -1); 1048 return (err); 1049 } 1050 1051 /* 1052 * Cache the MAC interface handle, a pointer to the immutable MAC 1053 * information and the current and 'factory' MAC address. 1054 */ 1055 dsp->ds_mh = dls_mac(dc); 1056 dsp->ds_mip = mac_info(dsp->ds_mh); 1057 1058 mac_unicst_get(dsp->ds_mh, dsp->ds_curr_addr); 1059 1060 addr_length = dsp->ds_mip->mi_addr_length; 1061 bcopy(dsp->ds_mip->mi_unicst_addr, dsp->ds_fact_addr, addr_length); 1062 1063 /* 1064 * Cache the interface VLAN identifier. (This will be VLAN_ID_NONE for 1065 * a non-VLAN interface). 1066 */ 1067 dsp->ds_vid = dls_vid(dc); 1068 1069 /* 1070 * Set the default packet priority. 1071 */ 1072 dsp->ds_pri = 0; 1073 1074 /* 1075 * Add a notify function so that the we get updates from the MAC. 1076 */ 1077 dsp->ds_mnh = mac_notify_add(dsp->ds_mh, str_notify, (void *)dsp); 1078 1079 dsp->ds_ppa = ppa; 1080 dsp->ds_dc = dc; 1081 dsp->ds_dlstate = DL_UNBOUND; 1082 1083 return (0); 1084 } 1085 1086 /* 1087 * Process DL_DETACH_REQ (style 2) or close(2) (style 1). Can also be called 1088 * from close(2) for style 2. 1089 */ 1090 void 1091 dld_str_detach(dld_str_t *dsp) 1092 { 1093 ASSERT(dsp->ds_thr == 0); 1094 1095 /* 1096 * Remove the notify function. 1097 */ 1098 mac_notify_remove(dsp->ds_mh, dsp->ds_mnh); 1099 1100 /* 1101 * Disable the capabilities and clear the promisc flag. 1102 */ 1103 ASSERT(!dsp->ds_polling); 1104 ASSERT(!dsp->ds_soft_ring); 1105 dld_capabilities_disable(dsp); 1106 dsp->ds_promisc = 0; 1107 1108 /* 1109 * Clear LSO flags. 1110 */ 1111 dsp->ds_lso = B_FALSE; 1112 dsp->ds_lso_max = 0; 1113 1114 /* 1115 * Close the channel. 1116 */ 1117 dls_close(dsp->ds_dc); 1118 dsp->ds_ppa = (t_uscalar_t)-1; 1119 dsp->ds_dc = NULL; 1120 dsp->ds_mh = NULL; 1121 1122 (void) qassociate(dsp->ds_wq, -1); 1123 1124 /* 1125 * Re-initialize the DLPI state machine. 1126 */ 1127 dsp->ds_dlstate = DL_UNATTACHED; 1128 1129 } 1130 1131 /* 1132 * This function is only called for VLAN streams. In raw mode, we strip VLAN 1133 * tags before sending packets up to the DLS clients, with the exception of 1134 * special priority tagged packets, in that case, we set the VID to 0. 1135 * mp must be a VLAN tagged packet. 1136 */ 1137 static mblk_t * 1138 i_dld_ether_header_strip_tag(mblk_t *mp) 1139 { 1140 mblk_t *newmp; 1141 struct ether_vlan_header *evhp; 1142 uint16_t tci, new_tci; 1143 1144 ASSERT(MBLKL(mp) >= sizeof (struct ether_vlan_header)); 1145 if (DB_REF(mp) > 1) { 1146 newmp = copymsg(mp); 1147 if (newmp == NULL) 1148 return (NULL); 1149 freemsg(mp); 1150 mp = newmp; 1151 } 1152 evhp = (struct ether_vlan_header *)mp->b_rptr; 1153 1154 tci = ntohs(evhp->ether_tci); 1155 if (VLAN_PRI(tci) == 0) { 1156 /* 1157 * Priority is 0, strip the tag. 1158 */ 1159 ovbcopy(mp->b_rptr, mp->b_rptr + VLAN_TAGSZ, 2 * ETHERADDRL); 1160 mp->b_rptr += VLAN_TAGSZ; 1161 } else { 1162 /* 1163 * Priority is not 0, update the VID to 0. 1164 */ 1165 new_tci = VLAN_TCI(VLAN_PRI(tci), VLAN_CFI(tci), VLAN_ID_NONE); 1166 evhp->ether_tci = htons(new_tci); 1167 } 1168 return (mp); 1169 } 1170 1171 /* 1172 * Raw mode receive function. 1173 */ 1174 /*ARGSUSED*/ 1175 void 1176 dld_str_rx_raw(void *arg, mac_resource_handle_t mrh, mblk_t *mp, 1177 mac_header_info_t *mhip) 1178 { 1179 dld_str_t *dsp = (dld_str_t *)arg; 1180 boolean_t is_ethernet = (dsp->ds_mip->mi_media == DL_ETHER); 1181 mblk_t *next, *newmp; 1182 1183 ASSERT(mp != NULL); 1184 do { 1185 /* 1186 * Get the pointer to the next packet in the chain and then 1187 * clear b_next before the packet gets passed on. 1188 */ 1189 next = mp->b_next; 1190 mp->b_next = NULL; 1191 1192 /* 1193 * Wind back b_rptr to point at the MAC header. 1194 */ 1195 ASSERT(mp->b_rptr >= DB_BASE(mp) + mhip->mhi_hdrsize); 1196 mp->b_rptr -= mhip->mhi_hdrsize; 1197 1198 /* 1199 * Certain MAC type plugins provide an illusion for raw 1200 * DLPI consumers. They pretend that the MAC layer is 1201 * something that it's not for the benefit of observability 1202 * tools. For example, mac_wifi pretends that it's Ethernet 1203 * for such consumers. Here, unless native mode is enabled, 1204 * we call into the MAC layer so that this illusion can be 1205 * maintained. The plugin will optionally transform the MAC 1206 * header here into something that can be passed up to raw 1207 * consumers. The header goes from "cooked" mode to raw mode. 1208 */ 1209 if (!dsp->ds_native) { 1210 newmp = mac_header_uncook(dsp->ds_mh, mp); 1211 if (newmp == NULL) { 1212 freemsg(mp); 1213 goto next; 1214 } 1215 mp = newmp; 1216 } 1217 1218 /* 1219 * Strip the VLAN tag for VLAN streams. 1220 */ 1221 if (is_ethernet && dsp->ds_vid != VLAN_ID_NONE) { 1222 newmp = i_dld_ether_header_strip_tag(mp); 1223 if (newmp == NULL) { 1224 freemsg(mp); 1225 goto next; 1226 } 1227 mp = newmp; 1228 } 1229 1230 /* 1231 * Pass the packet on. 1232 */ 1233 if (canputnext(dsp->ds_rq)) 1234 putnext(dsp->ds_rq, mp); 1235 else 1236 freemsg(mp); 1237 1238 next: 1239 /* 1240 * Move on to the next packet in the chain. 1241 */ 1242 mp = next; 1243 } while (mp != NULL); 1244 } 1245 1246 /* 1247 * Fast-path receive function. 1248 */ 1249 /*ARGSUSED*/ 1250 void 1251 dld_str_rx_fastpath(void *arg, mac_resource_handle_t mrh, mblk_t *mp, 1252 mac_header_info_t *mhip) 1253 { 1254 dld_str_t *dsp = (dld_str_t *)arg; 1255 mblk_t *next; 1256 size_t offset = 0; 1257 1258 /* 1259 * MAC header stripping rules: 1260 * - Tagged packets: 1261 * a. VLAN streams. Strip the whole VLAN header including the tag. 1262 * b. Physical streams 1263 * - VLAN packets (non-zero VID). The stream must be either a 1264 * DL_PROMISC_SAP listener or a ETHERTYPE_VLAN listener. 1265 * Strip the Ethernet header but keep the VLAN header. 1266 * - Special tagged packets (zero VID) 1267 * * The stream is either a DL_PROMISC_SAP listener or a 1268 * ETHERTYPE_VLAN listener, strip the Ethernet header but 1269 * keep the VLAN header. 1270 * * Otherwise, strip the whole VLAN header. 1271 * - Untagged packets. Strip the whole MAC header. 1272 */ 1273 if (mhip->mhi_istagged && (dsp->ds_vid == VLAN_ID_NONE) && 1274 ((dsp->ds_sap == ETHERTYPE_VLAN) || 1275 (dsp->ds_promisc & DLS_PROMISC_SAP))) { 1276 offset = VLAN_TAGSZ; 1277 } 1278 1279 ASSERT(mp != NULL); 1280 do { 1281 /* 1282 * Get the pointer to the next packet in the chain and then 1283 * clear b_next before the packet gets passed on. 1284 */ 1285 next = mp->b_next; 1286 mp->b_next = NULL; 1287 1288 /* 1289 * Wind back b_rptr to point at the VLAN header. 1290 */ 1291 ASSERT(mp->b_rptr >= DB_BASE(mp) + offset); 1292 mp->b_rptr -= offset; 1293 1294 /* 1295 * Pass the packet on. 1296 */ 1297 if (canputnext(dsp->ds_rq)) 1298 putnext(dsp->ds_rq, mp); 1299 else 1300 freemsg(mp); 1301 /* 1302 * Move on to the next packet in the chain. 1303 */ 1304 mp = next; 1305 } while (mp != NULL); 1306 } 1307 1308 /* 1309 * Default receive function (send DL_UNITDATA_IND messages). 1310 */ 1311 /*ARGSUSED*/ 1312 void 1313 dld_str_rx_unitdata(void *arg, mac_resource_handle_t mrh, mblk_t *mp, 1314 mac_header_info_t *mhip) 1315 { 1316 dld_str_t *dsp = (dld_str_t *)arg; 1317 mblk_t *ud_mp; 1318 mblk_t *next; 1319 size_t offset = 0; 1320 boolean_t strip_vlan = B_TRUE; 1321 1322 /* 1323 * See MAC header stripping rules in the dld_str_rx_fastpath() function. 1324 */ 1325 if (mhip->mhi_istagged && (dsp->ds_vid == VLAN_ID_NONE) && 1326 ((dsp->ds_sap == ETHERTYPE_VLAN) || 1327 (dsp->ds_promisc & DLS_PROMISC_SAP))) { 1328 offset = VLAN_TAGSZ; 1329 strip_vlan = B_FALSE; 1330 } 1331 1332 ASSERT(mp != NULL); 1333 do { 1334 /* 1335 * Get the pointer to the next packet in the chain and then 1336 * clear b_next before the packet gets passed on. 1337 */ 1338 next = mp->b_next; 1339 mp->b_next = NULL; 1340 1341 /* 1342 * Wind back b_rptr to point at the MAC header. 1343 */ 1344 ASSERT(mp->b_rptr >= DB_BASE(mp) + mhip->mhi_hdrsize); 1345 mp->b_rptr -= mhip->mhi_hdrsize; 1346 1347 /* 1348 * Create the DL_UNITDATA_IND M_PROTO. 1349 */ 1350 if ((ud_mp = str_unitdata_ind(dsp, mp, strip_vlan)) == NULL) { 1351 freemsgchain(mp); 1352 return; 1353 } 1354 1355 /* 1356 * Advance b_rptr to point at the payload (or the VLAN header). 1357 */ 1358 mp->b_rptr += (mhip->mhi_hdrsize - offset); 1359 1360 /* 1361 * Prepend the DL_UNITDATA_IND. 1362 */ 1363 ud_mp->b_cont = mp; 1364 1365 /* 1366 * Send the message. 1367 */ 1368 if (canputnext(dsp->ds_rq)) 1369 putnext(dsp->ds_rq, ud_mp); 1370 else 1371 freemsg(ud_mp); 1372 1373 /* 1374 * Move on to the next packet in the chain. 1375 */ 1376 mp = next; 1377 } while (mp != NULL); 1378 } 1379 1380 /* 1381 * Generate DL_NOTIFY_IND messages to notify the DLPI consumer of the 1382 * current state of the interface. 1383 */ 1384 void 1385 dld_str_notify_ind(dld_str_t *dsp) 1386 { 1387 mac_notify_type_t type; 1388 1389 for (type = 0; type < MAC_NNOTE; type++) 1390 str_notify(dsp, type); 1391 } 1392 1393 typedef struct dl_unitdata_ind_wrapper { 1394 dl_unitdata_ind_t dl_unitdata; 1395 uint8_t dl_dest_addr[MAXMACADDRLEN + sizeof (uint16_t)]; 1396 uint8_t dl_src_addr[MAXMACADDRLEN + sizeof (uint16_t)]; 1397 } dl_unitdata_ind_wrapper_t; 1398 1399 /* 1400 * Create a DL_UNITDATA_IND M_PROTO message. 1401 */ 1402 static mblk_t * 1403 str_unitdata_ind(dld_str_t *dsp, mblk_t *mp, boolean_t strip_vlan) 1404 { 1405 mblk_t *nmp; 1406 dl_unitdata_ind_wrapper_t *dlwp; 1407 dl_unitdata_ind_t *dlp; 1408 mac_header_info_t mhi; 1409 uint_t addr_length; 1410 uint8_t *daddr; 1411 uint8_t *saddr; 1412 1413 /* 1414 * Get the packet header information. 1415 */ 1416 if (dls_header_info(dsp->ds_dc, mp, &mhi) != 0) 1417 return (NULL); 1418 1419 /* 1420 * Allocate a message large enough to contain the wrapper structure 1421 * defined above. 1422 */ 1423 if ((nmp = mexchange(dsp->ds_wq, NULL, 1424 sizeof (dl_unitdata_ind_wrapper_t), M_PROTO, 1425 DL_UNITDATA_IND)) == NULL) 1426 return (NULL); 1427 1428 dlwp = (dl_unitdata_ind_wrapper_t *)nmp->b_rptr; 1429 1430 dlp = &(dlwp->dl_unitdata); 1431 ASSERT(dlp == (dl_unitdata_ind_t *)nmp->b_rptr); 1432 ASSERT(dlp->dl_primitive == DL_UNITDATA_IND); 1433 1434 /* 1435 * Copy in the destination address. 1436 */ 1437 addr_length = dsp->ds_mip->mi_addr_length; 1438 daddr = dlwp->dl_dest_addr; 1439 dlp->dl_dest_addr_offset = (uintptr_t)daddr - (uintptr_t)dlp; 1440 bcopy(mhi.mhi_daddr, daddr, addr_length); 1441 1442 /* 1443 * Set the destination DLSAP to the SAP value encoded in the packet. 1444 */ 1445 if (mhi.mhi_istagged && !strip_vlan) 1446 *(uint16_t *)(daddr + addr_length) = ETHERTYPE_VLAN; 1447 else 1448 *(uint16_t *)(daddr + addr_length) = mhi.mhi_bindsap; 1449 dlp->dl_dest_addr_length = addr_length + sizeof (uint16_t); 1450 1451 /* 1452 * If the destination address was multicast or broadcast then the 1453 * dl_group_address field should be non-zero. 1454 */ 1455 dlp->dl_group_address = (mhi.mhi_dsttype == MAC_ADDRTYPE_MULTICAST) || 1456 (mhi.mhi_dsttype == MAC_ADDRTYPE_BROADCAST); 1457 1458 /* 1459 * Copy in the source address if one exists. Some MAC types (DL_IB 1460 * for example) may not have access to source information. 1461 */ 1462 if (mhi.mhi_saddr == NULL) { 1463 dlp->dl_src_addr_offset = dlp->dl_src_addr_length = 0; 1464 } else { 1465 saddr = dlwp->dl_src_addr; 1466 dlp->dl_src_addr_offset = (uintptr_t)saddr - (uintptr_t)dlp; 1467 bcopy(mhi.mhi_saddr, saddr, addr_length); 1468 1469 /* 1470 * Set the source DLSAP to the packet ethertype. 1471 */ 1472 *(uint16_t *)(saddr + addr_length) = mhi.mhi_origsap; 1473 dlp->dl_src_addr_length = addr_length + sizeof (uint16_t); 1474 } 1475 1476 return (nmp); 1477 } 1478 1479 /* 1480 * DL_NOTIFY_IND: DL_NOTE_PROMISC_ON_PHYS 1481 */ 1482 static void 1483 str_notify_promisc_on_phys(dld_str_t *dsp) 1484 { 1485 mblk_t *mp; 1486 dl_notify_ind_t *dlip; 1487 1488 if (!(dsp->ds_notifications & DL_NOTE_PROMISC_ON_PHYS)) 1489 return; 1490 1491 if ((mp = mexchange(dsp->ds_wq, NULL, sizeof (dl_notify_ind_t), 1492 M_PROTO, 0)) == NULL) 1493 return; 1494 1495 bzero(mp->b_rptr, sizeof (dl_notify_ind_t)); 1496 dlip = (dl_notify_ind_t *)mp->b_rptr; 1497 dlip->dl_primitive = DL_NOTIFY_IND; 1498 dlip->dl_notification = DL_NOTE_PROMISC_ON_PHYS; 1499 1500 qreply(dsp->ds_wq, mp); 1501 } 1502 1503 /* 1504 * DL_NOTIFY_IND: DL_NOTE_PROMISC_OFF_PHYS 1505 */ 1506 static void 1507 str_notify_promisc_off_phys(dld_str_t *dsp) 1508 { 1509 mblk_t *mp; 1510 dl_notify_ind_t *dlip; 1511 1512 if (!(dsp->ds_notifications & DL_NOTE_PROMISC_OFF_PHYS)) 1513 return; 1514 1515 if ((mp = mexchange(dsp->ds_wq, NULL, sizeof (dl_notify_ind_t), 1516 M_PROTO, 0)) == NULL) 1517 return; 1518 1519 bzero(mp->b_rptr, sizeof (dl_notify_ind_t)); 1520 dlip = (dl_notify_ind_t *)mp->b_rptr; 1521 dlip->dl_primitive = DL_NOTIFY_IND; 1522 dlip->dl_notification = DL_NOTE_PROMISC_OFF_PHYS; 1523 1524 qreply(dsp->ds_wq, mp); 1525 } 1526 1527 /* 1528 * DL_NOTIFY_IND: DL_NOTE_PHYS_ADDR 1529 */ 1530 static void 1531 str_notify_phys_addr(dld_str_t *dsp, const uint8_t *addr) 1532 { 1533 mblk_t *mp; 1534 dl_notify_ind_t *dlip; 1535 uint_t addr_length; 1536 uint16_t ethertype; 1537 1538 if (!(dsp->ds_notifications & DL_NOTE_PHYS_ADDR)) 1539 return; 1540 1541 addr_length = dsp->ds_mip->mi_addr_length; 1542 if ((mp = mexchange(dsp->ds_wq, NULL, 1543 sizeof (dl_notify_ind_t) + addr_length + sizeof (uint16_t), 1544 M_PROTO, 0)) == NULL) 1545 return; 1546 1547 bzero(mp->b_rptr, sizeof (dl_notify_ind_t)); 1548 dlip = (dl_notify_ind_t *)mp->b_rptr; 1549 dlip->dl_primitive = DL_NOTIFY_IND; 1550 dlip->dl_notification = DL_NOTE_PHYS_ADDR; 1551 dlip->dl_data = DL_CURR_PHYS_ADDR; 1552 dlip->dl_addr_offset = sizeof (dl_notify_ind_t); 1553 dlip->dl_addr_length = addr_length + sizeof (uint16_t); 1554 1555 bcopy(addr, &dlip[1], addr_length); 1556 1557 ethertype = (dsp->ds_sap < ETHERTYPE_802_MIN) ? 0 : dsp->ds_sap; 1558 *(uint16_t *)((uchar_t *)(dlip + 1) + addr_length) = ethertype; 1559 1560 qreply(dsp->ds_wq, mp); 1561 } 1562 1563 /* 1564 * DL_NOTIFY_IND: DL_NOTE_LINK_UP 1565 */ 1566 static void 1567 str_notify_link_up(dld_str_t *dsp) 1568 { 1569 mblk_t *mp; 1570 dl_notify_ind_t *dlip; 1571 1572 if (!(dsp->ds_notifications & DL_NOTE_LINK_UP)) 1573 return; 1574 1575 if ((mp = mexchange(dsp->ds_wq, NULL, sizeof (dl_notify_ind_t), 1576 M_PROTO, 0)) == NULL) 1577 return; 1578 1579 bzero(mp->b_rptr, sizeof (dl_notify_ind_t)); 1580 dlip = (dl_notify_ind_t *)mp->b_rptr; 1581 dlip->dl_primitive = DL_NOTIFY_IND; 1582 dlip->dl_notification = DL_NOTE_LINK_UP; 1583 1584 qreply(dsp->ds_wq, mp); 1585 } 1586 1587 /* 1588 * DL_NOTIFY_IND: DL_NOTE_LINK_DOWN 1589 */ 1590 static void 1591 str_notify_link_down(dld_str_t *dsp) 1592 { 1593 mblk_t *mp; 1594 dl_notify_ind_t *dlip; 1595 1596 if (!(dsp->ds_notifications & DL_NOTE_LINK_DOWN)) 1597 return; 1598 1599 if ((mp = mexchange(dsp->ds_wq, NULL, sizeof (dl_notify_ind_t), 1600 M_PROTO, 0)) == NULL) 1601 return; 1602 1603 bzero(mp->b_rptr, sizeof (dl_notify_ind_t)); 1604 dlip = (dl_notify_ind_t *)mp->b_rptr; 1605 dlip->dl_primitive = DL_NOTIFY_IND; 1606 dlip->dl_notification = DL_NOTE_LINK_DOWN; 1607 1608 qreply(dsp->ds_wq, mp); 1609 } 1610 1611 /* 1612 * DL_NOTIFY_IND: DL_NOTE_SPEED 1613 */ 1614 static void 1615 str_notify_speed(dld_str_t *dsp, uint32_t speed) 1616 { 1617 mblk_t *mp; 1618 dl_notify_ind_t *dlip; 1619 1620 if (!(dsp->ds_notifications & DL_NOTE_SPEED)) 1621 return; 1622 1623 if ((mp = mexchange(dsp->ds_wq, NULL, sizeof (dl_notify_ind_t), 1624 M_PROTO, 0)) == NULL) 1625 return; 1626 1627 bzero(mp->b_rptr, sizeof (dl_notify_ind_t)); 1628 dlip = (dl_notify_ind_t *)mp->b_rptr; 1629 dlip->dl_primitive = DL_NOTIFY_IND; 1630 dlip->dl_notification = DL_NOTE_SPEED; 1631 dlip->dl_data = speed; 1632 1633 qreply(dsp->ds_wq, mp); 1634 } 1635 1636 /* 1637 * DL_NOTIFY_IND: DL_NOTE_CAPAB_RENEG 1638 */ 1639 static void 1640 str_notify_capab_reneg(dld_str_t *dsp) 1641 { 1642 mblk_t *mp; 1643 dl_notify_ind_t *dlip; 1644 1645 if (!(dsp->ds_notifications & DL_NOTE_CAPAB_RENEG)) 1646 return; 1647 1648 if ((mp = mexchange(dsp->ds_wq, NULL, sizeof (dl_notify_ind_t), 1649 M_PROTO, 0)) == NULL) 1650 return; 1651 1652 bzero(mp->b_rptr, sizeof (dl_notify_ind_t)); 1653 dlip = (dl_notify_ind_t *)mp->b_rptr; 1654 dlip->dl_primitive = DL_NOTIFY_IND; 1655 dlip->dl_notification = DL_NOTE_CAPAB_RENEG; 1656 1657 qreply(dsp->ds_wq, mp); 1658 } 1659 1660 /* 1661 * DL_NOTIFY_IND: DL_NOTE_FASTPATH_FLUSH 1662 */ 1663 static void 1664 str_notify_fastpath_flush(dld_str_t *dsp) 1665 { 1666 mblk_t *mp; 1667 dl_notify_ind_t *dlip; 1668 1669 if (!(dsp->ds_notifications & DL_NOTE_FASTPATH_FLUSH)) 1670 return; 1671 1672 if ((mp = mexchange(dsp->ds_wq, NULL, sizeof (dl_notify_ind_t), 1673 M_PROTO, 0)) == NULL) 1674 return; 1675 1676 bzero(mp->b_rptr, sizeof (dl_notify_ind_t)); 1677 dlip = (dl_notify_ind_t *)mp->b_rptr; 1678 dlip->dl_primitive = DL_NOTIFY_IND; 1679 dlip->dl_notification = DL_NOTE_FASTPATH_FLUSH; 1680 1681 qreply(dsp->ds_wq, mp); 1682 } 1683 1684 /* 1685 * MAC notification callback. 1686 */ 1687 static void 1688 str_notify(void *arg, mac_notify_type_t type) 1689 { 1690 dld_str_t *dsp = (dld_str_t *)arg; 1691 queue_t *q = dsp->ds_wq; 1692 1693 switch (type) { 1694 case MAC_NOTE_TX: 1695 qenable(q); 1696 break; 1697 1698 case MAC_NOTE_DEVPROMISC: 1699 /* 1700 * Send the appropriate DL_NOTIFY_IND. 1701 */ 1702 if (mac_promisc_get(dsp->ds_mh, MAC_DEVPROMISC)) 1703 str_notify_promisc_on_phys(dsp); 1704 else 1705 str_notify_promisc_off_phys(dsp); 1706 break; 1707 1708 case MAC_NOTE_PROMISC: 1709 break; 1710 1711 case MAC_NOTE_UNICST: 1712 /* 1713 * This notification is sent whenever the MAC unicast address 1714 * changes. We need to re-cache the address. 1715 */ 1716 mac_unicst_get(dsp->ds_mh, dsp->ds_curr_addr); 1717 1718 /* 1719 * Send the appropriate DL_NOTIFY_IND. 1720 */ 1721 str_notify_phys_addr(dsp, dsp->ds_curr_addr); 1722 break; 1723 1724 case MAC_NOTE_LINK: 1725 /* 1726 * This notification is sent every time the MAC driver 1727 * updates the link state. 1728 */ 1729 switch (mac_link_get(dsp->ds_mh)) { 1730 case LINK_STATE_UP: { 1731 uint64_t speed; 1732 /* 1733 * The link is up so send the appropriate 1734 * DL_NOTIFY_IND. 1735 */ 1736 str_notify_link_up(dsp); 1737 1738 speed = mac_stat_get(dsp->ds_mh, MAC_STAT_IFSPEED); 1739 str_notify_speed(dsp, (uint32_t)(speed / 1000ull)); 1740 break; 1741 } 1742 case LINK_STATE_DOWN: 1743 /* 1744 * The link is down so send the appropriate 1745 * DL_NOTIFY_IND. 1746 */ 1747 str_notify_link_down(dsp); 1748 break; 1749 1750 default: 1751 break; 1752 } 1753 break; 1754 1755 case MAC_NOTE_RESOURCE: 1756 case MAC_NOTE_VNIC: 1757 /* 1758 * This notification is sent whenever the MAC resources 1759 * change or capabilities change. We need to renegotiate 1760 * the capabilities. Send the appropriate DL_NOTIFY_IND. 1761 */ 1762 str_notify_capab_reneg(dsp); 1763 break; 1764 1765 case MAC_NOTE_FASTPATH_FLUSH: 1766 str_notify_fastpath_flush(dsp); 1767 break; 1768 1769 default: 1770 ASSERT(B_FALSE); 1771 break; 1772 } 1773 } 1774 1775 /* 1776 * Enqueue one or more messages to the transmit queue. 1777 * Caller specifies the insertion position (head/tail). 1778 */ 1779 void 1780 dld_tx_enqueue(dld_str_t *dsp, mblk_t *mp, boolean_t head_insert) 1781 { 1782 mblk_t *tail; 1783 queue_t *q = dsp->ds_wq; 1784 uint_t cnt, msgcnt; 1785 uint_t tot_cnt, tot_msgcnt; 1786 1787 ASSERT(DB_TYPE(mp) == M_DATA); 1788 /* Calculate total size and count of the packet(s) */ 1789 for (tail = mp, cnt = msgdsize(mp), msgcnt = 1; 1790 tail->b_next != NULL; tail = tail->b_next) { 1791 ASSERT(DB_TYPE(tail->b_next) == M_DATA); 1792 cnt += msgdsize(tail->b_next); 1793 msgcnt++; 1794 } 1795 1796 mutex_enter(&dsp->ds_tx_list_lock); 1797 /* 1798 * If the queue depth would exceed the allowed threshold, drop 1799 * new packet(s) and drain those already in the queue. 1800 */ 1801 tot_cnt = dsp->ds_tx_cnt + cnt; 1802 tot_msgcnt = dsp->ds_tx_msgcnt + msgcnt; 1803 1804 if (!head_insert && 1805 (tot_cnt >= dld_max_q_count || tot_msgcnt >= dld_max_q_count)) { 1806 ASSERT(dsp->ds_tx_qbusy); 1807 mutex_exit(&dsp->ds_tx_list_lock); 1808 freemsgchain(mp); 1809 goto done; 1810 } 1811 1812 /* Update the queue size parameters */ 1813 dsp->ds_tx_cnt = tot_cnt; 1814 dsp->ds_tx_msgcnt = tot_msgcnt; 1815 1816 /* 1817 * If the transmit queue is currently empty and we are 1818 * about to deposit the packet(s) there, switch mode to 1819 * "busy" and raise flow-control condition. 1820 */ 1821 if (!dsp->ds_tx_qbusy) { 1822 dsp->ds_tx_qbusy = B_TRUE; 1823 ASSERT(dsp->ds_tx_flow_mp != NULL); 1824 (void) putq(q, dsp->ds_tx_flow_mp); 1825 dsp->ds_tx_flow_mp = NULL; 1826 } 1827 1828 if (!head_insert) { 1829 /* Tail insertion */ 1830 if (dsp->ds_tx_list_head == NULL) 1831 dsp->ds_tx_list_head = mp; 1832 else 1833 dsp->ds_tx_list_tail->b_next = mp; 1834 dsp->ds_tx_list_tail = tail; 1835 } else { 1836 /* Head insertion */ 1837 tail->b_next = dsp->ds_tx_list_head; 1838 if (dsp->ds_tx_list_head == NULL) 1839 dsp->ds_tx_list_tail = tail; 1840 dsp->ds_tx_list_head = mp; 1841 } 1842 mutex_exit(&dsp->ds_tx_list_lock); 1843 done: 1844 /* Schedule service thread to drain the transmit queue */ 1845 if (!head_insert) 1846 qenable(q); 1847 } 1848 1849 void 1850 dld_tx_flush(dld_str_t *dsp) 1851 { 1852 mutex_enter(&dsp->ds_tx_list_lock); 1853 if (dsp->ds_tx_list_head != NULL) { 1854 freemsgchain(dsp->ds_tx_list_head); 1855 dsp->ds_tx_list_head = dsp->ds_tx_list_tail = NULL; 1856 dsp->ds_tx_cnt = dsp->ds_tx_msgcnt = 0; 1857 if (dsp->ds_tx_qbusy) { 1858 dsp->ds_tx_flow_mp = getq(dsp->ds_wq); 1859 ASSERT(dsp->ds_tx_flow_mp != NULL); 1860 dsp->ds_tx_qbusy = B_FALSE; 1861 } 1862 } 1863 mutex_exit(&dsp->ds_tx_list_lock); 1864 } 1865 1866 /* 1867 * Process an M_IOCTL message. 1868 */ 1869 static void 1870 dld_ioc(dld_str_t *dsp, mblk_t *mp) 1871 { 1872 uint_t cmd; 1873 1874 cmd = ((struct iocblk *)mp->b_rptr)->ioc_cmd; 1875 ASSERT(dsp->ds_type == DLD_DLPI); 1876 1877 switch (cmd) { 1878 case DLIOCNATIVE: 1879 ioc_native(dsp, mp); 1880 break; 1881 case DLIOCRAW: 1882 ioc_raw(dsp, mp); 1883 break; 1884 case DLIOCHDRINFO: 1885 ioc_fast(dsp, mp); 1886 break; 1887 default: 1888 ioc(dsp, mp); 1889 } 1890 } 1891 1892 /* 1893 * DLIOCNATIVE 1894 */ 1895 static void 1896 ioc_native(dld_str_t *dsp, mblk_t *mp) 1897 { 1898 queue_t *q = dsp->ds_wq; 1899 const mac_info_t *mip = dsp->ds_mip; 1900 1901 rw_enter(&dsp->ds_lock, RW_WRITER); 1902 1903 /* 1904 * Native mode can be enabled if it's disabled and if the 1905 * native media type is different. 1906 */ 1907 if (!dsp->ds_native && mip->mi_media != mip->mi_nativemedia) 1908 dsp->ds_native = B_TRUE; 1909 1910 rw_exit(&dsp->ds_lock); 1911 1912 if (dsp->ds_native) 1913 miocack(q, mp, 0, mip->mi_nativemedia); 1914 else 1915 miocnak(q, mp, 0, ENOTSUP); 1916 } 1917 1918 /* 1919 * DLIOCRAW 1920 */ 1921 static void 1922 ioc_raw(dld_str_t *dsp, mblk_t *mp) 1923 { 1924 queue_t *q = dsp->ds_wq; 1925 1926 rw_enter(&dsp->ds_lock, RW_WRITER); 1927 if (dsp->ds_polling || dsp->ds_soft_ring) { 1928 rw_exit(&dsp->ds_lock); 1929 miocnak(q, mp, 0, EPROTO); 1930 return; 1931 } 1932 1933 if (dsp->ds_mode != DLD_RAW && dsp->ds_dlstate == DL_IDLE) { 1934 /* 1935 * Set the receive callback. 1936 */ 1937 dls_rx_set(dsp->ds_dc, dld_str_rx_raw, (void *)dsp); 1938 } 1939 1940 /* 1941 * Note that raw mode is enabled. 1942 */ 1943 dsp->ds_mode = DLD_RAW; 1944 1945 rw_exit(&dsp->ds_lock); 1946 miocack(q, mp, 0, 0); 1947 } 1948 1949 /* 1950 * DLIOCHDRINFO 1951 */ 1952 static void 1953 ioc_fast(dld_str_t *dsp, mblk_t *mp) 1954 { 1955 dl_unitdata_req_t *dlp; 1956 off_t off; 1957 size_t len; 1958 const uint8_t *addr; 1959 uint16_t sap; 1960 mblk_t *nmp; 1961 mblk_t *hmp; 1962 uint_t addr_length; 1963 queue_t *q = dsp->ds_wq; 1964 int err; 1965 dls_channel_t dc; 1966 1967 if (dld_opt & DLD_OPT_NO_FASTPATH) { 1968 err = ENOTSUP; 1969 goto failed; 1970 } 1971 1972 /* 1973 * DLIOCHDRINFO should only come from IP. The one initiated from 1974 * user-land should not be allowed. 1975 */ 1976 if (((struct iocblk *)mp->b_rptr)->ioc_cr != kcred) { 1977 err = EINVAL; 1978 goto failed; 1979 } 1980 1981 nmp = mp->b_cont; 1982 if (nmp == NULL || MBLKL(nmp) < sizeof (dl_unitdata_req_t) || 1983 (dlp = (dl_unitdata_req_t *)nmp->b_rptr, 1984 dlp->dl_primitive != DL_UNITDATA_REQ)) { 1985 err = EINVAL; 1986 goto failed; 1987 } 1988 1989 off = dlp->dl_dest_addr_offset; 1990 len = dlp->dl_dest_addr_length; 1991 1992 if (!MBLKIN(nmp, off, len)) { 1993 err = EINVAL; 1994 goto failed; 1995 } 1996 1997 rw_enter(&dsp->ds_lock, RW_READER); 1998 if (dsp->ds_dlstate != DL_IDLE) { 1999 rw_exit(&dsp->ds_lock); 2000 err = ENOTSUP; 2001 goto failed; 2002 } 2003 2004 addr_length = dsp->ds_mip->mi_addr_length; 2005 if (len != addr_length + sizeof (uint16_t)) { 2006 rw_exit(&dsp->ds_lock); 2007 err = EINVAL; 2008 goto failed; 2009 } 2010 2011 addr = nmp->b_rptr + off; 2012 sap = *(uint16_t *)(nmp->b_rptr + off + addr_length); 2013 dc = dsp->ds_dc; 2014 2015 if ((hmp = dls_header(dc, addr, sap, 0, NULL)) == NULL) { 2016 rw_exit(&dsp->ds_lock); 2017 err = ENOMEM; 2018 goto failed; 2019 } 2020 2021 /* 2022 * This is a performance optimization. We originally entered 2023 * as reader and only become writer upon transitioning into 2024 * the DLD_FASTPATH mode for the first time. Otherwise we 2025 * stay as reader and return the fast-path header to IP. 2026 */ 2027 if (dsp->ds_mode != DLD_FASTPATH) { 2028 if (!rw_tryupgrade(&dsp->ds_lock)) { 2029 rw_exit(&dsp->ds_lock); 2030 rw_enter(&dsp->ds_lock, RW_WRITER); 2031 2032 /* 2033 * State may have changed before we re-acquired 2034 * the writer lock in case the upgrade failed. 2035 */ 2036 if (dsp->ds_dlstate != DL_IDLE) { 2037 rw_exit(&dsp->ds_lock); 2038 err = ENOTSUP; 2039 goto failed; 2040 } 2041 } 2042 2043 /* 2044 * Set the receive callback (unless polling is enabled). 2045 */ 2046 if (!dsp->ds_polling && !dsp->ds_soft_ring) 2047 dls_rx_set(dc, dld_str_rx_fastpath, (void *)dsp); 2048 2049 /* 2050 * Note that fast-path mode is enabled. 2051 */ 2052 dsp->ds_mode = DLD_FASTPATH; 2053 } 2054 rw_exit(&dsp->ds_lock); 2055 2056 freemsg(nmp->b_cont); 2057 nmp->b_cont = hmp; 2058 2059 miocack(q, mp, MBLKL(nmp) + MBLKL(hmp), 0); 2060 return; 2061 failed: 2062 miocnak(q, mp, 0, err); 2063 } 2064 2065 /* 2066 * Catch-all handler. 2067 */ 2068 static void 2069 ioc(dld_str_t *dsp, mblk_t *mp) 2070 { 2071 queue_t *q = dsp->ds_wq; 2072 mac_handle_t mh; 2073 2074 rw_enter(&dsp->ds_lock, RW_READER); 2075 if (dsp->ds_dlstate == DL_UNATTACHED) { 2076 rw_exit(&dsp->ds_lock); 2077 miocnak(q, mp, 0, EINVAL); 2078 return; 2079 } 2080 mh = dsp->ds_mh; 2081 ASSERT(mh != NULL); 2082 rw_exit(&dsp->ds_lock); 2083 mac_ioctl(mh, q, mp); 2084 } 2085