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