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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Data-Link Driver 30 */ 31 32 #include <sys/types.h> 33 #include <sys/debug.h> 34 #include <sys/sysmacros.h> 35 #include <sys/stream.h> 36 #include <sys/ddi.h> 37 #include <sys/sunddi.h> 38 #include <sys/strsun.h> 39 #include <sys/cpuvar.h> 40 #include <sys/dlpi.h> 41 #include <netinet/in.h> 42 #include <sys/sdt.h> 43 #include <sys/strsubr.h> 44 #include <sys/vlan.h> 45 #include <sys/mac.h> 46 #include <sys/dls.h> 47 #include <sys/dld.h> 48 #include <sys/dld_impl.h> 49 #include <sys/dls_soft_ring.h> 50 51 typedef boolean_t proto_reqfunc_t(dld_str_t *, union DL_primitives *, mblk_t *); 52 53 static proto_reqfunc_t proto_info_req, proto_attach_req, proto_detach_req, 54 proto_bind_req, proto_unbind_req, proto_promiscon_req, proto_promiscoff_req, 55 proto_enabmulti_req, proto_disabmulti_req, proto_physaddr_req, 56 proto_setphysaddr_req, proto_udqos_req, proto_req, proto_capability_req, 57 proto_notify_req, proto_passive_req; 58 59 static void proto_poll_disable(dld_str_t *); 60 static boolean_t proto_poll_enable(dld_str_t *, dl_capab_dls_t *); 61 62 static void proto_soft_ring_disable(dld_str_t *); 63 static boolean_t proto_soft_ring_enable(dld_str_t *, dl_capab_dls_t *); 64 static boolean_t proto_capability_advertise(dld_str_t *, mblk_t *); 65 static void proto_change_soft_ring_fanout(dld_str_t *, int); 66 67 #define DL_ACK_PENDING(state) \ 68 ((state) == DL_ATTACH_PENDING || \ 69 (state) == DL_DETACH_PENDING || \ 70 (state) == DL_BIND_PENDING || \ 71 (state) == DL_UNBIND_PENDING) 72 73 /* 74 * Process a DLPI protocol message. 75 * The primitives DL_BIND_REQ, DL_ENABMULTI_REQ, DL_PROMISCON_REQ, 76 * DL_SET_PHYS_ADDR_REQ put the data link below our dld_str_t into an 77 * 'active' state. The primitive DL_PASSIVE_REQ marks our dld_str_t 78 * as 'passive' and forbids it from being subsequently made 'active' 79 * by the above primitives. 80 */ 81 void 82 dld_wput_proto_nondata(dld_str_t *dsp, mblk_t *mp) 83 { 84 union DL_primitives *udlp; 85 t_uscalar_t prim; 86 87 ASSERT(MBLKL(mp) >= sizeof (t_uscalar_t)); 88 89 udlp = (union DL_primitives *)mp->b_rptr; 90 prim = udlp->dl_primitive; 91 92 switch (prim) { 93 case DL_INFO_REQ: 94 (void) proto_info_req(dsp, udlp, mp); 95 break; 96 case DL_BIND_REQ: 97 (void) proto_bind_req(dsp, udlp, mp); 98 break; 99 case DL_UNBIND_REQ: 100 (void) proto_unbind_req(dsp, udlp, mp); 101 break; 102 case DL_UDQOS_REQ: 103 (void) proto_udqos_req(dsp, udlp, mp); 104 break; 105 case DL_ATTACH_REQ: 106 (void) proto_attach_req(dsp, udlp, mp); 107 break; 108 case DL_DETACH_REQ: 109 (void) proto_detach_req(dsp, udlp, mp); 110 break; 111 case DL_ENABMULTI_REQ: 112 (void) proto_enabmulti_req(dsp, udlp, mp); 113 break; 114 case DL_DISABMULTI_REQ: 115 (void) proto_disabmulti_req(dsp, udlp, mp); 116 break; 117 case DL_PROMISCON_REQ: 118 (void) proto_promiscon_req(dsp, udlp, mp); 119 break; 120 case DL_PROMISCOFF_REQ: 121 (void) proto_promiscoff_req(dsp, udlp, mp); 122 break; 123 case DL_PHYS_ADDR_REQ: 124 (void) proto_physaddr_req(dsp, udlp, mp); 125 break; 126 case DL_SET_PHYS_ADDR_REQ: 127 (void) proto_setphysaddr_req(dsp, udlp, mp); 128 break; 129 case DL_NOTIFY_REQ: 130 (void) proto_notify_req(dsp, udlp, mp); 131 break; 132 case DL_CAPABILITY_REQ: 133 (void) proto_capability_req(dsp, udlp, mp); 134 break; 135 case DL_PASSIVE_REQ: 136 (void) proto_passive_req(dsp, udlp, mp); 137 break; 138 default: 139 (void) proto_req(dsp, udlp, mp); 140 break; 141 } 142 } 143 144 #define NEG(x) -(x) 145 146 typedef struct dl_info_ack_wrapper { 147 dl_info_ack_t dl_info; 148 uint8_t dl_addr[MAXMACADDRLEN + sizeof (uint16_t)]; 149 uint8_t dl_brdcst_addr[MAXMACADDRLEN]; 150 dl_qos_cl_range1_t dl_qos_range1; 151 dl_qos_cl_sel1_t dl_qos_sel1; 152 } dl_info_ack_wrapper_t; 153 154 /* 155 * DL_INFO_REQ 156 */ 157 /*ARGSUSED*/ 158 static boolean_t 159 proto_info_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 160 { 161 dl_info_ack_wrapper_t *dlwp; 162 dl_info_ack_t *dlp; 163 dl_qos_cl_sel1_t *selp; 164 dl_qos_cl_range1_t *rangep; 165 uint8_t *addr; 166 uint8_t *brdcst_addr; 167 uint_t addr_length; 168 uint_t sap_length; 169 mac_info_t minfo; 170 mac_info_t *minfop; 171 queue_t *q = dsp->ds_wq; 172 173 /* 174 * Swap the request message for one large enough to contain the 175 * wrapper structure defined above. 176 */ 177 if ((mp = mexchange(q, mp, sizeof (dl_info_ack_wrapper_t), 178 M_PCPROTO, 0)) == NULL) 179 return (B_FALSE); 180 181 rw_enter(&dsp->ds_lock, RW_READER); 182 183 bzero(mp->b_rptr, sizeof (dl_info_ack_wrapper_t)); 184 dlwp = (dl_info_ack_wrapper_t *)mp->b_rptr; 185 186 dlp = &(dlwp->dl_info); 187 ASSERT(dlp == (dl_info_ack_t *)mp->b_rptr); 188 189 dlp->dl_primitive = DL_INFO_ACK; 190 191 /* 192 * Set up the sub-structure pointers. 193 */ 194 addr = dlwp->dl_addr; 195 brdcst_addr = dlwp->dl_brdcst_addr; 196 rangep = &(dlwp->dl_qos_range1); 197 selp = &(dlwp->dl_qos_sel1); 198 199 /* 200 * This driver supports only version 2 connectionless DLPI provider 201 * nodes. 202 */ 203 dlp->dl_service_mode = DL_CLDLS; 204 dlp->dl_version = DL_VERSION_2; 205 206 /* 207 * Set the style of the provider 208 */ 209 dlp->dl_provider_style = dsp->ds_style; 210 ASSERT(dlp->dl_provider_style == DL_STYLE1 || 211 dlp->dl_provider_style == DL_STYLE2); 212 213 /* 214 * Set the current DLPI state. 215 */ 216 dlp->dl_current_state = dsp->ds_dlstate; 217 218 /* 219 * Gratuitously set the media type. This is to deal with modules 220 * that assume the media type is known prior to DL_ATTACH_REQ 221 * being completed. 222 */ 223 dlp->dl_mac_type = DL_ETHER; 224 225 /* 226 * If the stream is not at least attached we try to retrieve the 227 * mac_info using mac_info_get() 228 */ 229 if (dsp->ds_dlstate == DL_UNATTACHED || 230 dsp->ds_dlstate == DL_ATTACH_PENDING || 231 dsp->ds_dlstate == DL_DETACH_PENDING) { 232 if (!mac_info_get(ddi_major_to_name(dsp->ds_major), &minfo)) { 233 /* 234 * Cannot find mac_info. giving up. 235 */ 236 goto done; 237 } 238 minfop = &minfo; 239 } else { 240 minfop = (mac_info_t *)dsp->ds_mip; 241 /* We can only get the sdu if we're attached. */ 242 mac_sdu_get(dsp->ds_mh, &dlp->dl_min_sdu, &dlp->dl_max_sdu); 243 } 244 245 /* 246 * Set the media type (properly this time). 247 */ 248 if (dsp->ds_native) 249 dlp->dl_mac_type = minfop->mi_nativemedia; 250 else 251 dlp->dl_mac_type = minfop->mi_media; 252 253 /* 254 * Set the DLSAP length. We only support 16 bit values and they 255 * appear after the MAC address portion of DLSAP addresses. 256 */ 257 sap_length = sizeof (uint16_t); 258 dlp->dl_sap_length = NEG(sap_length); 259 260 addr_length = minfop->mi_addr_length; 261 262 /* 263 * Copy in the media broadcast address. 264 */ 265 if (minfop->mi_brdcst_addr != NULL) { 266 dlp->dl_brdcst_addr_offset = 267 (uintptr_t)brdcst_addr - (uintptr_t)dlp; 268 bcopy(minfop->mi_brdcst_addr, brdcst_addr, addr_length); 269 dlp->dl_brdcst_addr_length = addr_length; 270 } 271 272 dlp->dl_qos_range_offset = (uintptr_t)rangep - (uintptr_t)dlp; 273 dlp->dl_qos_range_length = sizeof (dl_qos_cl_range1_t); 274 275 rangep->dl_qos_type = DL_QOS_CL_RANGE1; 276 rangep->dl_trans_delay.dl_target_value = DL_UNKNOWN; 277 rangep->dl_trans_delay.dl_accept_value = DL_UNKNOWN; 278 rangep->dl_protection.dl_min = DL_UNKNOWN; 279 rangep->dl_protection.dl_max = DL_UNKNOWN; 280 rangep->dl_residual_error = DL_UNKNOWN; 281 282 /* 283 * Specify the supported range of priorities. 284 */ 285 rangep->dl_priority.dl_min = 0; 286 rangep->dl_priority.dl_max = (1 << VLAN_PRI_SIZE) - 1; 287 288 dlp->dl_qos_offset = (uintptr_t)selp - (uintptr_t)dlp; 289 dlp->dl_qos_length = sizeof (dl_qos_cl_sel1_t); 290 291 selp->dl_qos_type = DL_QOS_CL_SEL1; 292 selp->dl_trans_delay = DL_UNKNOWN; 293 selp->dl_protection = DL_UNKNOWN; 294 selp->dl_residual_error = DL_UNKNOWN; 295 296 /* 297 * Specify the current priority (which can be changed by 298 * the DL_UDQOS_REQ primitive). 299 */ 300 selp->dl_priority = dsp->ds_pri; 301 302 dlp->dl_addr_length = addr_length + sizeof (uint16_t); 303 if (dsp->ds_dlstate == DL_IDLE) { 304 /* 305 * The stream is bound. Therefore we can formulate a valid 306 * DLSAP address. 307 */ 308 dlp->dl_addr_offset = (uintptr_t)addr - (uintptr_t)dlp; 309 if (addr_length > 0) 310 bcopy(dsp->ds_curr_addr, addr, addr_length); 311 *(uint16_t *)(addr + addr_length) = dsp->ds_sap; 312 } 313 314 done: 315 ASSERT(IMPLY(dlp->dl_qos_offset != 0, dlp->dl_qos_length != 0)); 316 ASSERT(IMPLY(dlp->dl_qos_range_offset != 0, 317 dlp->dl_qos_range_length != 0)); 318 ASSERT(IMPLY(dlp->dl_addr_offset != 0, dlp->dl_addr_length != 0)); 319 ASSERT(IMPLY(dlp->dl_brdcst_addr_offset != 0, 320 dlp->dl_brdcst_addr_length != 0)); 321 322 rw_exit(&dsp->ds_lock); 323 324 qreply(q, mp); 325 return (B_TRUE); 326 } 327 328 /* 329 * DL_ATTACH_REQ 330 */ 331 static boolean_t 332 proto_attach_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 333 { 334 dl_attach_req_t *dlp = (dl_attach_req_t *)udlp; 335 int err = 0; 336 t_uscalar_t dl_err; 337 queue_t *q = dsp->ds_wq; 338 339 rw_enter(&dsp->ds_lock, RW_WRITER); 340 341 if (MBLKL(mp) < sizeof (dl_attach_req_t) || 342 dlp->dl_ppa < 0 || dsp->ds_style == DL_STYLE1) { 343 dl_err = DL_BADPRIM; 344 goto failed; 345 } 346 347 if (dsp->ds_dlstate != DL_UNATTACHED) { 348 dl_err = DL_OUTSTATE; 349 goto failed; 350 } 351 352 dsp->ds_dlstate = DL_ATTACH_PENDING; 353 354 err = dld_str_attach(dsp, dlp->dl_ppa); 355 if (err != 0) { 356 switch (err) { 357 case ENOENT: 358 dl_err = DL_BADPPA; 359 err = 0; 360 break; 361 default: 362 dl_err = DL_SYSERR; 363 break; 364 } 365 dsp->ds_dlstate = DL_UNATTACHED; 366 goto failed; 367 } 368 ASSERT(dsp->ds_dlstate == DL_UNBOUND); 369 rw_exit(&dsp->ds_lock); 370 371 dlokack(q, mp, DL_ATTACH_REQ); 372 return (B_TRUE); 373 failed: 374 rw_exit(&dsp->ds_lock); 375 dlerrorack(q, mp, DL_ATTACH_REQ, dl_err, (t_uscalar_t)err); 376 return (B_FALSE); 377 } 378 379 /*ARGSUSED*/ 380 static boolean_t 381 proto_detach_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 382 { 383 queue_t *q = dsp->ds_wq; 384 t_uscalar_t dl_err; 385 386 rw_enter(&dsp->ds_lock, RW_WRITER); 387 388 if (MBLKL(mp) < sizeof (dl_detach_req_t)) { 389 dl_err = DL_BADPRIM; 390 goto failed; 391 } 392 393 if (dsp->ds_dlstate != DL_UNBOUND) { 394 dl_err = DL_OUTSTATE; 395 goto failed; 396 } 397 398 if (dsp->ds_style == DL_STYLE1) { 399 dl_err = DL_BADPRIM; 400 goto failed; 401 } 402 403 dsp->ds_dlstate = DL_DETACH_PENDING; 404 dld_str_detach(dsp); 405 406 rw_exit(&dsp->ds_lock); 407 dlokack(dsp->ds_wq, mp, DL_DETACH_REQ); 408 return (B_TRUE); 409 failed: 410 rw_exit(&dsp->ds_lock); 411 dlerrorack(q, mp, DL_DETACH_REQ, dl_err, 0); 412 return (B_FALSE); 413 } 414 415 /* 416 * DL_BIND_REQ 417 */ 418 static boolean_t 419 proto_bind_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 420 { 421 dl_bind_req_t *dlp = (dl_bind_req_t *)udlp; 422 int err = 0; 423 uint8_t dlsap_addr[MAXMACADDRLEN + sizeof (uint16_t)]; 424 uint_t dlsap_addr_length; 425 t_uscalar_t dl_err; 426 t_scalar_t sap; 427 queue_t *q = dsp->ds_wq; 428 429 /* 430 * Because control message processing is serialized, we don't need 431 * to hold any locks to read any fields of dsp; we only need ds_lock 432 * to update the ds_dlstate, ds_sap and ds_passivestate fields. 433 */ 434 if (MBLKL(mp) < sizeof (dl_bind_req_t)) { 435 dl_err = DL_BADPRIM; 436 goto failed; 437 } 438 439 if (dlp->dl_xidtest_flg != 0) { 440 dl_err = DL_NOAUTO; 441 goto failed; 442 } 443 444 if (dlp->dl_service_mode != DL_CLDLS) { 445 dl_err = DL_UNSUPPORTED; 446 goto failed; 447 } 448 449 if (dsp->ds_dlstate != DL_UNBOUND) { 450 dl_err = DL_OUTSTATE; 451 goto failed; 452 } 453 454 if (dsp->ds_passivestate == DLD_UNINITIALIZED && 455 !dls_active_set(dsp->ds_dc)) { 456 dl_err = DL_SYSERR; 457 err = EBUSY; 458 goto failed; 459 } 460 461 /* 462 * Set the receive callback. 463 */ 464 dls_rx_set(dsp->ds_dc, (dsp->ds_mode == DLD_RAW) ? 465 dld_str_rx_raw : dld_str_rx_unitdata, dsp); 466 467 /* 468 * Bind the channel such that it can receive packets. 469 */ 470 sap = dlp->dl_sap; 471 err = dls_bind(dsp->ds_dc, sap); 472 if (err != 0) { 473 switch (err) { 474 case EINVAL: 475 dl_err = DL_BADADDR; 476 err = 0; 477 break; 478 default: 479 dl_err = DL_SYSERR; 480 break; 481 } 482 483 if (dsp->ds_passivestate == DLD_UNINITIALIZED) 484 dls_active_clear(dsp->ds_dc); 485 486 goto failed; 487 } 488 489 /* 490 * Copy in MAC address. 491 */ 492 dlsap_addr_length = dsp->ds_mip->mi_addr_length; 493 bcopy(dsp->ds_curr_addr, dlsap_addr, dlsap_addr_length); 494 495 /* 496 * Copy in the SAP. 497 */ 498 *(uint16_t *)(dlsap_addr + dlsap_addr_length) = sap; 499 dlsap_addr_length += sizeof (uint16_t); 500 501 rw_enter(&dsp->ds_lock, RW_WRITER); 502 503 dsp->ds_dlstate = DL_IDLE; 504 if (dsp->ds_passivestate == DLD_UNINITIALIZED) 505 dsp->ds_passivestate = DLD_ACTIVE; 506 dsp->ds_sap = sap; 507 508 if (dsp->ds_mode == DLD_FASTPATH) 509 dsp->ds_tx = str_mdata_fastpath_put; 510 else if (dsp->ds_mode == DLD_RAW) 511 dsp->ds_tx = str_mdata_raw_put; 512 dsp->ds_unitdata_tx = dld_wput_proto_data; 513 514 rw_exit(&dsp->ds_lock); 515 516 dlbindack(q, mp, sap, dlsap_addr, dlsap_addr_length, 0, 0); 517 return (B_TRUE); 518 failed: 519 dlerrorack(q, mp, DL_BIND_REQ, dl_err, (t_uscalar_t)err); 520 return (B_FALSE); 521 } 522 523 /* 524 * DL_UNBIND_REQ 525 */ 526 /*ARGSUSED*/ 527 static boolean_t 528 proto_unbind_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 529 { 530 queue_t *q = dsp->ds_wq; 531 t_uscalar_t dl_err; 532 533 if (MBLKL(mp) < sizeof (dl_unbind_req_t)) { 534 dl_err = DL_BADPRIM; 535 goto failed; 536 } 537 538 if (dsp->ds_dlstate != DL_IDLE) { 539 dl_err = DL_OUTSTATE; 540 goto failed; 541 } 542 543 /* 544 * Flush any remaining packets scheduled for transmission. 545 */ 546 dld_tx_flush(dsp); 547 548 /* 549 * Unbind the channel to stop packets being received. 550 */ 551 dls_unbind(dsp->ds_dc); 552 553 /* 554 * Clear the receive callback. 555 */ 556 dls_rx_set(dsp->ds_dc, NULL, NULL); 557 558 rw_enter(&dsp->ds_lock, RW_WRITER); 559 560 /* 561 * Disable polling mode, if it is enabled. 562 */ 563 proto_poll_disable(dsp); 564 565 /* 566 * If soft rings were enabled, the workers should be quiesced. 567 */ 568 dls_soft_ring_disable(dsp->ds_dc); 569 570 /* 571 * Clear LSO flags. 572 */ 573 dsp->ds_lso = B_FALSE; 574 dsp->ds_lso_max = 0; 575 576 /* 577 * Set the mode back to the default (unitdata). 578 */ 579 dsp->ds_mode = DLD_UNITDATA; 580 dsp->ds_dlstate = DL_UNBOUND; 581 DLD_TX_QUIESCE(dsp); 582 rw_exit(&dsp->ds_lock); 583 584 dlokack(q, mp, DL_UNBIND_REQ); 585 586 return (B_TRUE); 587 failed: 588 dlerrorack(q, mp, DL_UNBIND_REQ, dl_err, 0); 589 return (B_FALSE); 590 } 591 592 /* 593 * DL_PROMISCON_REQ 594 */ 595 static boolean_t 596 proto_promiscon_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 597 { 598 dl_promiscon_req_t *dlp = (dl_promiscon_req_t *)udlp; 599 int err = 0; 600 t_uscalar_t dl_err; 601 uint32_t promisc; 602 queue_t *q = dsp->ds_wq; 603 604 /* 605 * Because control message processing is serialized, we don't need 606 * to hold any locks to read any fields of dsp; we only need ds_lock 607 * to update the ds_promisc and ds_passivestate fields. 608 */ 609 if (MBLKL(mp) < sizeof (dl_promiscon_req_t)) { 610 dl_err = DL_BADPRIM; 611 goto failed; 612 } 613 614 if (dsp->ds_dlstate == DL_UNATTACHED || 615 DL_ACK_PENDING(dsp->ds_dlstate)) { 616 dl_err = DL_OUTSTATE; 617 goto failed; 618 } 619 620 switch (dlp->dl_level) { 621 case DL_PROMISC_SAP: 622 promisc = DLS_PROMISC_SAP; 623 break; 624 case DL_PROMISC_MULTI: 625 promisc = DLS_PROMISC_MULTI; 626 break; 627 case DL_PROMISC_PHYS: 628 promisc = DLS_PROMISC_PHYS; 629 break; 630 default: 631 dl_err = DL_NOTSUPPORTED; 632 goto failed; 633 } 634 635 if (dsp->ds_passivestate == DLD_UNINITIALIZED && 636 !dls_active_set(dsp->ds_dc)) { 637 dl_err = DL_SYSERR; 638 err = EBUSY; 639 goto failed; 640 } 641 642 /* 643 * Adjust channel promiscuity. 644 */ 645 promisc = (dsp->ds_promisc | promisc); 646 err = dls_promisc(dsp->ds_dc, promisc); 647 if (err != 0) { 648 dl_err = DL_SYSERR; 649 if (dsp->ds_passivestate == DLD_UNINITIALIZED) 650 dls_active_clear(dsp->ds_dc); 651 goto failed; 652 } 653 654 rw_enter(&dsp->ds_lock, RW_WRITER); 655 if (dsp->ds_passivestate == DLD_UNINITIALIZED) 656 dsp->ds_passivestate = DLD_ACTIVE; 657 dsp->ds_promisc = promisc; 658 rw_exit(&dsp->ds_lock); 659 660 dlokack(q, mp, DL_PROMISCON_REQ); 661 return (B_TRUE); 662 failed: 663 dlerrorack(q, mp, DL_PROMISCON_REQ, dl_err, (t_uscalar_t)err); 664 return (B_FALSE); 665 } 666 667 /* 668 * DL_PROMISCOFF_REQ 669 */ 670 static boolean_t 671 proto_promiscoff_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 672 { 673 dl_promiscoff_req_t *dlp = (dl_promiscoff_req_t *)udlp; 674 int err = 0; 675 t_uscalar_t dl_err; 676 uint32_t promisc; 677 queue_t *q = dsp->ds_wq; 678 679 /* 680 * Because control messages processing is serialized, we don't need 681 * to hold any lock to read any field of dsp; we hold ds_lock to 682 * update the ds_promisc field. 683 */ 684 if (MBLKL(mp) < sizeof (dl_promiscoff_req_t)) { 685 dl_err = DL_BADPRIM; 686 goto failed; 687 } 688 689 if (dsp->ds_dlstate == DL_UNATTACHED || 690 DL_ACK_PENDING(dsp->ds_dlstate)) { 691 dl_err = DL_OUTSTATE; 692 goto failed; 693 } 694 695 switch (dlp->dl_level) { 696 case DL_PROMISC_SAP: 697 promisc = DLS_PROMISC_SAP; 698 break; 699 case DL_PROMISC_MULTI: 700 promisc = DLS_PROMISC_MULTI; 701 break; 702 case DL_PROMISC_PHYS: 703 promisc = DLS_PROMISC_PHYS; 704 break; 705 default: 706 dl_err = DL_NOTSUPPORTED; 707 goto failed; 708 } 709 710 if (!(dsp->ds_promisc & promisc)) { 711 dl_err = DL_NOTENAB; 712 goto failed; 713 } 714 715 promisc = (dsp->ds_promisc & ~promisc); 716 err = dls_promisc(dsp->ds_dc, promisc); 717 if (err != 0) { 718 dl_err = DL_SYSERR; 719 goto failed; 720 } 721 722 rw_enter(&dsp->ds_lock, RW_WRITER); 723 dsp->ds_promisc = promisc; 724 rw_exit(&dsp->ds_lock); 725 726 dlokack(q, mp, DL_PROMISCOFF_REQ); 727 return (B_TRUE); 728 failed: 729 dlerrorack(q, mp, DL_PROMISCOFF_REQ, dl_err, (t_uscalar_t)err); 730 return (B_FALSE); 731 } 732 733 /* 734 * DL_ENABMULTI_REQ 735 */ 736 static boolean_t 737 proto_enabmulti_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 738 { 739 dl_enabmulti_req_t *dlp = (dl_enabmulti_req_t *)udlp; 740 int err = 0; 741 t_uscalar_t dl_err; 742 queue_t *q = dsp->ds_wq; 743 744 /* 745 * Because control messages processing is serialized, we don't need 746 * to hold any lock to read any field of dsp; we hold ds_lock to 747 * update the ds_passivestate field. 748 */ 749 if (dsp->ds_dlstate == DL_UNATTACHED || 750 DL_ACK_PENDING(dsp->ds_dlstate)) { 751 dl_err = DL_OUTSTATE; 752 goto failed; 753 } 754 755 if (MBLKL(mp) < sizeof (dl_enabmulti_req_t) || 756 !MBLKIN(mp, dlp->dl_addr_offset, dlp->dl_addr_length) || 757 dlp->dl_addr_length != dsp->ds_mip->mi_addr_length) { 758 dl_err = DL_BADPRIM; 759 goto failed; 760 } 761 762 if (dsp->ds_passivestate == DLD_UNINITIALIZED && 763 !dls_active_set(dsp->ds_dc)) { 764 dl_err = DL_SYSERR; 765 err = EBUSY; 766 goto failed; 767 } 768 769 err = dls_multicst_add(dsp->ds_dc, mp->b_rptr + dlp->dl_addr_offset); 770 if (err != 0) { 771 switch (err) { 772 case EINVAL: 773 dl_err = DL_BADADDR; 774 err = 0; 775 break; 776 case ENOSPC: 777 dl_err = DL_TOOMANY; 778 err = 0; 779 break; 780 default: 781 dl_err = DL_SYSERR; 782 break; 783 } 784 785 if (dsp->ds_passivestate == DLD_UNINITIALIZED) 786 dls_active_clear(dsp->ds_dc); 787 788 goto failed; 789 } 790 791 rw_enter(&dsp->ds_lock, RW_WRITER); 792 if (dsp->ds_passivestate == DLD_UNINITIALIZED) 793 dsp->ds_passivestate = DLD_ACTIVE; 794 rw_exit(&dsp->ds_lock); 795 796 dlokack(q, mp, DL_ENABMULTI_REQ); 797 return (B_TRUE); 798 failed: 799 dlerrorack(q, mp, DL_ENABMULTI_REQ, dl_err, (t_uscalar_t)err); 800 return (B_FALSE); 801 } 802 803 /* 804 * DL_DISABMULTI_REQ 805 */ 806 static boolean_t 807 proto_disabmulti_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 808 { 809 dl_disabmulti_req_t *dlp = (dl_disabmulti_req_t *)udlp; 810 int err = 0; 811 t_uscalar_t dl_err; 812 queue_t *q = dsp->ds_wq; 813 814 /* 815 * Because control messages processing is serialized, we don't need 816 * to hold any lock to read any field of dsp. 817 */ 818 if (dsp->ds_dlstate == DL_UNATTACHED || 819 DL_ACK_PENDING(dsp->ds_dlstate)) { 820 dl_err = DL_OUTSTATE; 821 goto failed; 822 } 823 824 if (MBLKL(mp) < sizeof (dl_disabmulti_req_t) || 825 !MBLKIN(mp, dlp->dl_addr_offset, dlp->dl_addr_length) || 826 dlp->dl_addr_length != dsp->ds_mip->mi_addr_length) { 827 dl_err = DL_BADPRIM; 828 goto failed; 829 } 830 831 err = dls_multicst_remove(dsp->ds_dc, mp->b_rptr + dlp->dl_addr_offset); 832 if (err != 0) { 833 switch (err) { 834 case EINVAL: 835 dl_err = DL_BADADDR; 836 err = 0; 837 break; 838 case ENOENT: 839 dl_err = DL_NOTENAB; 840 err = 0; 841 break; 842 default: 843 dl_err = DL_SYSERR; 844 break; 845 } 846 goto failed; 847 } 848 849 dlokack(q, mp, DL_DISABMULTI_REQ); 850 return (B_TRUE); 851 failed: 852 dlerrorack(q, mp, DL_DISABMULTI_REQ, dl_err, (t_uscalar_t)err); 853 return (B_FALSE); 854 } 855 856 /* 857 * DL_PHYS_ADDR_REQ 858 */ 859 static boolean_t 860 proto_physaddr_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 861 { 862 dl_phys_addr_req_t *dlp = (dl_phys_addr_req_t *)udlp; 863 queue_t *q = dsp->ds_wq; 864 t_uscalar_t dl_err; 865 char *addr; 866 uint_t addr_length; 867 868 rw_enter(&dsp->ds_lock, RW_READER); 869 870 if (MBLKL(mp) < sizeof (dl_phys_addr_req_t)) { 871 dl_err = DL_BADPRIM; 872 goto failed; 873 } 874 875 if (dsp->ds_dlstate == DL_UNATTACHED || 876 DL_ACK_PENDING(dsp->ds_dlstate)) { 877 dl_err = DL_OUTSTATE; 878 goto failed; 879 } 880 881 if (dlp->dl_addr_type != DL_CURR_PHYS_ADDR && 882 dlp->dl_addr_type != DL_FACT_PHYS_ADDR) { 883 dl_err = DL_UNSUPPORTED; 884 goto failed; 885 } 886 887 addr_length = dsp->ds_mip->mi_addr_length; 888 addr = kmem_alloc(addr_length, KM_NOSLEEP); 889 if (addr == NULL) { 890 rw_exit(&dsp->ds_lock); 891 merror(q, mp, ENOSR); 892 return (B_FALSE); 893 } 894 895 /* 896 * Copy out the address before we drop the lock; we don't 897 * want to call dlphysaddrack() while holding ds_lock. 898 */ 899 bcopy((dlp->dl_addr_type == DL_CURR_PHYS_ADDR) ? 900 dsp->ds_curr_addr : dsp->ds_fact_addr, addr, addr_length); 901 902 rw_exit(&dsp->ds_lock); 903 dlphysaddrack(q, mp, addr, (t_uscalar_t)addr_length); 904 kmem_free(addr, addr_length); 905 return (B_TRUE); 906 failed: 907 rw_exit(&dsp->ds_lock); 908 dlerrorack(q, mp, DL_PHYS_ADDR_REQ, dl_err, 0); 909 return (B_FALSE); 910 } 911 912 /* 913 * DL_SET_PHYS_ADDR_REQ 914 */ 915 static boolean_t 916 proto_setphysaddr_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 917 { 918 dl_set_phys_addr_req_t *dlp = (dl_set_phys_addr_req_t *)udlp; 919 int err = 0; 920 t_uscalar_t dl_err; 921 queue_t *q = dsp->ds_wq; 922 923 /* 924 * Because control message processing is serialized, we don't need 925 * to hold any locks to read any fields of dsp; we only need ds_lock 926 * to update the ds_passivestate field. 927 */ 928 if (dsp->ds_dlstate == DL_UNATTACHED || 929 DL_ACK_PENDING(dsp->ds_dlstate)) { 930 dl_err = DL_OUTSTATE; 931 goto failed; 932 } 933 934 if (MBLKL(mp) < sizeof (dl_set_phys_addr_req_t) || 935 !MBLKIN(mp, dlp->dl_addr_offset, dlp->dl_addr_length) || 936 dlp->dl_addr_length != dsp->ds_mip->mi_addr_length) { 937 dl_err = DL_BADPRIM; 938 goto failed; 939 } 940 941 if (dsp->ds_passivestate == DLD_UNINITIALIZED && 942 !dls_active_set(dsp->ds_dc)) { 943 dl_err = DL_SYSERR; 944 err = EBUSY; 945 goto failed; 946 } 947 948 err = mac_unicst_set(dsp->ds_mh, mp->b_rptr + dlp->dl_addr_offset); 949 if (err != 0) { 950 switch (err) { 951 case EINVAL: 952 dl_err = DL_BADADDR; 953 err = 0; 954 break; 955 956 default: 957 dl_err = DL_SYSERR; 958 break; 959 } 960 961 if (dsp->ds_passivestate == DLD_UNINITIALIZED) 962 dls_active_clear(dsp->ds_dc); 963 964 goto failed; 965 } 966 967 rw_enter(&dsp->ds_lock, RW_WRITER); 968 if (dsp->ds_passivestate == DLD_UNINITIALIZED) 969 dsp->ds_passivestate = DLD_ACTIVE; 970 rw_exit(&dsp->ds_lock); 971 972 dlokack(q, mp, DL_SET_PHYS_ADDR_REQ); 973 return (B_TRUE); 974 failed: 975 dlerrorack(q, mp, DL_SET_PHYS_ADDR_REQ, dl_err, (t_uscalar_t)err); 976 return (B_FALSE); 977 } 978 979 /* 980 * DL_UDQOS_REQ 981 */ 982 static boolean_t 983 proto_udqos_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 984 { 985 dl_udqos_req_t *dlp = (dl_udqos_req_t *)udlp; 986 dl_qos_cl_sel1_t *selp; 987 int off, len; 988 t_uscalar_t dl_err; 989 queue_t *q = dsp->ds_wq; 990 991 off = dlp->dl_qos_offset; 992 len = dlp->dl_qos_length; 993 994 if (MBLKL(mp) < sizeof (dl_udqos_req_t) || !MBLKIN(mp, off, len)) { 995 dl_err = DL_BADPRIM; 996 goto failed; 997 } 998 999 selp = (dl_qos_cl_sel1_t *)(mp->b_rptr + off); 1000 if (selp->dl_qos_type != DL_QOS_CL_SEL1) { 1001 dl_err = DL_BADQOSTYPE; 1002 goto failed; 1003 } 1004 1005 if (selp->dl_priority > (1 << VLAN_PRI_SIZE) - 1 || 1006 selp->dl_priority < 0) { 1007 dl_err = DL_BADQOSPARAM; 1008 goto failed; 1009 } 1010 1011 if (dsp->ds_dlstate == DL_UNATTACHED || 1012 DL_ACK_PENDING(dsp->ds_dlstate)) { 1013 dl_err = DL_OUTSTATE; 1014 goto failed; 1015 } 1016 1017 rw_enter(&dsp->ds_lock, RW_WRITER); 1018 dsp->ds_pri = selp->dl_priority; 1019 rw_exit(&dsp->ds_lock); 1020 1021 dlokack(q, mp, DL_UDQOS_REQ); 1022 return (B_TRUE); 1023 failed: 1024 dlerrorack(q, mp, DL_UDQOS_REQ, dl_err, 0); 1025 return (B_FALSE); 1026 } 1027 1028 static boolean_t 1029 check_ip_above(queue_t *q) 1030 { 1031 queue_t *next_q; 1032 boolean_t ret = B_TRUE; 1033 1034 claimstr(q); 1035 next_q = q->q_next; 1036 if (strcmp(next_q->q_qinfo->qi_minfo->mi_idname, "ip") != 0) 1037 ret = B_FALSE; 1038 releasestr(q); 1039 return (ret); 1040 } 1041 1042 /* 1043 * DL_CAPABILITY_REQ 1044 */ 1045 /*ARGSUSED*/ 1046 static boolean_t 1047 proto_capability_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 1048 { 1049 dl_capability_req_t *dlp = (dl_capability_req_t *)udlp; 1050 dl_capability_sub_t *sp; 1051 size_t size, len; 1052 offset_t off, end; 1053 t_uscalar_t dl_err; 1054 queue_t *q = dsp->ds_wq; 1055 1056 rw_enter(&dsp->ds_lock, RW_WRITER); 1057 1058 if (MBLKL(mp) < sizeof (dl_capability_req_t)) { 1059 dl_err = DL_BADPRIM; 1060 goto failed; 1061 } 1062 1063 if (dsp->ds_dlstate == DL_UNATTACHED || 1064 DL_ACK_PENDING(dsp->ds_dlstate)) { 1065 dl_err = DL_OUTSTATE; 1066 goto failed; 1067 } 1068 1069 /* 1070 * This request is overloaded. If there are no requested capabilities 1071 * then we just want to acknowledge with all the capabilities we 1072 * support. Otherwise we enable the set of capabilities requested. 1073 */ 1074 if (dlp->dl_sub_length == 0) { 1075 /* callee drops lock */ 1076 return (proto_capability_advertise(dsp, mp)); 1077 } 1078 1079 if (!MBLKIN(mp, dlp->dl_sub_offset, dlp->dl_sub_length)) { 1080 dl_err = DL_BADPRIM; 1081 goto failed; 1082 } 1083 1084 dlp->dl_primitive = DL_CAPABILITY_ACK; 1085 1086 off = dlp->dl_sub_offset; 1087 len = dlp->dl_sub_length; 1088 1089 /* 1090 * Walk the list of capabilities to be enabled. 1091 */ 1092 for (end = off + len; off < end; ) { 1093 sp = (dl_capability_sub_t *)(mp->b_rptr + off); 1094 size = sizeof (dl_capability_sub_t) + sp->dl_length; 1095 1096 if (off + size > end || 1097 !IS_P2ALIGNED(off, sizeof (uint32_t))) { 1098 dl_err = DL_BADPRIM; 1099 goto failed; 1100 } 1101 1102 switch (sp->dl_cap) { 1103 /* 1104 * TCP/IP checksum offload to hardware. 1105 */ 1106 case DL_CAPAB_HCKSUM: { 1107 dl_capab_hcksum_t *hcksump; 1108 dl_capab_hcksum_t hcksum; 1109 1110 hcksump = (dl_capab_hcksum_t *)&sp[1]; 1111 /* 1112 * Copy for alignment. 1113 */ 1114 bcopy(hcksump, &hcksum, sizeof (dl_capab_hcksum_t)); 1115 dlcapabsetqid(&(hcksum.hcksum_mid), dsp->ds_rq); 1116 bcopy(&hcksum, hcksump, sizeof (dl_capab_hcksum_t)); 1117 break; 1118 } 1119 1120 /* 1121 * Large segment offload. (LSO) 1122 */ 1123 case DL_CAPAB_LSO: { 1124 dl_capab_lso_t *lsop; 1125 dl_capab_lso_t lso; 1126 1127 lsop = (dl_capab_lso_t *)&sp[1]; 1128 /* 1129 * Copy for alignment. 1130 */ 1131 bcopy(lsop, &lso, sizeof (dl_capab_lso_t)); 1132 dlcapabsetqid(&(lso.lso_mid), dsp->ds_rq); 1133 bcopy(&lso, lsop, sizeof (dl_capab_lso_t)); 1134 break; 1135 } 1136 1137 /* 1138 * IP polling interface. 1139 */ 1140 case DL_CAPAB_POLL: { 1141 dl_capab_dls_t *pollp; 1142 dl_capab_dls_t poll; 1143 1144 pollp = (dl_capab_dls_t *)&sp[1]; 1145 /* 1146 * Copy for alignment. 1147 */ 1148 bcopy(pollp, &poll, sizeof (dl_capab_dls_t)); 1149 1150 switch (poll.dls_flags) { 1151 default: 1152 /*FALLTHRU*/ 1153 case POLL_DISABLE: 1154 proto_poll_disable(dsp); 1155 break; 1156 1157 case POLL_ENABLE: 1158 ASSERT(!(dld_opt & DLD_OPT_NO_POLL)); 1159 1160 /* 1161 * Make sure polling is disabled. 1162 */ 1163 proto_poll_disable(dsp); 1164 1165 /* 1166 * Note that only IP should enable POLL. 1167 */ 1168 if (check_ip_above(dsp->ds_rq) && 1169 proto_poll_enable(dsp, &poll)) { 1170 bzero(&poll, sizeof (dl_capab_dls_t)); 1171 poll.dls_flags = POLL_ENABLE; 1172 } else { 1173 bzero(&poll, sizeof (dl_capab_dls_t)); 1174 poll.dls_flags = POLL_DISABLE; 1175 } 1176 break; 1177 } 1178 1179 dlcapabsetqid(&(poll.dls_mid), dsp->ds_rq); 1180 bcopy(&poll, pollp, sizeof (dl_capab_dls_t)); 1181 break; 1182 } 1183 case DL_CAPAB_SOFT_RING: { 1184 dl_capab_dls_t *soft_ringp; 1185 dl_capab_dls_t soft_ring; 1186 1187 soft_ringp = (dl_capab_dls_t *)&sp[1]; 1188 /* 1189 * Copy for alignment. 1190 */ 1191 bcopy(soft_ringp, &soft_ring, 1192 sizeof (dl_capab_dls_t)); 1193 1194 switch (soft_ring.dls_flags) { 1195 default: 1196 /*FALLTHRU*/ 1197 case SOFT_RING_DISABLE: 1198 proto_soft_ring_disable(dsp); 1199 break; 1200 1201 case SOFT_RING_ENABLE: 1202 ASSERT(!(dld_opt & DLD_OPT_NO_SOFTRING)); 1203 /* 1204 * Make sure soft_ring is disabled. 1205 */ 1206 proto_soft_ring_disable(dsp); 1207 1208 /* 1209 * Note that only IP can enable soft ring. 1210 */ 1211 if (check_ip_above(dsp->ds_rq) && 1212 proto_soft_ring_enable(dsp, &soft_ring)) { 1213 bzero(&soft_ring, 1214 sizeof (dl_capab_dls_t)); 1215 soft_ring.dls_flags = SOFT_RING_ENABLE; 1216 } else { 1217 bzero(&soft_ring, 1218 sizeof (dl_capab_dls_t)); 1219 soft_ring.dls_flags = SOFT_RING_DISABLE; 1220 } 1221 break; 1222 } 1223 1224 dlcapabsetqid(&(soft_ring.dls_mid), dsp->ds_rq); 1225 bcopy(&soft_ring, soft_ringp, 1226 sizeof (dl_capab_dls_t)); 1227 break; 1228 } 1229 default: 1230 break; 1231 } 1232 1233 off += size; 1234 } 1235 rw_exit(&dsp->ds_lock); 1236 qreply(q, mp); 1237 return (B_TRUE); 1238 failed: 1239 rw_exit(&dsp->ds_lock); 1240 dlerrorack(q, mp, DL_CAPABILITY_REQ, dl_err, 0); 1241 return (B_FALSE); 1242 } 1243 1244 /* 1245 * DL_NOTIFY_REQ 1246 */ 1247 static boolean_t 1248 proto_notify_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 1249 { 1250 dl_notify_req_t *dlp = (dl_notify_req_t *)udlp; 1251 t_uscalar_t dl_err; 1252 queue_t *q = dsp->ds_wq; 1253 uint_t note = 1254 DL_NOTE_PROMISC_ON_PHYS | 1255 DL_NOTE_PROMISC_OFF_PHYS | 1256 DL_NOTE_PHYS_ADDR | 1257 DL_NOTE_LINK_UP | 1258 DL_NOTE_LINK_DOWN | 1259 DL_NOTE_CAPAB_RENEG | 1260 DL_NOTE_SPEED; 1261 1262 rw_enter(&dsp->ds_lock, RW_WRITER); 1263 1264 if (MBLKL(mp) < sizeof (dl_notify_req_t)) { 1265 dl_err = DL_BADPRIM; 1266 goto failed; 1267 } 1268 1269 if (dsp->ds_dlstate == DL_UNATTACHED || 1270 DL_ACK_PENDING(dsp->ds_dlstate)) { 1271 dl_err = DL_OUTSTATE; 1272 goto failed; 1273 } 1274 1275 note &= ~(mac_no_notification(dsp->ds_mh)); 1276 1277 /* 1278 * Cache the notifications that are being enabled. 1279 */ 1280 dsp->ds_notifications = dlp->dl_notifications & note; 1281 rw_exit(&dsp->ds_lock); 1282 /* 1283 * The ACK carries all notifications regardless of which set is 1284 * being enabled. 1285 */ 1286 dlnotifyack(q, mp, note); 1287 1288 /* 1289 * Solicit DL_NOTIFY_IND messages for each enabled notification. 1290 */ 1291 rw_enter(&dsp->ds_lock, RW_READER); 1292 if (dsp->ds_notifications != 0) { 1293 rw_exit(&dsp->ds_lock); 1294 dld_str_notify_ind(dsp); 1295 } else { 1296 rw_exit(&dsp->ds_lock); 1297 } 1298 return (B_TRUE); 1299 failed: 1300 rw_exit(&dsp->ds_lock); 1301 dlerrorack(q, mp, DL_NOTIFY_REQ, dl_err, 0); 1302 return (B_FALSE); 1303 } 1304 1305 /* 1306 * DL_UNITDATA_REQ 1307 */ 1308 void 1309 dld_wput_proto_data(dld_str_t *dsp, mblk_t *mp) 1310 { 1311 queue_t *q = dsp->ds_wq; 1312 dl_unitdata_req_t *dlp = (dl_unitdata_req_t *)mp->b_rptr; 1313 off_t off; 1314 size_t len, size; 1315 const uint8_t *addr; 1316 uint16_t sap; 1317 uint_t addr_length; 1318 mblk_t *bp, *payload; 1319 uint32_t start, stuff, end, value, flags; 1320 t_uscalar_t dl_err; 1321 uint_t max_sdu; 1322 1323 if (MBLKL(mp) < sizeof (dl_unitdata_req_t) || mp->b_cont == NULL) { 1324 dl_err = DL_BADPRIM; 1325 goto failed; 1326 } 1327 1328 addr_length = dsp->ds_mip->mi_addr_length; 1329 1330 off = dlp->dl_dest_addr_offset; 1331 len = dlp->dl_dest_addr_length; 1332 1333 if (!MBLKIN(mp, off, len) || !IS_P2ALIGNED(off, sizeof (uint16_t))) { 1334 dl_err = DL_BADPRIM; 1335 goto failed; 1336 } 1337 1338 if (len != addr_length + sizeof (uint16_t)) { 1339 dl_err = DL_BADADDR; 1340 goto failed; 1341 } 1342 1343 addr = mp->b_rptr + off; 1344 sap = *(uint16_t *)(mp->b_rptr + off + addr_length); 1345 1346 /* 1347 * Check the length of the packet and the block types. 1348 */ 1349 size = 0; 1350 payload = mp->b_cont; 1351 for (bp = payload; bp != NULL; bp = bp->b_cont) { 1352 if (DB_TYPE(bp) != M_DATA) 1353 goto baddata; 1354 1355 size += MBLKL(bp); 1356 } 1357 1358 mac_sdu_get(dsp->ds_mh, NULL, &max_sdu); 1359 if (size > max_sdu) 1360 goto baddata; 1361 1362 /* 1363 * Build a packet header. 1364 */ 1365 if ((bp = dls_header(dsp->ds_dc, addr, sap, dlp->dl_priority.dl_max, 1366 &payload)) == NULL) { 1367 dl_err = DL_BADADDR; 1368 goto failed; 1369 } 1370 1371 /* 1372 * We no longer need the M_PROTO header, so free it. 1373 */ 1374 freeb(mp); 1375 1376 /* 1377 * Transfer the checksum offload information if it is present. 1378 */ 1379 hcksum_retrieve(payload, NULL, NULL, &start, &stuff, &end, &value, 1380 &flags); 1381 (void) hcksum_assoc(bp, NULL, NULL, start, stuff, end, value, flags, 0); 1382 1383 /* 1384 * Link the payload onto the new header. 1385 */ 1386 ASSERT(bp->b_cont == NULL); 1387 bp->b_cont = payload; 1388 dld_tx_single(dsp, bp); 1389 return; 1390 failed: 1391 dlerrorack(q, mp, DL_UNITDATA_REQ, dl_err, 0); 1392 return; 1393 1394 baddata: 1395 dluderrorind(q, mp, (void *)addr, len, DL_BADDATA, 0); 1396 } 1397 1398 /* 1399 * DL_PASSIVE_REQ 1400 */ 1401 /* ARGSUSED */ 1402 static boolean_t 1403 proto_passive_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp) 1404 { 1405 t_uscalar_t dl_err; 1406 1407 /* 1408 * READER lock is enough because ds_passivestate can only be changed 1409 * as the result of non-data message processing. 1410 */ 1411 rw_enter(&dsp->ds_lock, RW_READER); 1412 1413 /* 1414 * If we've already become active by issuing an active primitive, 1415 * then it's too late to try to become passive. 1416 */ 1417 if (dsp->ds_passivestate == DLD_ACTIVE) { 1418 dl_err = DL_OUTSTATE; 1419 goto failed; 1420 } 1421 1422 if (MBLKL(mp) < sizeof (dl_passive_req_t)) { 1423 dl_err = DL_BADPRIM; 1424 goto failed; 1425 } 1426 1427 dsp->ds_passivestate = DLD_PASSIVE; 1428 rw_exit(&dsp->ds_lock); 1429 dlokack(dsp->ds_wq, mp, DL_PASSIVE_REQ); 1430 return (B_TRUE); 1431 failed: 1432 rw_exit(&dsp->ds_lock); 1433 dlerrorack(dsp->ds_wq, mp, DL_PASSIVE_REQ, dl_err, 0); 1434 return (B_FALSE); 1435 } 1436 1437 /* 1438 * Catch-all handler. 1439 */ 1440 static boolean_t 1441 proto_req(dld_str_t *dsp, union DL_primitives *dlp, mblk_t *mp) 1442 { 1443 dlerrorack(dsp->ds_wq, mp, dlp->dl_primitive, DL_UNSUPPORTED, 0); 1444 return (B_FALSE); 1445 } 1446 1447 static void 1448 proto_poll_disable(dld_str_t *dsp) 1449 { 1450 mac_handle_t mh; 1451 1452 ASSERT(RW_WRITE_HELD(&dsp->ds_lock)); 1453 1454 if (!dsp->ds_polling) 1455 return; 1456 1457 /* 1458 * It should be impossible to enable raw mode if polling is turned on. 1459 */ 1460 ASSERT(dsp->ds_mode != DLD_RAW); 1461 1462 /* 1463 * Reset the resource_add callback. 1464 */ 1465 mh = dls_mac(dsp->ds_dc); 1466 mac_resource_set(mh, NULL, NULL); 1467 mac_resources(mh); 1468 1469 /* 1470 * Set receive function back to default. 1471 */ 1472 dls_rx_set(dsp->ds_dc, (dsp->ds_mode == DLD_FASTPATH) ? 1473 dld_str_rx_fastpath : dld_str_rx_unitdata, dsp); 1474 1475 /* 1476 * Note that polling is disabled. 1477 */ 1478 dsp->ds_polling = B_FALSE; 1479 } 1480 1481 static boolean_t 1482 proto_poll_enable(dld_str_t *dsp, dl_capab_dls_t *pollp) 1483 { 1484 mac_handle_t mh; 1485 1486 ASSERT(RW_WRITE_HELD(&dsp->ds_lock)); 1487 ASSERT(!dsp->ds_polling); 1488 1489 /* 1490 * We cannot enable polling if raw mode 1491 * has been enabled. 1492 */ 1493 if (dsp->ds_mode == DLD_RAW) 1494 return (B_FALSE); 1495 1496 mh = dls_mac(dsp->ds_dc); 1497 1498 /* 1499 * Register resources. 1500 */ 1501 mac_resource_set(mh, (mac_resource_add_t)pollp->dls_ring_add, 1502 (void *)pollp->dls_rx_handle); 1503 1504 mac_resources(mh); 1505 1506 /* 1507 * Set the upstream receive function. 1508 */ 1509 dls_rx_set(dsp->ds_dc, (dls_rx_t)pollp->dls_rx, 1510 (void *)pollp->dls_rx_handle); 1511 1512 /* 1513 * Note that polling is enabled. This prevents further DLIOCHDRINFO 1514 * ioctls from overwriting the receive function pointer. 1515 */ 1516 dsp->ds_polling = B_TRUE; 1517 return (B_TRUE); 1518 } 1519 1520 static void 1521 proto_soft_ring_disable(dld_str_t *dsp) 1522 { 1523 ASSERT(RW_WRITE_HELD(&dsp->ds_lock)); 1524 1525 if (!dsp->ds_soft_ring) 1526 return; 1527 1528 /* 1529 * It should be impossible to enable raw mode if soft_ring is turned on. 1530 */ 1531 ASSERT(dsp->ds_mode != DLD_RAW); 1532 proto_change_soft_ring_fanout(dsp, SOFT_RING_NONE); 1533 /* 1534 * Note that fanout is disabled. 1535 */ 1536 dsp->ds_soft_ring = B_FALSE; 1537 } 1538 1539 static boolean_t 1540 proto_soft_ring_enable(dld_str_t *dsp, dl_capab_dls_t *soft_ringp) 1541 { 1542 ASSERT(RW_WRITE_HELD(&dsp->ds_lock)); 1543 ASSERT(!dsp->ds_soft_ring); 1544 1545 /* 1546 * We cannot enable soft_ring if raw mode 1547 * has been enabled. 1548 */ 1549 if (dsp->ds_mode == DLD_RAW) 1550 return (B_FALSE); 1551 1552 if (dls_soft_ring_enable(dsp->ds_dc, soft_ringp) == B_FALSE) 1553 return (B_FALSE); 1554 1555 dsp->ds_soft_ring = B_TRUE; 1556 return (B_TRUE); 1557 } 1558 1559 static void 1560 proto_change_soft_ring_fanout(dld_str_t *dsp, int type) 1561 { 1562 dls_channel_t dc = dsp->ds_dc; 1563 1564 if (type == SOFT_RING_NONE) { 1565 dls_rx_set(dc, (dsp->ds_mode == DLD_FASTPATH) ? 1566 dld_str_rx_fastpath : dld_str_rx_unitdata, dsp); 1567 } else if (type != SOFT_RING_NONE) { 1568 dls_rx_set(dc, (dls_rx_t)dls_soft_ring_fanout, dc); 1569 } 1570 } 1571 1572 /* 1573 * DL_CAPABILITY_ACK/DL_ERROR_ACK 1574 */ 1575 static boolean_t 1576 proto_capability_advertise(dld_str_t *dsp, mblk_t *mp) 1577 { 1578 dl_capability_ack_t *dlap; 1579 dl_capability_sub_t *dlsp; 1580 size_t subsize; 1581 dl_capab_dls_t poll; 1582 dl_capab_dls_t soft_ring; 1583 dl_capab_hcksum_t hcksum; 1584 dl_capab_lso_t lso; 1585 dl_capab_zerocopy_t zcopy; 1586 uint8_t *ptr; 1587 queue_t *q = dsp->ds_wq; 1588 mblk_t *mp1; 1589 boolean_t is_vlan = (dsp->ds_vid != VLAN_ID_NONE); 1590 boolean_t poll_capable = B_FALSE; 1591 boolean_t soft_ring_capable = B_FALSE; 1592 boolean_t hcksum_capable = B_FALSE; 1593 boolean_t zcopy_capable = B_FALSE; 1594 boolean_t lso_capable = B_FALSE; 1595 mac_capab_lso_t mac_lso; 1596 1597 ASSERT(RW_WRITE_HELD(&dsp->ds_lock)); 1598 1599 /* 1600 * Initially assume no capabilities. 1601 */ 1602 subsize = 0; 1603 1604 /* 1605 * Check if soft ring can be enabled on this interface. Note that we 1606 * do not enable softring on any legacy drivers, because doing that 1607 * would hurt the performance if the legacy driver has its own taskq 1608 * implementation. Further, most high-performance legacy drivers do 1609 * have their own taskq implementation. 1610 * 1611 * If advertising DL_CAPAB_SOFT_RING has not been explicitly disabled, 1612 * reserve space for that capability. 1613 */ 1614 if (!mac_is_legacy(dsp->ds_mh) && !(dld_opt & DLD_OPT_NO_SOFTRING)) { 1615 soft_ring_capable = B_TRUE; 1616 subsize += sizeof (dl_capability_sub_t) + 1617 sizeof (dl_capab_dls_t); 1618 } 1619 1620 /* 1621 * Check if polling can be enabled on this interface. 1622 * If advertising DL_CAPAB_POLL has not been explicitly disabled 1623 * then reserve space for that capability. 1624 */ 1625 if (mac_capab_get(dsp->ds_mh, MAC_CAPAB_POLL, NULL) && 1626 !(dld_opt & DLD_OPT_NO_POLL) && !is_vlan) { 1627 poll_capable = B_TRUE; 1628 subsize += sizeof (dl_capability_sub_t) + 1629 sizeof (dl_capab_dls_t); 1630 } 1631 1632 /* 1633 * Check if checksum offload is supported on this MAC. Don't 1634 * advertise DL_CAPAB_HCKSUM if the underlying MAC is VLAN incapable, 1635 * since it might not be able to do the hardware checksum offload 1636 * with the correct offset. 1637 */ 1638 bzero(&hcksum, sizeof (dl_capab_hcksum_t)); 1639 if ((!is_vlan || (!mac_capab_get(dsp->ds_mh, MAC_CAPAB_NO_NATIVEVLAN, 1640 NULL))) && mac_capab_get(dsp->ds_mh, MAC_CAPAB_HCKSUM, 1641 &hcksum.hcksum_txflags)) { 1642 if (hcksum.hcksum_txflags != 0) { 1643 hcksum_capable = B_TRUE; 1644 subsize += sizeof (dl_capability_sub_t) + 1645 sizeof (dl_capab_hcksum_t); 1646 } 1647 } 1648 1649 /* 1650 * Check if LSO is supported on this MAC, then reserve space for 1651 * the DL_CAPAB_LSO capability. 1652 */ 1653 if (mac_capab_get(dsp->ds_mh, MAC_CAPAB_LSO, &mac_lso)) { 1654 lso_capable = B_TRUE; 1655 subsize += sizeof (dl_capability_sub_t) + 1656 sizeof (dl_capab_lso_t); 1657 } 1658 1659 /* 1660 * Check if zerocopy is supported on this interface. 1661 * If advertising DL_CAPAB_ZEROCOPY has not been explicitly disabled 1662 * then reserve space for that capability. 1663 */ 1664 if (!mac_capab_get(dsp->ds_mh, MAC_CAPAB_NO_ZCOPY, NULL) && 1665 !(dld_opt & DLD_OPT_NO_ZEROCOPY)) { 1666 zcopy_capable = B_TRUE; 1667 subsize += sizeof (dl_capability_sub_t) + 1668 sizeof (dl_capab_zerocopy_t); 1669 } 1670 1671 /* 1672 * If there are no capabilities to advertise or if we 1673 * can't allocate a response, send a DL_ERROR_ACK. 1674 */ 1675 if ((mp1 = reallocb(mp, 1676 sizeof (dl_capability_ack_t) + subsize, 0)) == NULL) { 1677 rw_exit(&dsp->ds_lock); 1678 dlerrorack(q, mp, DL_CAPABILITY_REQ, DL_NOTSUPPORTED, 0); 1679 return (B_FALSE); 1680 } 1681 1682 mp = mp1; 1683 DB_TYPE(mp) = M_PROTO; 1684 mp->b_wptr = mp->b_rptr + sizeof (dl_capability_ack_t) + subsize; 1685 bzero(mp->b_rptr, MBLKL(mp)); 1686 dlap = (dl_capability_ack_t *)mp->b_rptr; 1687 dlap->dl_primitive = DL_CAPABILITY_ACK; 1688 dlap->dl_sub_offset = sizeof (dl_capability_ack_t); 1689 dlap->dl_sub_length = subsize; 1690 ptr = (uint8_t *)&dlap[1]; 1691 1692 /* 1693 * IP polling interface. 1694 */ 1695 if (poll_capable) { 1696 /* 1697 * Attempt to disable just in case this is a re-negotiation; 1698 * READER lock is enough because ds_polling can only be 1699 * changed as the result of non-data message processing. 1700 */ 1701 proto_poll_disable(dsp); 1702 1703 dlsp = (dl_capability_sub_t *)ptr; 1704 1705 dlsp->dl_cap = DL_CAPAB_POLL; 1706 dlsp->dl_length = sizeof (dl_capab_dls_t); 1707 ptr += sizeof (dl_capability_sub_t); 1708 1709 bzero(&poll, sizeof (dl_capab_dls_t)); 1710 poll.dls_version = POLL_VERSION_1; 1711 poll.dls_flags = POLL_CAPABLE; 1712 poll.dls_tx_handle = (uintptr_t)dsp; 1713 poll.dls_tx = (uintptr_t)str_mdata_fastpath_put; 1714 dlcapabsetqid(&(poll.dls_mid), dsp->ds_rq); 1715 bcopy(&poll, ptr, sizeof (dl_capab_dls_t)); 1716 ptr += sizeof (dl_capab_dls_t); 1717 } 1718 1719 1720 if (soft_ring_capable) { 1721 dlsp = (dl_capability_sub_t *)ptr; 1722 1723 dlsp->dl_cap = DL_CAPAB_SOFT_RING; 1724 dlsp->dl_length = sizeof (dl_capab_dls_t); 1725 ptr += sizeof (dl_capability_sub_t); 1726 1727 bzero(&soft_ring, sizeof (dl_capab_dls_t)); 1728 soft_ring.dls_version = SOFT_RING_VERSION_1; 1729 soft_ring.dls_flags = SOFT_RING_CAPABLE; 1730 soft_ring.dls_tx_handle = (uintptr_t)dsp; 1731 soft_ring.dls_tx = (uintptr_t)str_mdata_fastpath_put; 1732 soft_ring.dls_ring_change_status = 1733 (uintptr_t)proto_change_soft_ring_fanout; 1734 soft_ring.dls_ring_bind = (uintptr_t)soft_ring_bind; 1735 soft_ring.dls_ring_unbind = (uintptr_t)soft_ring_unbind; 1736 1737 dlcapabsetqid(&(soft_ring.dls_mid), dsp->ds_rq); 1738 bcopy(&soft_ring, ptr, sizeof (dl_capab_dls_t)); 1739 ptr += sizeof (dl_capab_dls_t); 1740 } 1741 1742 /* 1743 * TCP/IP checksum offload. 1744 */ 1745 if (hcksum_capable) { 1746 dlsp = (dl_capability_sub_t *)ptr; 1747 1748 dlsp->dl_cap = DL_CAPAB_HCKSUM; 1749 dlsp->dl_length = sizeof (dl_capab_hcksum_t); 1750 ptr += sizeof (dl_capability_sub_t); 1751 1752 hcksum.hcksum_version = HCKSUM_VERSION_1; 1753 dlcapabsetqid(&(hcksum.hcksum_mid), dsp->ds_rq); 1754 bcopy(&hcksum, ptr, sizeof (dl_capab_hcksum_t)); 1755 ptr += sizeof (dl_capab_hcksum_t); 1756 } 1757 1758 /* 1759 * Large segment offload. (LSO) 1760 */ 1761 if (lso_capable) { 1762 dlsp = (dl_capability_sub_t *)ptr; 1763 1764 dlsp->dl_cap = DL_CAPAB_LSO; 1765 dlsp->dl_length = sizeof (dl_capab_lso_t); 1766 ptr += sizeof (dl_capability_sub_t); 1767 1768 lso.lso_version = LSO_VERSION_1; 1769 lso.lso_flags = mac_lso.lso_flags; 1770 lso.lso_max = mac_lso.lso_basic_tcp_ipv4.lso_max; 1771 1772 /* Simply enable LSO with DLD */ 1773 dsp->ds_lso = B_TRUE; 1774 dsp->ds_lso_max = lso.lso_max; 1775 1776 dlcapabsetqid(&(lso.lso_mid), dsp->ds_rq); 1777 bcopy(&lso, ptr, sizeof (dl_capab_lso_t)); 1778 ptr += sizeof (dl_capab_lso_t); 1779 } else { 1780 dsp->ds_lso = B_FALSE; 1781 dsp->ds_lso_max = 0; 1782 } 1783 1784 /* 1785 * Zero copy 1786 */ 1787 if (zcopy_capable) { 1788 dlsp = (dl_capability_sub_t *)ptr; 1789 1790 dlsp->dl_cap = DL_CAPAB_ZEROCOPY; 1791 dlsp->dl_length = sizeof (dl_capab_zerocopy_t); 1792 ptr += sizeof (dl_capability_sub_t); 1793 1794 bzero(&zcopy, sizeof (dl_capab_zerocopy_t)); 1795 zcopy.zerocopy_version = ZEROCOPY_VERSION_1; 1796 zcopy.zerocopy_flags = DL_CAPAB_VMSAFE_MEM; 1797 1798 dlcapabsetqid(&(zcopy.zerocopy_mid), dsp->ds_rq); 1799 bcopy(&zcopy, ptr, sizeof (dl_capab_zerocopy_t)); 1800 ptr += sizeof (dl_capab_zerocopy_t); 1801 } 1802 1803 ASSERT(ptr == mp->b_rptr + sizeof (dl_capability_ack_t) + subsize); 1804 1805 rw_exit(&dsp->ds_lock); 1806 qreply(q, mp); 1807 return (B_TRUE); 1808 } 1809 1810 /* 1811 * Disable any enabled capabilities. 1812 */ 1813 void 1814 dld_capabilities_disable(dld_str_t *dsp) 1815 { 1816 if (dsp->ds_polling) 1817 proto_poll_disable(dsp); 1818 1819 if (dsp->ds_soft_ring) 1820 proto_soft_ring_disable(dsp); 1821 } 1822