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