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 /* 23 * Copyright 2014 QLogic Corporation 24 * The contents of this file are subject to the terms of the 25 * QLogic End User License (the "License"). 26 * You may not use this file except in compliance with the License. 27 * 28 * You can obtain a copy of the License at 29 * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/ 30 * QLogic_End_User_Software_License.txt 31 * See the License for the specific language governing permissions 32 * and limitations under the License. 33 */ 34 35 /* 36 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 37 * Copyright (c) 2017, Joyent, Inc. 38 * Copyright 2023 Oxide Computer Company 39 */ 40 41 #include "bnxe.h" 42 43 #include <sys/mac.h> 44 #include <sys/mac_ether.h> 45 #include <sys/dlpi.h> 46 47 #if !(defined(__S11) || defined(__S12)) 48 #define mri_driver mr_driver 49 #define mri_start mr_start 50 #define mri_stop mr_stop 51 #define mri_intr mr_intr 52 #define mri_poll mr_poll 53 #define mri_tx mr_send 54 #define mgi_driver mrg_driver 55 #define mgi_start mrg_start 56 #define mgi_stop mrg_stop 57 #define mgi_count mrg_count 58 #define mgi_addmac mrg_addmac 59 #define mgi_remmac mrg_addmac 60 #define mr_gaddring mr_gadd_ring 61 #define mr_gremring mr_grem_ring 62 #endif /* not __S11 or __S12 */ 63 64 /* 65 * Reconfiguring the network devices parameters require net_config 66 * privilege starting Solaris 10. Only root user is allowed to 67 * update device parameter in Solaris 9 and earlier version. Following 68 * declaration allows single binary image to run on all OS versions. 69 */ 70 extern int secpolicy_net_config(const cred_t *, boolean_t); 71 extern int drv_priv(cred_t *); 72 #pragma weak secpolicy_net_config 73 #pragma weak drv_priv 74 75 #ifdef MC_SETPROP 76 77 char * bnxeLink_priv_props[] = 78 { 79 "_adv_2500fdx_cap", 80 "_en_2500fdx_cap", 81 "_adv_txpause_cap", 82 "_en_txpause_cap", 83 "_txpause", 84 "_adv_rxpause_cap", 85 "_en_rxpause_cap", 86 "_rxpause", 87 "_autoneg_flow", 88 "_checksum", 89 "_num_rings", 90 "_rx_descs", 91 "_rx_free_reclaim", 92 "_rx_copy_threshold", 93 "_tx_descs", 94 "_tx_free_reclaim", 95 "_tx_copy_threshold", 96 "_tx_ring_policy", 97 "_interrupt_coalesce", 98 "_rx_interrupt_coalesce_usec", 99 "_tx_interrupt_coalesce_usec", 100 "_disable_msix", 101 "_l2_fw_flow_ctrl", 102 "_autogreeen_enable", 103 "_lso_enable", 104 "_log_enable", 105 "_fcoe_enable", 106 NULL 107 }; 108 109 #endif /* MC_SETPROP */ 110 111 112 static int BnxeMacStats(void * pArg, 113 uint_t stat, 114 uint64_t * pVal) 115 { 116 um_device_t * pUM = (um_device_t *)pArg; 117 lm_device_t * pLM; 118 b10_l2_chip_statistics_t b10_l2_stats; 119 int idx, rc = 0; 120 121 if ((pUM == NULL) || (pVal == NULL)) 122 { 123 return EINVAL; 124 } 125 126 pLM = &pUM->lm_dev; 127 128 BNXE_LOCK_ENTER_GLD(pUM); 129 130 if (!pUM->plumbed) 131 { 132 BNXE_LOCK_EXIT_GLD(pUM); 133 return EAGAIN; 134 } 135 136 *pVal = 0; 137 138 switch (stat) 139 { 140 case MAC_STAT_IFSPEED: 141 *pVal = (pUM->props.link_speed * 1000000ULL); 142 break; 143 144 case MAC_STAT_MULTIRCV: 145 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 146 L2_CHIP_STATISTICS_VER_NUM_1); 147 *pVal = b10_l2_stats.IfHCInMulticastPkts; 148 break; 149 150 case MAC_STAT_BRDCSTRCV: 151 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 152 L2_CHIP_STATISTICS_VER_NUM_1); 153 *pVal = b10_l2_stats.IfHCInBroadcastPkts; 154 break; 155 156 case MAC_STAT_MULTIXMT: 157 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 158 L2_CHIP_STATISTICS_VER_NUM_1); 159 *pVal = b10_l2_stats.IfHCOutMulticastPkts; 160 break; 161 162 case MAC_STAT_BRDCSTXMT: 163 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 164 L2_CHIP_STATISTICS_VER_NUM_1); 165 *pVal = b10_l2_stats.IfHCOutBroadcastPkts; 166 break; 167 168 case MAC_STAT_NORCVBUF: 169 lm_get_stats(pLM, LM_STATS_RCV_NO_BUFFER_DROP, (u64_t *)pVal); 170 break; 171 172 case MAC_STAT_NOXMTBUF: 173 *pVal = 0; 174 LM_FOREACH_TSS_IDX(pLM, idx) 175 { 176 *pVal += pUM->txq[idx].txRecycle; 177 } 178 break; 179 180 case MAC_STAT_IERRORS: 181 case ETHER_STAT_MACRCV_ERRORS: 182 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 183 L2_CHIP_STATISTICS_VER_NUM_1); 184 *pVal = b10_l2_stats.IfInErrors; 185 break; 186 187 case MAC_STAT_OERRORS: 188 /* XXX not available */ 189 break; 190 191 case MAC_STAT_COLLISIONS: 192 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 193 L2_CHIP_STATISTICS_VER_NUM_1); 194 *pVal = b10_l2_stats.EtherStatsCollisions; 195 break; 196 197 case MAC_STAT_RBYTES: 198 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 199 L2_CHIP_STATISTICS_VER_NUM_1); 200 *pVal = b10_l2_stats.IfHCInOctets; 201 break; 202 203 case MAC_STAT_IPACKETS: 204 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 205 L2_CHIP_STATISTICS_VER_NUM_1); 206 *pVal = b10_l2_stats.IfHCInPkts; 207 break; 208 209 case MAC_STAT_OBYTES: 210 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 211 L2_CHIP_STATISTICS_VER_NUM_1); 212 *pVal = b10_l2_stats.IfHCOutOctets; 213 break; 214 215 case MAC_STAT_OPACKETS: 216 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 217 L2_CHIP_STATISTICS_VER_NUM_1); 218 *pVal = b10_l2_stats.IfHCOutPkts; 219 break; 220 221 case ETHER_STAT_ALIGN_ERRORS: 222 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 223 L2_CHIP_STATISTICS_VER_NUM_1); 224 *pVal = b10_l2_stats.Dot3StatsAlignmentErrors; 225 break; 226 227 case ETHER_STAT_FCS_ERRORS: 228 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 229 L2_CHIP_STATISTICS_VER_NUM_1); 230 *pVal = b10_l2_stats.Dot3StatsFCSErrors; 231 break; 232 233 case ETHER_STAT_FIRST_COLLISIONS: 234 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 235 L2_CHIP_STATISTICS_VER_NUM_1); 236 *pVal = b10_l2_stats.Dot3StatsSingleCollisionFrames; 237 break; 238 239 case ETHER_STAT_MULTI_COLLISIONS: 240 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 241 L2_CHIP_STATISTICS_VER_NUM_1); 242 *pVal = b10_l2_stats.Dot3StatsMultipleCollisionFrames; 243 break; 244 245 case ETHER_STAT_DEFER_XMTS: 246 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 247 L2_CHIP_STATISTICS_VER_NUM_1); 248 *pVal = b10_l2_stats.Dot3StatsDeferredTransmissions; 249 break; 250 251 case ETHER_STAT_TX_LATE_COLLISIONS: 252 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 253 L2_CHIP_STATISTICS_VER_NUM_1); 254 *pVal = b10_l2_stats.Dot3StatsLateCollisions; 255 break; 256 257 case ETHER_STAT_EX_COLLISIONS: 258 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 259 L2_CHIP_STATISTICS_VER_NUM_1); 260 *pVal = b10_l2_stats.Dot3StatsExcessiveCollisions; 261 break; 262 263 case ETHER_STAT_MACXMT_ERRORS: 264 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 265 L2_CHIP_STATISTICS_VER_NUM_1); 266 *pVal = b10_l2_stats.Dot3StatsInternalMacTransmitErrors; 267 break; 268 269 case ETHER_STAT_CARRIER_ERRORS: 270 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 271 L2_CHIP_STATISTICS_VER_NUM_1); 272 *pVal = b10_l2_stats.Dot3StatsCarrierSenseErrors; 273 break; 274 275 case ETHER_STAT_TOOLONG_ERRORS: 276 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 277 L2_CHIP_STATISTICS_VER_NUM_1); 278 *pVal = b10_l2_stats.EtherStatsOverrsizePkts; 279 break; 280 281 #if (MAC_VERSION > 1) 282 case ETHER_STAT_TOOSHORT_ERRORS: 283 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats, 284 L2_CHIP_STATISTICS_VER_NUM_1); 285 *pVal = b10_l2_stats.EtherStatsUndersizePkts; 286 break; 287 #endif 288 289 case ETHER_STAT_XCVR_ADDR: 290 *pVal = pLM->vars.phy_addr; 291 break; 292 293 case ETHER_STAT_XCVR_ID: 294 *pVal = 0; 295 break; 296 297 case ETHER_STAT_XCVR_INUSE: 298 *pVal = (uint64_t)bnxe_phy_to_media(pUM); 299 break; 300 301 #if (MAC_VERSION > 1) 302 case ETHER_STAT_CAP_10GFDX: 303 *pVal = 1; 304 break; 305 #endif 306 307 case ETHER_STAT_CAP_1000FDX: 308 *pVal = 1; 309 break; 310 311 #if 0 312 case ETHER_STAT_CAP_1000HDX: 313 //*pVal = linkconf->param_1000hdx; 314 *pVal = 0; 315 break; 316 #endif 317 318 case ETHER_STAT_CAP_100FDX: 319 //*pVal = linkconf->param_100fdx; 320 *pVal = 1; 321 break; 322 323 case ETHER_STAT_CAP_100HDX: 324 //*pVal = linkconf->param_100hdx; 325 *pVal = 1; 326 break; 327 328 case ETHER_STAT_CAP_10FDX: 329 //*pVal = linkconf->param_10fdx; 330 *pVal = 1; 331 break; 332 333 case ETHER_STAT_CAP_10HDX: 334 //*pVal = linkconf->param_10hdx; 335 *pVal = 1; 336 break; 337 338 case ETHER_STAT_CAP_ASMPAUSE: 339 *pVal = 1; 340 break; 341 342 case ETHER_STAT_CAP_PAUSE: 343 *pVal = 1; 344 break; 345 346 case ETHER_STAT_CAP_AUTONEG: 347 *pVal = 1; 348 break; 349 350 #if (MAC_VERSION > 1) 351 case ETHER_STAT_CAP_REMFAULT: 352 *pVal = 1; 353 break; 354 #endif 355 356 #if (MAC_VERSION > 1) 357 case ETHER_STAT_ADV_CAP_10GFDX: 358 *pVal = pUM->curcfg.lnkcfg.param_10000fdx; 359 break; 360 #endif 361 362 case ETHER_STAT_ADV_CAP_1000FDX: 363 *pVal = pUM->curcfg.lnkcfg.param_1000fdx; 364 break; 365 366 #if 0 367 case ETHER_STAT_ADV_CAP_1000HDX: 368 //*pVal = pUM->curcfg.lnkcfg.param_1000hdx; 369 *pVal = 0; 370 break; 371 #endif 372 373 case ETHER_STAT_ADV_CAP_100FDX: 374 *pVal = pUM->curcfg.lnkcfg.param_100fdx; 375 break; 376 377 case ETHER_STAT_ADV_CAP_100HDX: 378 *pVal = pUM->curcfg.lnkcfg.param_100hdx; 379 break; 380 381 case ETHER_STAT_ADV_CAP_10FDX: 382 *pVal = pUM->curcfg.lnkcfg.param_10fdx; 383 break; 384 385 case ETHER_STAT_ADV_CAP_10HDX: 386 *pVal = pUM->curcfg.lnkcfg.param_10hdx; 387 break; 388 389 case ETHER_STAT_ADV_CAP_ASMPAUSE: 390 *pVal = 1; 391 break; 392 393 case ETHER_STAT_ADV_CAP_PAUSE: 394 *pVal = 1; 395 break; 396 397 case ETHER_STAT_ADV_CAP_AUTONEG: 398 *pVal = pUM->curcfg.lnkcfg.link_autoneg; 399 break; 400 401 #if (MAC_VERSION > 1) 402 case ETHER_STAT_ADV_REMFAULT: 403 *pVal = 1; 404 break; 405 #endif 406 407 #if 0 /* LP caps not supported */ 408 #if (MAC_VERSION > 1) 409 case ETHER_STAT_LP_CAP_10GFDX: 410 *pVal = pUM->remote.param_10000fdx; 411 break; 412 #endif 413 414 case ETHER_STAT_LP_CAP_1000FDX: 415 *pVal = pUM->remote.param_1000fdx; 416 break; 417 418 #if 0 419 case ETHER_STAT_LP_CAP_1000HDX: 420 //*pVal = pUM->remote.param_1000hdx; 421 *pVal = 0; 422 break; 423 #endif 424 425 case ETHER_STAT_LP_CAP_100FDX: 426 *pVal = pUM->remote.param_100fdx; 427 break; 428 429 case ETHER_STAT_LP_CAP_100HDX: 430 *pVal = pUM->remote.param_100hdx; 431 break; 432 433 case ETHER_STAT_LP_CAP_10FDX: 434 *pVal = pUM->remote.param_10fdx; 435 break; 436 437 case ETHER_STAT_LP_CAP_10HDX: 438 *pVal = pUM->remote.param_10hdx; 439 break; 440 441 #if 0 442 case ETHER_STAT_LP_CAP_ASMPAUSE: 443 /* XXX implement LP_ASYM_PAUSE stat */ 444 break; 445 446 case ETHER_STAT_LP_CAP_PAUSE: 447 /* XXX implement LP_PAUSE stat */ 448 break; 449 #endif 450 451 case ETHER_STAT_LP_CAP_AUTONEG: 452 *pVal = pUM->remote.link_autoneg; 453 break; 454 455 case ETHER_STAT_LP_REMFAULT: 456 /* XXX implement LP_REMFAULT stat */ 457 break; 458 #endif /* LP caps not supported */ 459 460 #if 0 461 case ETHER_STAT_LINK_ASMPAUSE: 462 /* XXX implement ASMPAUSE stat */ 463 break; 464 465 case ETHER_STAT_LINK_PAUSE: 466 /* XXX implement PAUSE stat */ 467 break; 468 #endif 469 470 case ETHER_STAT_LINK_AUTONEG: 471 *pVal = pUM->curcfg.lnkcfg.link_autoneg; 472 break; 473 474 case ETHER_STAT_LINK_DUPLEX: 475 *pVal = (pUM->props.link_duplex == B_TRUE) ? 476 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; 477 break; 478 479 default: 480 rc = ENOTSUP; 481 } 482 483 BNXE_LOCK_EXIT_GLD(pUM); 484 485 return rc; 486 } 487 488 489 490 /* 491 * This routine is called by GLD to enable device for packet reception and 492 * enable interrupts. 493 */ 494 static int BnxeMacStart(void * pArg) 495 { 496 um_device_t * pUM = (um_device_t *)pArg; 497 498 BNXE_LOCK_ENTER_GLD(pUM); 499 500 if (pUM->plumbed) 501 { 502 /* already started */ 503 BNXE_LOCK_EXIT_GLD(pUM); 504 return EAGAIN; 505 } 506 507 /* Always report the initial link state as unknown. */ 508 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN); 509 510 if (BnxeHwStartL2(pUM)) 511 { 512 BNXE_LOCK_EXIT_GLD(pUM); 513 return EIO; 514 } 515 516 atomic_swap_32(&pUM->plumbed, B_TRUE); 517 518 mutex_enter(&bnxeLoaderMutex); 519 bnxeNumPlumbed++; 520 mutex_exit(&bnxeLoaderMutex); 521 522 BNXE_LOCK_EXIT_GLD(pUM); 523 524 return 0; 525 } 526 527 528 /* 529 * This routine stops packet reception by clearing RX MASK register. Also 530 * interrupts are disabled for this device. 531 */ 532 static void BnxeMacStop(void * pArg) 533 { 534 um_device_t * pUM = (um_device_t *)pArg; 535 536 BNXE_LOCK_ENTER_GLD(pUM); 537 538 if (pUM->plumbed) 539 { 540 atomic_swap_32(&pUM->plumbed, B_FALSE); 541 542 BnxeHwStopL2(pUM); 543 544 /* Report the link state back to unknown. */ 545 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN); 546 547 mutex_enter(&bnxeLoaderMutex); 548 bnxeNumPlumbed--; 549 mutex_exit(&bnxeLoaderMutex); 550 } 551 552 BNXE_LOCK_EXIT_GLD(pUM); 553 } 554 555 /* (flag) TRUE = on, FALSE = off */ 556 static int BnxeMacPromiscuous(void * pArg, 557 boolean_t flag) 558 { 559 um_device_t * pUM = (um_device_t *)pArg; 560 561 BNXE_LOCK_ENTER_GLD(pUM); 562 563 if (!pUM->plumbed) 564 { 565 BNXE_LOCK_EXIT_GLD(pUM); 566 return EAGAIN; 567 } 568 569 if (flag) 570 { 571 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] |= 572 LM_RX_MASK_PROMISCUOUS_MODE; 573 } 574 else 575 { 576 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] &= 577 ~LM_RX_MASK_PROMISCUOUS_MODE; 578 } 579 580 BNXE_LOCK_ENTER_HWINIT(pUM); 581 582 if (BnxeRxMask(pUM, LM_CLI_IDX_NDIS, 583 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS]) < 0) 584 { 585 BNXE_LOCK_EXIT_HWINIT(pUM); 586 BNXE_LOCK_EXIT_GLD(pUM); 587 return ECANCELED; 588 } 589 590 BNXE_LOCK_EXIT_HWINIT(pUM); 591 592 BNXE_LOCK_EXIT_GLD(pUM); 593 594 return 0; 595 } 596 597 598 /* 599 * This function is used to enable or disable multicast packet reception for 600 * particular multicast addresses. 601 * (flag) TRUE = add, FALSE = remove 602 */ 603 static int BnxeMacMulticast(void * pArg, 604 boolean_t flag, 605 const uint8_t * pMcastAddr) 606 { 607 um_device_t * pUM = (um_device_t *)pArg; 608 int rc; 609 610 BNXE_LOCK_ENTER_GLD(pUM); 611 612 if (!pUM->plumbed) 613 { 614 BNXE_LOCK_EXIT_GLD(pUM); 615 return EAGAIN; 616 } 617 618 BNXE_LOCK_ENTER_HWINIT(pUM); 619 rc = BnxeMulticast(pUM, LM_CLI_IDX_NDIS, flag, pMcastAddr, B_TRUE); 620 BNXE_LOCK_EXIT_HWINIT(pUM); 621 622 BNXE_LOCK_EXIT_GLD(pUM); 623 624 return rc; 625 } 626 627 628 #ifdef BNXE_RINGS 629 630 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS) 631 static int BnxeRxRingGroupAddMac(void * groupHandle, 632 const uint8_t * pMacAddr, 633 uint64_t flags) 634 #else 635 static int BnxeRxRingGroupAddMac(void * groupHandle, 636 const uint8_t * pMacAddr) 637 #endif 638 { 639 RxQueueGroup * pRxQGroup = (RxQueueGroup *)groupHandle; 640 um_device_t * pUM = (um_device_t *)pRxQGroup->pUM; 641 //u32_t idx = pRxQGroup->idx; 642 int rc; 643 644 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS) 645 _NOTE(ARGUNUSED(flags)) 646 #endif 647 648 BNXE_LOCK_ENTER_GLD(pUM); 649 650 if (!pUM->plumbed) 651 { 652 BNXE_LOCK_EXIT_GLD(pUM); 653 return ECANCELED; 654 } 655 656 /* Validate MAC address */ 657 if (IS_ETH_MULTICAST(pMacAddr)) 658 { 659 BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as a MAC Address."); 660 BNXE_LOCK_EXIT_GLD(pUM); 661 return EINVAL; 662 } 663 664 if (pUM->ucastTableLen == LM_MAX_UC_TABLE_SIZE) 665 { 666 BNXE_LOCK_EXIT_GLD(pUM); 667 return ENOMEM; 668 } 669 670 BNXE_LOCK_ENTER_HWINIT(pUM); 671 672 COPY_ETH_ADDRESS(pMacAddr, pUM->lm_dev.params.mac_addr); 673 674 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_TRUE, 675 pUM->lm_dev.params.mac_addr); 676 677 BNXE_LOCK_EXIT_HWINIT(pUM); 678 679 if (rc < 0) 680 { 681 BNXE_LOCK_EXIT_GLD(pUM); 682 return ECANCELED; 683 } 684 685 pUM->ucastTableLen++; 686 687 BNXE_LOCK_EXIT_GLD(pUM); 688 return 0; 689 } 690 691 692 static int BnxeRxRingGroupRemMac(void * groupHandle, 693 const uint8_t * pMacAddr) 694 { 695 RxQueueGroup * pRxQGroup = (RxQueueGroup *)groupHandle; 696 um_device_t * pUM = (um_device_t *)pRxQGroup->pUM; 697 //u32_t idx = pRxQGroup->idx; 698 int rc; 699 700 BNXE_LOCK_ENTER_GLD(pUM); 701 702 if (!pUM->plumbed) 703 { 704 BNXE_LOCK_EXIT_GLD(pUM); 705 return ECANCELED; 706 } 707 708 if (pUM->ucastTableLen == 0) 709 { 710 BNXE_LOCK_EXIT_GLD(pUM); 711 return EINVAL; 712 } 713 714 BNXE_LOCK_ENTER_HWINIT(pUM); 715 716 if (!IS_ETH_ADDRESS_EQUAL(pMacAddr, pUM->lm_dev.params.mac_addr)) 717 { 718 BnxeLogWarn(pUM, "Deleting MAC address that doesn't match default"); 719 /* XXX */ 720 } 721 722 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_FALSE, 723 pUM->lm_dev.params.mac_addr); 724 725 memset(pUM->lm_dev.params.mac_addr, 0, sizeof(pUM->lm_dev.params.mac_addr)); 726 727 BNXE_LOCK_EXIT_HWINIT(pUM); 728 729 if (rc < 0) 730 { 731 BNXE_LOCK_EXIT_GLD(pUM); 732 return ECANCELED; 733 } 734 735 pUM->ucastTableLen--; 736 737 BNXE_LOCK_EXIT_GLD(pUM); 738 return 0; 739 } 740 741 742 static mblk_t * BnxeTxRingSend(void * ringHandle, 743 mblk_t * pMblk) 744 { 745 TxQueue * pTxQ = (TxQueue *)ringHandle; 746 um_device_t * pUM = (um_device_t *)pTxQ->pUM; 747 u32_t idx = pTxQ->idx; 748 mblk_t * pNextMblk; 749 int rc; 750 751 while (pMblk) 752 { 753 pNextMblk = pMblk->b_next; 754 pMblk->b_next = NULL; 755 756 rc = BnxeTxSendMblk(pUM, idx, pMblk, 0, 0); 757 758 if (rc == BNXE_TX_GOODXMIT) 759 { 760 pMblk = pNextMblk; 761 continue; 762 } 763 else if (rc == BNXE_TX_DEFERPKT) 764 { 765 pMblk = pNextMblk; 766 } 767 else 768 { 769 pMblk->b_next = pNextMblk; 770 } 771 772 break; 773 } 774 775 return pMblk; 776 } 777 778 #endif /* BNXE_RINGS */ 779 780 781 static int BnxeMacUnicast(void * pArg, 782 const uint8_t * pMacAddr) 783 { 784 um_device_t * pUM = (um_device_t *)pArg; 785 int rc; 786 787 BNXE_LOCK_ENTER_GLD(pUM); 788 789 if (!pUM->plumbed) 790 { 791 memcpy(pUM->gldMac, pMacAddr, ETHERNET_ADDRESS_SIZE); 792 BNXE_LOCK_EXIT_GLD(pUM); 793 return 0; 794 } 795 796 /* Validate MAC address */ 797 if (IS_ETH_MULTICAST(pMacAddr)) 798 { 799 BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as a MAC Address."); 800 BNXE_LOCK_EXIT_GLD(pUM); 801 return EINVAL; 802 } 803 804 BNXE_LOCK_ENTER_HWINIT(pUM); 805 806 COPY_ETH_ADDRESS(pMacAddr, pUM->lm_dev.params.mac_addr); 807 808 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_TRUE, 809 pUM->lm_dev.params.mac_addr); 810 811 BNXE_LOCK_EXIT_HWINIT(pUM); 812 813 if (rc < 0) 814 { 815 BNXE_LOCK_EXIT_GLD(pUM); 816 return EAGAIN; 817 } 818 819 BNXE_LOCK_EXIT_GLD(pUM); 820 return 0; 821 } 822 823 824 static mblk_t * BnxeMacTx(void * pArg, 825 mblk_t * pMblk) 826 { 827 um_device_t * pUM = (um_device_t *)pArg; 828 mblk_t * pNextMblk; 829 int ring, rc; 830 831 BNXE_LOCK_ENTER_GLDTX(pUM, RW_READER); 832 833 if (!pUM->plumbed) 834 { 835 freemsgchain(pMblk); 836 BNXE_LOCK_EXIT_GLDTX(pUM); 837 838 return NULL; 839 } 840 841 while (pMblk) 842 { 843 ring = BnxeRouteTxRing(pUM, pMblk); 844 845 pNextMblk = pMblk->b_next; 846 pMblk->b_next = NULL; 847 848 //rc = BnxeTxSendMblk(pUM, NDIS_CID(&pUM->lm_dev), pMblk, 0, 0); 849 rc = BnxeTxSendMblk(pUM, ring, pMblk, 0, 0); 850 851 if (rc == BNXE_TX_GOODXMIT) 852 { 853 pMblk = pNextMblk; 854 continue; 855 } 856 else if (rc == BNXE_TX_DEFERPKT) 857 { 858 pMblk = pNextMblk; 859 } 860 else 861 { 862 pMblk->b_next = pNextMblk; 863 } 864 865 break; 866 } 867 868 BNXE_LOCK_EXIT_GLDTX(pUM); 869 870 return pMblk; 871 } 872 873 874 #ifdef MC_RESOURCES 875 876 static void BnxeBlank(void * pArg, 877 time_t tick_cnt, 878 uint_t pkt_cnt) 879 { 880 um_device_t * pUM = (um_device_t *)pArg; 881 882 if (!pUM->plumbed) 883 { 884 return; 885 } 886 887 /* XXX 888 * Need to dynamically reconfigure the hw with new interrupt 889 * coalescing params... 890 */ 891 } 892 893 894 static void BnxeMacResources(void * pArg) 895 { 896 um_device_t * pUM = (um_device_t *)pArg; 897 mac_rx_fifo_t mrf; 898 int idx; 899 900 mrf.mrf_type = MAC_RX_FIFO; 901 mrf.mrf_blank = BnxeBlank; 902 mrf.mrf_arg = (void *)pUM; 903 mrf.mrf_normal_blank_time = 25; 904 mrf.mrf_normal_pkt_count = 8; 905 906 LM_FOREACH_RSS_IDX(&pUM->lm_dev, idx) 907 { 908 pUM->macRxResourceHandles[idx] = 909 mac_resource_add(pUM->pMac, (mac_resource_t *)&mrf); 910 } 911 } 912 913 #endif /* MC_RESOURCES */ 914 915 916 static boolean_t BnxeReadReg(um_device_t * pUM, 917 struct bnxe_reg_data * pData) 918 { 919 if (pData->offset & 0x3) 920 { 921 BnxeLogWarn(pUM, "Invalid register offset for GIOCBNXEREG ioctl"); 922 return B_FALSE; 923 } 924 925 LM_BAR_RD32_OFFSET(&pUM->lm_dev, 0, pData->offset, &pData->value); 926 927 return B_TRUE; 928 } 929 930 931 static boolean_t BnxeWriteReg(um_device_t * pUM, 932 struct bnxe_reg_data * pData) 933 { 934 if (pData->offset & 0x3) 935 { 936 BnxeLogWarn(pUM, "Invalid register offset for SIOCBNXEREG ioctl"); 937 return B_FALSE; 938 } 939 940 LM_BAR_WR32_OFFSET(&pUM->lm_dev, 0, pData->offset, pData->value); 941 942 return B_TRUE; 943 } 944 945 946 static boolean_t BnxeReadNvm(um_device_t * pUM, 947 struct bnxe_nvram_data * pData) 948 { 949 if (pData->offset & 0x3) 950 { 951 BnxeLogWarn(pUM, "Invalid register offset for GIOCBNXENVRM ioctl"); 952 return B_FALSE; 953 } 954 955 if (lm_nvram_read(&pUM->lm_dev, 956 pData->offset, 957 pData->value, 958 (pData->num_of_u32 * sizeof(u32_t))) != 959 LM_STATUS_SUCCESS) 960 { 961 return B_FALSE; 962 } 963 964 return B_TRUE; 965 } 966 967 968 static boolean_t BnxeWriteNvm(um_device_t * pUM, 969 struct bnxe_nvram_data * pData) 970 { 971 if (pData->offset & 0x3) 972 { 973 BnxeLogWarn(pUM, "Invalid register offset for SIOCBNXENVRM ioctl"); 974 return B_FALSE; 975 } 976 977 if (lm_nvram_write(&pUM->lm_dev, 978 pData->offset, 979 pData->value, 980 (pData->num_of_u32 * sizeof(u32_t))) != 981 LM_STATUS_SUCCESS) 982 { 983 return B_FALSE; 984 } 985 986 return B_TRUE; 987 } 988 989 990 static boolean_t BnxeReadPciCfg(um_device_t * pUM, 991 struct bnxe_reg_data * pData) 992 { 993 pData->value = pci_config_get32(pUM->pPciCfg, (off_t)pData->offset); 994 return B_TRUE; 995 } 996 997 typedef enum { 998 STATS_SHOW_TYPE_NUM, 999 STATS_SHOW_TYPE_STR, 1000 STATS_SHOW_TYPE_CNT, 1001 STATS_SHOW_TYPE_MAX 1002 } stats_show_type_t; 1003 1004 typedef union _b10_stats_show_data_t 1005 { 1006 u32_t op; /* ioctl sub-commond */ 1007 1008 struct 1009 { 1010 u32_t num; /* return number of stats */ 1011 u32_t len; /* length of each string item */ 1012 } desc; 1013 1014 /* variable length... */ 1015 char str[1]; /* holds names of desc.num stats, each desc.len in length */ 1016 1017 struct 1018 { 1019 b10_l2_chip_statistics_v2_t l2_chip_stats; 1020 b10_l4_chip_statistics_t l4_chip_stats; 1021 b10_l2_driver_statistics_t l2_drv_stats; 1022 b10_l4_driver_statistics_t l4_drv_stats; 1023 } cnt; 1024 } b10_stats_show_data_t; 1025 1026 1027 static boolean_t BnxeStatsShow(um_device_t * pUM, 1028 b10_stats_show_data_t * pStats, 1029 u32_t statsLen) 1030 { 1031 stats_show_type_t op; 1032 const size_t stats_size = sizeof(pStats->cnt); 1033 1034 /* 1035 * All stats names MUST conform to STATS_STR_LEN length!!! 1036 */ 1037 1038 #define STATS_STR_LEN 39 1039 1040 /* XXX 1041 * Note: these strings must be updated whenever any of 1042 * b10_l2_chip_statistics_t, b10_l4_chip_statistics_t, 1043 * b10_l2_driver_statistics_t or b10_l4_driver_statistics_t 1044 * are changed, or additional statistics are required. 1045 */ 1046 1047 const char p_stat_str[] = 1048 1049 // b10_l2_chip_statistics_t 1050 1051 "l2_chip_stats_ver_num\0 " 1052 "IfHCInOctets\0 " 1053 "IfHCInBadOctets\0 " 1054 "IfHCOutOctets\0 " 1055 "IfHCOutBadOctets\0 " 1056 "IfHCOutPkts\0 " 1057 "IfHCInPkts\0 " 1058 "IfHCInUcastPkts\0 " 1059 "IfHCInMulticastPkts\0 " 1060 "IfHCInBroadcastPkts\0 " 1061 "IfHCOutUcastPkts\0 " 1062 "IfHCOutMulticastPkts\0 " 1063 "IfHCOutBroadcastPkts\0 " 1064 "IfHCInUcastOctets\0 " 1065 "IfHCInMulticastOctets\0 " 1066 "IfHCInBroadcastOctets\0 " 1067 "IfHCOutUcastOctets\0 " 1068 "IfHCOutMulticastOctets\0 " 1069 "IfHCOutBroadcastOctets\0 " 1070 "IfHCOutDiscards\0 " 1071 "IfHCInFalseCarrierErrors\0 " 1072 "Dot3StatsInternalMacTransmitErrors\0 " 1073 "Dot3StatsCarrierSenseErrors\0 " 1074 "Dot3StatsFCSErrors\0 " 1075 "Dot3StatsAlignmentErrors\0 " 1076 "Dot3StatsSingleCollisionFrames\0 " 1077 "Dot3StatsMultipleCollisionFrames\0 " 1078 "Dot3StatsDeferredTransmissions\0 " 1079 "Dot3StatsExcessiveCollisions\0 " 1080 "Dot3StatsLateCollisions\0 " 1081 "EtherStatsCollisions\0 " 1082 "EtherStatsFragments\0 " 1083 "EtherStatsJabbers\0 " 1084 "EtherStatsUndersizePkts\0 " 1085 "EtherStatsOverrsizePkts\0 " 1086 "EtherStatsPktsTx64Octets\0 " 1087 "EtherStatsPktsTx65Octetsto127Octets\0 " 1088 "EtherStatsPktsTx128Octetsto255Octets\0 " 1089 "EtherStatsPktsTx256Octetsto511Octets\0 " 1090 "EtherStatsPktsTx512Octetsto1023Octets\0 " 1091 "EtherStatsPktsTx1024Octetsto1522Octets\0" 1092 "EtherStatsPktsTxOver1522Octets\0 " 1093 "XonPauseFramesReceived\0 " 1094 "XoffPauseFramesReceived\0 " 1095 "OutXonSent\0 " 1096 "OutXoffSent\0 " 1097 "FlowControlDone\0 " 1098 "MacControlFramesReceived\0 " 1099 "XoffStateEntered\0 " 1100 "IfInFramesL2FilterDiscards\0 " 1101 "IfInTTL0Discards\0 " 1102 "IfInxxOverflowDiscards\0 " 1103 "IfInMBUFDiscards\0 " 1104 "IfInErrors\0 " 1105 "IfInErrorsOctets\0 " 1106 "IfInNoBrbBuffer\0 " 1107 1108 "Nig_brb_packet\0 " 1109 "Nig_brb_truncate\0 " 1110 "Nig_flow_ctrl_discard\0 " 1111 "Nig_flow_ctrl_octets\0 " 1112 "Nig_flow_ctrl_packet\0 " 1113 "Nig_mng_discard\0 " 1114 "Nig_mng_octet_inp\0 " 1115 "Nig_mng_octet_out\0 " 1116 "Nig_mng_packet_inp\0 " 1117 "Nig_mng_packet_out\0 " 1118 "Nig_pbf_octets\0 " 1119 "Nig_pbf_packet\0 " 1120 "Nig_safc_inp\0 " 1121 1122 "Tx_Lpi_Count\0 " // This counter counts the number of timers the debounced version of EEE link idle is asserted 1123 1124 // b10_l4_chip_statistics_t 1125 1126 "l4_chip_stats_ver_num\0 " 1127 "NoTxCqes\0 " 1128 "InTCP4Segments\0 " 1129 "OutTCP4Segments\0 " 1130 "RetransmittedTCP4Segments\0 " 1131 "InTCP4Errors\0 " 1132 "InIP4Receives\0 " 1133 "InIP4HeaderErrors\0 " 1134 "InIP4Discards\0 " 1135 "InIP4Delivers\0 " 1136 "InIP4Octets\0 " 1137 "OutIP4Octets\0 " 1138 "InIP4TruncatedPackets\0 " 1139 "InTCP6Segments\0 " 1140 "OutTCP6Segments\0 " 1141 "RetransmittedTCP6Segments\0 " 1142 "InTCP6Errors\0 " 1143 "InIP6Receives\0 " 1144 "InIP6HeaderErrors\0 " 1145 "InIP6Discards\0 " 1146 "InIP6Delivers\0 " 1147 "InIP6Octets\0 " 1148 "OutIP6Octets\0 " 1149 "InIP6TruncatedPackets\0 " 1150 1151 // b10_l2_driver_statistics_t 1152 1153 "l2_driver_stats_ver_num\0 " 1154 "RxIPv4FragCount\0 " 1155 "RxIpCsErrorCount\0 " 1156 "RxTcpCsErrorCount\0 " 1157 "RxLlcSnapCount\0 " 1158 "RxPhyErrorCount\0 " 1159 "RxIpv6ExtCount\0 " 1160 "TxNoL2Bd\0 " 1161 "TxNoSqWqe\0 " 1162 "TxL2AssemblyBufUse\0 " 1163 1164 // b10_l4_driver_statistics_t 1165 1166 "l4_driver_stats_ver_num\0 " 1167 "CurrentlyIpv4Established\0 " 1168 "OutIpv4Resets\0 " 1169 "OutIpv4Fin\0 " 1170 "InIpv4Reset\0 " 1171 "InIpv4Fin\0 " 1172 "CurrentlyIpv6Established\0 " 1173 "OutIpv6Resets\0 " 1174 "OutIpv6Fin\0 " 1175 "InIpv6Reset\0 " 1176 "InIpv6Fin\0 " 1177 "RxIndicateReturnPendingCnt\0 " 1178 "RxIndicateReturnDoneCnt\0 " 1179 "RxActiveGenBufCnt\0 " 1180 "TxNoL4Bd\0 " 1181 "TxL4AssemblyBufUse\0 " 1182 1183 ; 1184 1185 ASSERT_STATIC((sizeof(p_stat_str) / STATS_STR_LEN) == 1186 (stats_size / sizeof(u64_t))); 1187 1188 op = *((stats_show_type_t *)pStats); 1189 1190 switch (op) 1191 { 1192 case STATS_SHOW_TYPE_NUM: 1193 1194 if (statsLen < sizeof(pStats->desc)) 1195 { 1196 return B_FALSE; 1197 } 1198 1199 pStats->desc.num = (stats_size / sizeof(u64_t)); 1200 pStats->desc.len = STATS_STR_LEN; 1201 1202 return B_TRUE; 1203 1204 case STATS_SHOW_TYPE_STR: 1205 1206 if (statsLen != sizeof(p_stat_str)) 1207 { 1208 return B_FALSE; 1209 } 1210 1211 memcpy(pStats->str, p_stat_str, sizeof(p_stat_str)); 1212 1213 return B_TRUE; 1214 1215 case STATS_SHOW_TYPE_CNT: 1216 1217 if (statsLen != stats_size) 1218 { 1219 return B_FALSE; 1220 } 1221 1222 lm_stats_get_l2_chip_stats(&pUM->lm_dev, 1223 &pStats->cnt.l2_chip_stats, 1224 L2_CHIP_STATISTICS_VER_NUM_2); 1225 1226 lm_stats_get_l4_chip_stats(&pUM->lm_dev, 1227 &pStats->cnt.l4_chip_stats); 1228 1229 lm_stats_get_l2_driver_stats(&pUM->lm_dev 1230 ,&pStats->cnt.l2_drv_stats); 1231 1232 lm_stats_get_l4_driver_stats(&pUM->lm_dev, 1233 &pStats->cnt.l4_drv_stats); 1234 1235 return B_TRUE; 1236 1237 default: 1238 1239 return B_FALSE; 1240 } 1241 } 1242 1243 static void BnxeMacIoctl(void * pArg, 1244 queue_t * pQ, 1245 mblk_t * pMblk) 1246 { 1247 um_device_t * pUM = (um_device_t *)pArg; 1248 struct iocblk * pIoctl; 1249 int rc; 1250 1251 if ((pQ == NULL) || (pMblk == NULL)) 1252 { 1253 return; 1254 } 1255 1256 if (pMblk->b_datap->db_type != M_IOCTL) 1257 { 1258 miocnak(pQ, pMblk, 0, EINVAL); 1259 return; 1260 } 1261 1262 pIoctl = (struct iocblk *)pMblk->b_rptr; 1263 1264 BNXE_LOCK_ENTER_GLD(pUM); 1265 1266 switch (pIoctl->ioc_cmd) 1267 { 1268 case GIOCBNXELLDP: 1269 1270 if ((pIoctl->ioc_count != sizeof(b10_lldp_params_get_t)) || 1271 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) || 1272 (miocpullup(pMblk, sizeof(b10_lldp_params_get_t)) < 0)) 1273 { 1274 miocnak(pQ, pMblk, 0, EINVAL); 1275 break; 1276 } 1277 1278 if (((b10_lldp_params_get_t *)pMblk->b_cont->b_rptr)->ver_num != 1279 LLDP_PARAMS_VER_NUM) 1280 { 1281 miocnak(pQ, pMblk, 0, EINVAL); 1282 break; 1283 } 1284 1285 if (lm_dcbx_lldp_read_params(&pUM->lm_dev, 1286 (b10_lldp_params_get_t *)pMblk->b_cont->b_rptr) != 1287 LM_STATUS_SUCCESS) 1288 { 1289 miocnak(pQ, pMblk, 0, 1290 (!IS_DCB_ENABLED(&pUM->lm_dev)) ? ENOTSUP : EINVAL); 1291 break; 1292 } 1293 1294 miocack(pQ, pMblk, pIoctl->ioc_count, 0); 1295 break; 1296 1297 case GIOCBNXEDCBX: 1298 1299 if ((pIoctl->ioc_count != sizeof(b10_dcbx_params_get_t)) || 1300 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) || 1301 (miocpullup(pMblk, sizeof(b10_dcbx_params_get_t)) < 0)) 1302 { 1303 miocnak(pQ, pMblk, 0, EINVAL); 1304 break; 1305 } 1306 1307 if (((b10_dcbx_params_get_t *)pMblk->b_cont->b_rptr)->ver_num != 1308 DCBX_PARAMS_VER_NUM) 1309 { 1310 miocnak(pQ, pMblk, 0, EINVAL); 1311 break; 1312 } 1313 1314 if (lm_dcbx_read_params(&pUM->lm_dev, 1315 (b10_dcbx_params_get_t *)pMblk->b_cont->b_rptr) != 1316 LM_STATUS_SUCCESS) 1317 { 1318 miocnak(pQ, pMblk, 0, 1319 (!IS_DCB_ENABLED(&pUM->lm_dev)) ? ENOTSUP : EINVAL); 1320 break; 1321 } 1322 1323 miocack(pQ, pMblk, pIoctl->ioc_count, 0); 1324 break; 1325 1326 case SIOCBNXEDCBX: 1327 1328 /* XXX */ 1329 miocnak(pQ, pMblk, 0, EINVAL); 1330 break; 1331 1332 case GIOCBNXEREG: 1333 1334 if ((pIoctl->ioc_count != sizeof(struct bnxe_reg_data)) || 1335 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) || 1336 (miocpullup(pMblk, sizeof(struct bnxe_reg_data)) < 0)) 1337 { 1338 miocnak(pQ, pMblk, 0, EINVAL); 1339 break; 1340 } 1341 1342 if (!BnxeReadReg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr)) 1343 { 1344 miocnak(pQ, pMblk, 0, EINVAL); 1345 } 1346 else 1347 { 1348 miocack(pQ, pMblk, pIoctl->ioc_count, 0); 1349 } 1350 1351 break; 1352 1353 case SIOCBNXEREG: 1354 1355 if ((pIoctl->ioc_count != sizeof(struct bnxe_reg_data)) || 1356 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) || 1357 (miocpullup(pMblk, sizeof(struct bnxe_reg_data)) < 0)) 1358 { 1359 miocnak(pQ, pMblk, 0, EINVAL); 1360 break; 1361 } 1362 1363 if (!BnxeWriteReg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr)) 1364 { 1365 miocnak(pQ, pMblk, 0, EINVAL); 1366 } 1367 else 1368 { 1369 miocack(pQ, pMblk, pIoctl->ioc_count, 0); 1370 } 1371 1372 break; 1373 1374 case GIOCBNXENVRM: 1375 1376 if ((pIoctl->ioc_count < sizeof(struct bnxe_nvram_data)) || 1377 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) || 1378 (miocpullup(pMblk, pIoctl->ioc_count) < 0)) 1379 { 1380 miocnak(pQ, pMblk, 0, EINVAL); 1381 break; 1382 } 1383 1384 if (!BnxeReadNvm(pUM, (struct bnxe_nvram_data *)pMblk->b_cont->b_rptr)) 1385 { 1386 miocnak(pQ, pMblk, 0, EINVAL); 1387 } 1388 else 1389 { 1390 miocack(pQ, pMblk, pIoctl->ioc_count, 0); 1391 } 1392 1393 break; 1394 1395 case SIOCBNXENVRM: 1396 1397 if ((pIoctl->ioc_count < sizeof(struct bnxe_nvram_data)) || 1398 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) || 1399 (miocpullup(pMblk, pIoctl->ioc_count) < 0)) 1400 { 1401 miocnak(pQ, pMblk, 0, EINVAL); 1402 break; 1403 } 1404 1405 if (!BnxeWriteNvm(pUM, (struct bnxe_nvram_data *)pMblk->b_cont->b_rptr)) 1406 { 1407 miocnak(pQ, pMblk, 0, EINVAL); 1408 } 1409 else 1410 { 1411 miocack(pQ, pMblk, pIoctl->ioc_count, 0); 1412 } 1413 1414 break; 1415 1416 case GIOCBNXEPCI: 1417 1418 if ((pIoctl->ioc_count != sizeof(struct bnxe_reg_data)) || 1419 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) || 1420 (miocpullup(pMblk, sizeof(struct bnxe_reg_data)) < 0)) 1421 { 1422 miocnak(pQ, pMblk, 0, EINVAL); 1423 break; 1424 } 1425 1426 if (!BnxeReadPciCfg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr)) 1427 { 1428 miocnak(pQ, pMblk, 0, EINVAL); 1429 } 1430 else 1431 { 1432 miocack(pQ, pMblk, pIoctl->ioc_count, 0); 1433 } 1434 1435 break; 1436 1437 case GIOCBNXESTATS: 1438 1439 /* min size = sizeof(op) in b10_stats_show_data_t */ 1440 if ((pIoctl->ioc_count < sizeof(u32_t)) || 1441 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) || 1442 (miocpullup(pMblk, pIoctl->ioc_count) < 0)) 1443 { 1444 miocnak(pQ, pMblk, 0, EINVAL); 1445 break; 1446 } 1447 1448 if (!BnxeStatsShow(pUM, 1449 (b10_stats_show_data_t *)pMblk->b_cont->b_rptr, 1450 pIoctl->ioc_count)) 1451 { 1452 miocnak(pQ, pMblk, 0, EINVAL); 1453 } 1454 else 1455 { 1456 miocack(pQ, pMblk, pIoctl->ioc_count, 0); 1457 } 1458 1459 break; 1460 1461 default: 1462 1463 miocnak(pQ, pMblk, 0, EINVAL); 1464 break; 1465 } 1466 1467 BNXE_LOCK_EXIT_GLD(pUM); 1468 } 1469 1470 1471 #ifdef BNXE_RINGS 1472 1473 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS) 1474 static mblk_t * BnxeRxRingPoll(void * ringHandle, 1475 int numBytes, 1476 int numPkts) 1477 #else 1478 static mblk_t * BnxeRxRingPoll(void * ringHandle, 1479 int numBytes) 1480 #endif 1481 { 1482 RxQueue * pRxQ = (RxQueue *)ringHandle; 1483 um_device_t * pUM = (um_device_t *)pRxQ->pUM; 1484 u32_t idx = pRxQ->idx; 1485 mblk_t * pMblk = NULL; 1486 boolean_t pktsRxed = 0; 1487 boolean_t pktsTxed = 0; 1488 1489 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS) 1490 _NOTE(ARGUNUSED(numPkts)) 1491 #endif 1492 1493 if (numBytes <= 0) 1494 { 1495 return NULL; 1496 } 1497 1498 if (pRxQ->inPollMode == B_FALSE) 1499 { 1500 BnxeLogWarn(pUM, "Polling on ring %d when NOT in poll mode!", idx); 1501 return NULL; 1502 } 1503 1504 BNXE_LOCK_ENTER_INTR(pUM, idx); 1505 1506 pRxQ->pollCnt++; 1507 1508 BnxePollRxRing(pUM, idx, &pktsRxed, &pktsTxed); 1509 1510 if (pktsTxed) BnxeTxRingProcess(pUM, idx); 1511 if (pktsRxed) pMblk = BnxeRxRingProcess(pUM, idx, TRUE, numBytes); 1512 1513 /* 1514 * This is here for the off chance that all rings are in polling 1515 * mode and the default interrupt hasn't fired recently to handle 1516 * the sq. 1517 */ 1518 lm_sq_post_pending(&pUM->lm_dev); 1519 1520 BNXE_LOCK_EXIT_INTR(pUM, idx); 1521 1522 return pMblk; 1523 } 1524 1525 1526 static int BnxeRxRingStart(mac_ring_driver_t ringHandle 1527 #if defined(__S11) || defined(__S12) 1528 , uint64_t genNumber 1529 #endif 1530 ) 1531 { 1532 RxQueue * pRxQ = (RxQueue *)ringHandle; 1533 um_device_t * pUM = (um_device_t *)pRxQ->pUM; 1534 u32_t idx = pRxQ->idx; 1535 1536 BnxeLogDbg(pUM, "Starting Rx Ring %d", idx); 1537 1538 BNXE_LOCK_ENTER_RX(pUM, idx); 1539 #if defined(__S11) || defined(__S12) 1540 pRxQ->genNumber = genNumber; 1541 #endif 1542 pRxQ->inPollMode = B_FALSE; 1543 pRxQ->intrDisableCnt = 0; 1544 pRxQ->intrEnableCnt = 0; 1545 pRxQ->pollCnt = 0; 1546 BNXE_LOCK_EXIT_RX(pUM, idx); 1547 1548 return 0; 1549 } 1550 1551 1552 #if defined(__S11) || defined(__S12) 1553 1554 static int BnxeRingStat(mac_ring_driver_t ringHandle, 1555 uint_t stat, 1556 uint64_t * val) 1557 { 1558 RxQueue * pRxQ = (RxQueue *)ringHandle; 1559 um_device_t * pUM = (um_device_t *)pRxQ->pUM; 1560 1561 switch (stat) 1562 { 1563 case MAC_STAT_OERRORS: 1564 case MAC_STAT_OBYTES: 1565 case MAC_STAT_OPACKETS: 1566 case MAC_STAT_IERRORS: 1567 case MAC_STAT_RBYTES: /* MAC_STAT_IBYTES */ 1568 case MAC_STAT_IPACKETS: 1569 default: 1570 return ENOTSUP; 1571 } 1572 1573 return 0; 1574 } 1575 1576 #endif /* __S11 or __S12 */ 1577 1578 1579 #if defined(__S11) || defined(__S12) 1580 static int BnxeRxRingIntrEnable(mac_ring_driver_t ringHandle) 1581 #else 1582 static int BnxeRxRingIntrEnable(mac_intr_handle_t ringHandle) 1583 #endif 1584 { 1585 RxQueue * pRxQ = (RxQueue *)ringHandle; 1586 um_device_t * pUM = (um_device_t *)pRxQ->pUM; 1587 1588 BnxeLogDbg(pUM, "Enabling Interrupt for Rx Ring %d", pRxQ->idx); 1589 1590 /* polling not allowed on LM_NON_RSS_SB when overlapped with FCoE */ 1591 if ((pRxQ->idx == LM_NON_RSS_SB(&pUM->lm_dev)) && 1592 CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE) && 1593 (pUM->rssIntr.intrCount == LM_MAX_RSS_CHAINS(&pUM->lm_dev))) 1594 { 1595 return 0; /* ok, already enabled */ 1596 } 1597 1598 BnxeIntrIguSbEnable(pUM, pRxQ->idx, B_FALSE); 1599 1600 return 0; 1601 } 1602 1603 1604 #if defined(__S11) || defined(__S12) 1605 static int BnxeRxRingIntrDisable(mac_ring_driver_t ringHandle) 1606 #else 1607 static int BnxeRxRingIntrDisable(mac_intr_handle_t ringHandle) 1608 #endif 1609 { 1610 RxQueue * pRxQ = (RxQueue *)ringHandle; 1611 um_device_t * pUM = (um_device_t *)pRxQ->pUM; 1612 1613 BnxeLogDbg(pUM, "Disabling Interrupt for Rx Ring %d", pRxQ->idx); 1614 1615 /* polling not allowed on LM_NON_RSS_SB when overlapped with FCoE */ 1616 if ((pRxQ->idx == LM_NON_RSS_SB(&pUM->lm_dev)) && 1617 CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE) && 1618 (pUM->rssIntr.intrCount == LM_MAX_RSS_CHAINS(&pUM->lm_dev))) 1619 { 1620 return -1; /* NO, keep enabled! */ 1621 } 1622 1623 BnxeIntrIguSbDisable(pUM, pRxQ->idx, B_FALSE); 1624 1625 return 0; 1626 } 1627 1628 1629 /* callback function for MAC layer to register rings */ 1630 static void BnxeFillRing(void * arg, 1631 mac_ring_type_t ringType, 1632 const int ringGroupIndex, 1633 const int ringIndex, 1634 mac_ring_info_t * pRingInfo, 1635 mac_ring_handle_t ringHandle) 1636 { 1637 um_device_t * pUM = (um_device_t *)arg; 1638 RxQueue * pRxQ; 1639 TxQueue * pTxQ; 1640 1641 switch (ringType) 1642 { 1643 case MAC_RING_TYPE_RX: 1644 1645 BnxeLogInfo(pUM, "Initializing Rx Ring %d (Ring Group %d)", 1646 ringIndex, ringGroupIndex); 1647 1648 ASSERT(ringGroupIndex == 0); 1649 ASSERT(ringIndex < pUM->devParams.numRings); 1650 1651 pRxQ = &pUM->rxq[ringIndex]; 1652 pRxQ->ringHandle = ringHandle; 1653 1654 pRingInfo->mri_driver = (mac_ring_driver_t)pRxQ; 1655 pRingInfo->mri_start = BnxeRxRingStart; 1656 pRingInfo->mri_stop = NULL; 1657 #if defined(__S11) || defined(__S12) 1658 pRingInfo->mri_stat = BnxeRingStat; 1659 #endif 1660 pRingInfo->mri_poll = BnxeRxRingPoll; 1661 1662 #if !(defined(__S11) || defined(__S12)) 1663 pRingInfo->mri_intr.mi_handle = (mac_intr_handle_t)pRxQ; 1664 #endif 1665 pRingInfo->mri_intr.mi_enable = (mac_intr_enable_t)BnxeRxRingIntrEnable; 1666 pRingInfo->mri_intr.mi_disable = (mac_intr_disable_t)BnxeRxRingIntrDisable; 1667 1668 break; 1669 1670 case MAC_RING_TYPE_TX: 1671 1672 BnxeLogInfo(pUM, "Initializing Tx Ring %d (Ring Group %d)", 1673 ringIndex, ringGroupIndex); 1674 1675 ASSERT(ringGroupIndex == 0); 1676 ASSERT(ringIndex < pUM->devParams.numRings); 1677 1678 pTxQ = &pUM->txq[ringIndex]; 1679 pTxQ->ringHandle = ringHandle; 1680 1681 pRingInfo->mri_driver = (mac_ring_driver_t)pTxQ; 1682 pRingInfo->mri_start = NULL; 1683 pRingInfo->mri_stop = NULL; 1684 #if defined(__S11) || defined(__S12) 1685 pRingInfo->mri_stat = BnxeRingStat; 1686 #endif 1687 pRingInfo->mri_tx = (mac_ring_send_t)BnxeTxRingSend; 1688 1689 break; 1690 1691 default: 1692 break; 1693 } 1694 } 1695 1696 1697 /* callback function for MAC layer to register groups */ 1698 static void BnxeFillGroup(void * arg, 1699 mac_ring_type_t ringType, 1700 const int ringGroupIndex, 1701 mac_group_info_t * pGroupInfo, 1702 mac_group_handle_t groupHandle) 1703 { 1704 um_device_t * pUM = (um_device_t *)arg; 1705 RxQueueGroup * pRxQGroup; 1706 1707 switch (ringType) 1708 { 1709 case MAC_RING_TYPE_RX: 1710 1711 BnxeLogInfo(pUM, "Initializing Rx Group %d", ringGroupIndex); 1712 1713 pRxQGroup = &pUM->rxqGroup[ringGroupIndex]; 1714 pRxQGroup->groupHandle = groupHandle; 1715 1716 pGroupInfo->mgi_driver = (mac_group_driver_t)pRxQGroup; 1717 pGroupInfo->mgi_start = NULL; 1718 pGroupInfo->mgi_stop = NULL; 1719 pGroupInfo->mgi_addmac = BnxeRxRingGroupAddMac; 1720 pGroupInfo->mgi_remmac = BnxeRxRingGroupRemMac; 1721 pGroupInfo->mgi_count = (pUM->devParams.numRings / 1722 USER_OPTION_RX_RING_GROUPS_DEFAULT); 1723 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS) 1724 pGroupInfo->mgi_flags = MAC_GROUP_DEFAULT; 1725 #endif 1726 1727 break; 1728 1729 case MAC_RING_TYPE_TX: 1730 default: 1731 break; 1732 } 1733 } 1734 1735 #endif /* BNXE_RINGS */ 1736 1737 1738 static boolean_t BnxeMacGetCapability(void * pArg, 1739 mac_capab_t capability, 1740 void * pCapabilityData) 1741 { 1742 um_device_t * pUM = (um_device_t *)pArg; 1743 mac_capab_lso_t * pCapLSO; 1744 mac_capab_rings_t * pCapRings; 1745 1746 switch (capability) 1747 { 1748 case MAC_CAPAB_HCKSUM: 1749 1750 *((u32_t *)pCapabilityData) = 0; 1751 1752 if (pUM->devParams.enabled_oflds & 1753 (LM_OFFLOAD_TX_IP_CKSUM | LM_OFFLOAD_RX_IP_CKSUM)) 1754 { 1755 *((u32_t *)pCapabilityData) |= HCKSUM_IPHDRCKSUM; 1756 } 1757 1758 if (pUM->devParams.enabled_oflds & 1759 (LM_OFFLOAD_TX_TCP_CKSUM | LM_OFFLOAD_TX_UDP_CKSUM | 1760 LM_OFFLOAD_RX_TCP_CKSUM | LM_OFFLOAD_RX_UDP_CKSUM)) 1761 { 1762 *((u32_t *)pCapabilityData) |= HCKSUM_INET_PARTIAL; 1763 } 1764 1765 break; 1766 1767 case MAC_CAPAB_LSO: 1768 1769 pCapLSO = (mac_capab_lso_t *)pCapabilityData; 1770 1771 if (pUM->devParams.lsoEnable) 1772 { 1773 pCapLSO->lso_flags = LSO_TX_BASIC_TCP_IPV4; 1774 pCapLSO->lso_basic_tcp_ipv4.lso_max = BNXE_LSO_MAXLEN; 1775 break; 1776 } 1777 1778 return B_FALSE; 1779 1780 #ifdef BNXE_RINGS 1781 1782 case MAC_CAPAB_RINGS: 1783 1784 if (!pUM->devParams.numRings) 1785 { 1786 return B_FALSE; 1787 } 1788 1789 pCapRings = (mac_capab_rings_t *)pCapabilityData; 1790 1791 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS) 1792 pCapRings->mr_version = MAC_RINGS_VERSION_1; 1793 pCapRings->mr_flags = MAC_RINGS_FLAGS_NONE; 1794 #endif 1795 pCapRings->mr_group_type = MAC_GROUP_TYPE_STATIC; 1796 pCapRings->mr_rnum = pUM->devParams.numRings; 1797 pCapRings->mr_rget = BnxeFillRing; 1798 pCapRings->mr_gaddring = NULL; 1799 pCapRings->mr_gremring = NULL; 1800 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS) 1801 pCapRings->mr_ggetringtc = NULL; 1802 #endif 1803 1804 switch (pCapRings->mr_type) 1805 { 1806 case MAC_RING_TYPE_RX: 1807 1808 pCapRings->mr_gnum = USER_OPTION_RX_RING_GROUPS_DEFAULT; 1809 pCapRings->mr_gget = BnxeFillGroup; 1810 break; 1811 1812 case MAC_RING_TYPE_TX: 1813 1814 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS) 1815 pCapRings->mr_gnum = 1; 1816 #else 1817 pCapRings->mr_gnum = 0; 1818 #endif 1819 pCapRings->mr_gget = NULL; 1820 break; 1821 1822 default: 1823 1824 return B_FALSE; 1825 } 1826 1827 break; 1828 1829 #endif /* BNXE_RINGS */ 1830 1831 #if !(defined(__S11) || defined(__S12)) 1832 1833 case MAC_CAPAB_POLL: 1834 1835 /* 1836 * There's nothing for us to fill in, simply returning B_TRUE stating 1837 * that we support polling is sufficient. 1838 */ 1839 break; 1840 1841 #endif /* not __S11 or __S12 */ 1842 1843 #if defined(ILLUMOS) 1844 case MAC_CAPAB_TRANSCEIVER: 1845 return bnxe_fill_transceiver(pUM, pCapabilityData); 1846 #endif 1847 1848 default: 1849 1850 return B_FALSE; 1851 } 1852 1853 return B_TRUE; 1854 } 1855 1856 1857 #ifdef MC_SETPROP 1858 1859 static int BnxeSetPrivateProperty(um_device_t * pUM, 1860 const char * pr_name, 1861 uint_t pr_valsize, 1862 const void * pr_val) 1863 { 1864 int err = 0; 1865 long result; 1866 1867 if (strcmp(pr_name, "_en_2500fdx_cap") == 0) 1868 { 1869 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 1870 { 1871 return EINVAL; 1872 } 1873 1874 if ((result > 1) || (result < 0)) 1875 { 1876 return EINVAL; 1877 } 1878 1879 pUM->hwinit.lnkcfg.param_2500fdx = (uint32_t)result; 1880 pUM->curcfg.lnkcfg.param_2500fdx = (uint32_t)result; 1881 if (pUM->plumbed) BnxeUpdatePhy(pUM); 1882 } 1883 else if (strcmp(pr_name, "_en_txpause_cap") == 0) 1884 { 1885 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 1886 { 1887 return EINVAL; 1888 } 1889 1890 if ((result > 1) || (result < 0)) 1891 { 1892 return EINVAL; 1893 } 1894 1895 pUM->hwinit.lnkcfg.param_txpause = (uint32_t)result; 1896 pUM->curcfg.lnkcfg.param_txpause = (uint32_t)result; 1897 if (pUM->plumbed) BnxeUpdatePhy(pUM); 1898 } 1899 else if (strcmp(pr_name, "_en_rxpause_cap") == 0) 1900 { 1901 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 1902 { 1903 return EINVAL; 1904 } 1905 1906 if ((result > 1) || (result < 0)) 1907 { 1908 return EINVAL; 1909 } 1910 1911 pUM->hwinit.lnkcfg.param_rxpause = (uint32_t)result; 1912 pUM->curcfg.lnkcfg.param_rxpause = (uint32_t)result; 1913 if (pUM->plumbed) BnxeUpdatePhy(pUM); 1914 } 1915 else if (strcmp(pr_name, "_autoneg_flow") == 0) 1916 { 1917 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 1918 { 1919 return EINVAL; 1920 } 1921 1922 if ((result > 1) || (result < 0)) 1923 { 1924 return EINVAL; 1925 } 1926 1927 pUM->hwinit.flow_autoneg = (uint32_t)result; 1928 pUM->curcfg.flow_autoneg = (uint32_t)result; 1929 if (pUM->plumbed) BnxeUpdatePhy(pUM); 1930 } 1931 else if (strcmp(pr_name, "_checksum") == 0) 1932 { 1933 if (pUM->plumbed) 1934 { 1935 return EBUSY; 1936 } 1937 1938 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 1939 { 1940 return EINVAL; 1941 } 1942 1943 switch (result) 1944 { 1945 case USER_OPTION_CKSUM_NONE: 1946 1947 pUM->devParams.enabled_oflds = LM_OFFLOAD_NONE; 1948 break; 1949 1950 case USER_OPTION_CKSUM_L3: 1951 1952 pUM->devParams.enabled_oflds = (LM_OFFLOAD_TX_IP_CKSUM | 1953 LM_OFFLOAD_RX_IP_CKSUM); 1954 break; 1955 1956 case USER_OPTION_CKSUM_L3_L4: 1957 1958 pUM->devParams.enabled_oflds = (LM_OFFLOAD_TX_IP_CKSUM | 1959 LM_OFFLOAD_RX_IP_CKSUM | 1960 LM_OFFLOAD_TX_TCP_CKSUM | 1961 LM_OFFLOAD_RX_TCP_CKSUM | 1962 LM_OFFLOAD_TX_UDP_CKSUM | 1963 LM_OFFLOAD_RX_UDP_CKSUM); 1964 break; 1965 1966 default: 1967 1968 return EINVAL; 1969 } 1970 1971 pUM->devParams.checksum = (uint32_t)result; 1972 } 1973 else if (strcmp(pr_name, "_tx_ring_policy") == 0) 1974 { 1975 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 1976 { 1977 return EINVAL; 1978 } 1979 1980 switch (result) 1981 { 1982 case BNXE_ROUTE_RING_NONE: 1983 case BNXE_ROUTE_RING_TCPUDP: 1984 case BNXE_ROUTE_RING_DEST_MAC: 1985 case BNXE_ROUTE_RING_MSG_PRIO: 1986 1987 break; 1988 1989 default: 1990 1991 return EINVAL; 1992 } 1993 1994 pUM->devParams.routeTxRingPolicy = (uint32_t)result; 1995 } 1996 else if (strcmp(pr_name, "_num_rings") == 0) 1997 { 1998 if (pUM->plumbed) 1999 { 2000 return EBUSY; 2001 } 2002 2003 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2004 { 2005 return EINVAL; 2006 } 2007 2008 if ((result < USER_OPTION_NUM_RINGS_MIN) || 2009 (result > USER_OPTION_NUM_RINGS_MAX)) 2010 { 2011 return EINVAL; 2012 } 2013 2014 pUM->devParams.numRings = (uint32_t)result; 2015 } 2016 else if (strcmp(pr_name, "_rx_descs") == 0) 2017 { 2018 if (pUM->plumbed) 2019 { 2020 return EBUSY; 2021 } 2022 2023 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2024 { 2025 return EINVAL; 2026 } 2027 2028 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX)) 2029 { 2030 return EINVAL; 2031 } 2032 2033 pUM->devParams.numRxDesc[LM_CLI_IDX_NDIS] = (uint32_t)result; 2034 } 2035 else if (strcmp(pr_name, "_rx_free_reclaim") == 0) 2036 { 2037 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2038 { 2039 return EINVAL; 2040 } 2041 2042 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX)) 2043 { 2044 return EINVAL; 2045 } 2046 2047 pUM->devParams.maxRxFree = (uint32_t)result; 2048 } 2049 else if (strcmp(pr_name, "_tx_descs") == 0) 2050 { 2051 if (pUM->plumbed) 2052 { 2053 return EBUSY; 2054 } 2055 2056 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2057 { 2058 return EINVAL; 2059 } 2060 2061 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX)) 2062 { 2063 return EINVAL; 2064 } 2065 2066 pUM->devParams.numTxDesc[LM_CLI_IDX_NDIS] = (uint32_t)result; 2067 } 2068 else if (strcmp(pr_name, "_tx_free_reclaim") == 0) 2069 { 2070 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2071 { 2072 return EINVAL; 2073 } 2074 2075 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX)) 2076 { 2077 return EINVAL; 2078 } 2079 2080 pUM->devParams.maxTxFree = (uint32_t)result; 2081 } 2082 else if (strcmp(pr_name, "_rx_copy_threshold") == 0) 2083 { 2084 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2085 { 2086 return EINVAL; 2087 } 2088 2089 pUM->devParams.rxCopyThreshold = (uint32_t)result; 2090 } 2091 else if (strcmp(pr_name, "_tx_copy_threshold") == 0) 2092 { 2093 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2094 { 2095 return EINVAL; 2096 } 2097 2098 pUM->devParams.txCopyThreshold = (uint32_t)result; 2099 } 2100 else if (strcmp(pr_name, "_interrupt_coalesce") == 0) 2101 { 2102 if (pUM->plumbed) 2103 { 2104 return EBUSY; 2105 } 2106 2107 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2108 { 2109 return EINVAL; 2110 } 2111 2112 if ((result > 1) || (result < 0)) 2113 { 2114 return EINVAL; 2115 } 2116 2117 pUM->devParams.intrCoalesce = (uint32_t)result; 2118 } 2119 else if (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0) 2120 { 2121 if (pUM->plumbed) 2122 { 2123 return EBUSY; 2124 } 2125 2126 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2127 { 2128 return EINVAL; 2129 } 2130 2131 if ((result < USER_OPTION_INTR_COALESCE_MIN) || 2132 (result < USER_OPTION_INTR_COALESCE_MAX)) 2133 { 2134 return EINVAL; 2135 } 2136 2137 pUM->devParams.intrRxPerSec = (uint32_t)(1000000 / result); 2138 } 2139 else if (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0) 2140 { 2141 if (pUM->plumbed) 2142 { 2143 return EBUSY; 2144 } 2145 2146 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2147 { 2148 return EINVAL; 2149 } 2150 2151 if ((result < USER_OPTION_INTR_COALESCE_MIN) || 2152 (result < USER_OPTION_INTR_COALESCE_MAX)) 2153 { 2154 return EINVAL; 2155 } 2156 2157 pUM->devParams.intrTxPerSec = (uint32_t)(1000000 / result); 2158 } 2159 else if (strcmp(pr_name, "_disable_msix") == 0) 2160 { 2161 if (pUM->plumbed) 2162 { 2163 return EBUSY; 2164 } 2165 2166 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2167 { 2168 return EINVAL; 2169 } 2170 2171 if ((result > 1) || (result < 0)) 2172 { 2173 return EINVAL; 2174 } 2175 2176 pUM->devParams.disableMsix = (uint32_t)result; 2177 } 2178 else if (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0) 2179 { 2180 if (pUM->plumbed) 2181 { 2182 return EBUSY; 2183 } 2184 2185 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2186 { 2187 return EINVAL; 2188 } 2189 2190 if ((result > 1) || (result < 0)) 2191 { 2192 return EINVAL; 2193 } 2194 2195 pUM->devParams.l2_fw_flow_ctrl = (uint32_t)result; 2196 } 2197 else if (strcmp(pr_name, "_autogreeen_enable") == 0) 2198 { 2199 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2200 { 2201 return EINVAL; 2202 } 2203 2204 if ((result > 1) || (result < 0)) 2205 { 2206 return EINVAL; 2207 } 2208 2209 pUM->devParams.autogreeenEnable = (uint32_t)result; 2210 if (pUM->plumbed) BnxeUpdatePhy(pUM); 2211 } 2212 else if (strcmp(pr_name, "_lso_enable") == 0) 2213 { 2214 if (pUM->plumbed) 2215 { 2216 return EBUSY; 2217 } 2218 2219 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2220 { 2221 return EINVAL; 2222 } 2223 2224 if ((result > 1) || (result < 0)) 2225 { 2226 return EINVAL; 2227 } 2228 2229 pUM->devParams.lsoEnable = (uint32_t)result; 2230 } 2231 else if (strcmp(pr_name, "_log_enable") == 0) 2232 { 2233 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2234 { 2235 return EINVAL; 2236 } 2237 2238 if ((result > 1) || (result < 0)) 2239 { 2240 return EINVAL; 2241 } 2242 2243 pUM->devParams.logEnable = (uint32_t)result; 2244 } 2245 else if (strcmp(pr_name, "_fcoe_enable") == 0) 2246 { 2247 if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) 2248 { 2249 return EINVAL; 2250 } 2251 2252 if ((result > 1) || (result < 0)) 2253 { 2254 return EINVAL; 2255 } 2256 2257 pUM->devParams.fcoeEnable = (uint32_t)result; 2258 2259 if (BNXE_FCOE(pUM)) 2260 { 2261 BnxeFcoeStartStop(pUM); 2262 } 2263 } 2264 else 2265 { 2266 err = ENOTSUP; 2267 } 2268 2269 return err; 2270 } 2271 2272 2273 static int BnxeMacSetProperty(void * barg, 2274 const char * pr_name, 2275 mac_prop_id_t pr_num, 2276 uint_t pr_valsize, 2277 const void * pr_val) 2278 { 2279 um_device_t * pUM = barg; 2280 boolean_t reprogram = B_FALSE; 2281 boolean_t rxpause; 2282 boolean_t txpause; 2283 uint32_t mtu; 2284 link_flowctrl_t fl; 2285 int err = 0; 2286 2287 BNXE_LOCK_ENTER_GLD(pUM); 2288 2289 switch (pr_num) 2290 { 2291 /* read-only props */ 2292 case MAC_PROP_STATUS: 2293 case MAC_PROP_SPEED: 2294 case MAC_PROP_DUPLEX: 2295 case MAC_PROP_MEDIA: 2296 2297 case MAC_PROP_ADV_10GFDX_CAP: 2298 case MAC_PROP_ADV_1000FDX_CAP: 2299 case MAC_PROP_ADV_1000HDX_CAP: 2300 case MAC_PROP_ADV_100FDX_CAP: 2301 case MAC_PROP_ADV_100HDX_CAP: 2302 case MAC_PROP_ADV_10FDX_CAP: 2303 case MAC_PROP_ADV_10HDX_CAP: 2304 case MAC_PROP_ADV_100T4_CAP: 2305 2306 case MAC_PROP_EN_1000HDX_CAP: 2307 case MAC_PROP_EN_100T4_CAP: 2308 2309 default: 2310 2311 err = ENOTSUP; 2312 break; 2313 2314 case MAC_PROP_EN_10GFDX_CAP: 2315 2316 pUM->hwinit.lnkcfg.param_10000fdx = *(uint8_t *)pr_val; 2317 pUM->curcfg.lnkcfg.param_10000fdx = *(uint8_t *)pr_val; 2318 reprogram = B_TRUE; 2319 break; 2320 2321 case MAC_PROP_EN_1000FDX_CAP: 2322 2323 pUM->hwinit.lnkcfg.param_1000fdx = *(uint8_t *)pr_val; 2324 pUM->curcfg.lnkcfg.param_1000fdx = *(uint8_t *)pr_val; 2325 reprogram = B_TRUE; 2326 break; 2327 2328 case MAC_PROP_EN_100FDX_CAP: 2329 2330 pUM->hwinit.lnkcfg.param_100fdx = *(uint8_t *)pr_val; 2331 pUM->curcfg.lnkcfg.param_100fdx = *(uint8_t *)pr_val; 2332 reprogram = B_TRUE; 2333 break; 2334 2335 case MAC_PROP_EN_100HDX_CAP: 2336 2337 pUM->hwinit.lnkcfg.param_100hdx = *(uint8_t *)pr_val; 2338 pUM->curcfg.lnkcfg.param_100hdx = *(uint8_t *)pr_val; 2339 reprogram = B_TRUE; 2340 break; 2341 2342 case MAC_PROP_EN_10FDX_CAP: 2343 2344 pUM->hwinit.lnkcfg.param_10fdx = *(uint8_t *)pr_val; 2345 pUM->curcfg.lnkcfg.param_10fdx = *(uint8_t *)pr_val; 2346 reprogram = B_TRUE; 2347 break; 2348 2349 case MAC_PROP_EN_10HDX_CAP: 2350 2351 pUM->hwinit.lnkcfg.param_10hdx = *(uint8_t *)pr_val; 2352 pUM->curcfg.lnkcfg.param_10hdx = *(uint8_t *)pr_val; 2353 reprogram = B_TRUE; 2354 break; 2355 2356 case MAC_PROP_AUTONEG: 2357 2358 pUM->hwinit.lnkcfg.link_autoneg = *(uint8_t *)pr_val; 2359 pUM->curcfg.lnkcfg.link_autoneg = *(uint8_t *)pr_val; 2360 reprogram = B_TRUE; 2361 break; 2362 2363 case MAC_PROP_FLOWCTRL: 2364 2365 bcopy(pr_val, &fl, sizeof(fl)); 2366 2367 switch (fl) 2368 { 2369 case LINK_FLOWCTRL_NONE: 2370 2371 rxpause = B_FALSE; 2372 txpause = B_FALSE; 2373 break; 2374 2375 case LINK_FLOWCTRL_RX: 2376 2377 rxpause = B_TRUE; 2378 txpause = B_FALSE; 2379 break; 2380 2381 case LINK_FLOWCTRL_TX: 2382 2383 rxpause = B_FALSE; 2384 txpause = B_TRUE; 2385 break; 2386 2387 case LINK_FLOWCTRL_BI: 2388 2389 rxpause = B_TRUE; 2390 txpause = B_TRUE; 2391 break; 2392 2393 default: 2394 2395 err = ENOTSUP; 2396 break; 2397 } 2398 2399 if (err == 0) 2400 { 2401 pUM->hwinit.lnkcfg.param_rxpause = rxpause; 2402 pUM->hwinit.lnkcfg.param_txpause = txpause; 2403 pUM->curcfg.lnkcfg.param_rxpause = rxpause; 2404 pUM->curcfg.lnkcfg.param_txpause = txpause; 2405 reprogram = B_TRUE; 2406 } 2407 2408 break; 2409 2410 case MAC_PROP_MTU: 2411 2412 if (pUM->plumbed) 2413 { 2414 err = EBUSY; 2415 break; 2416 } 2417 2418 bcopy(pr_val, &mtu, sizeof (mtu)); 2419 2420 if ((mtu < USER_OPTION_MTU_MIN) || (mtu > USER_OPTION_MTU_MAX)) 2421 { 2422 err = EINVAL; 2423 break; 2424 } 2425 2426 if (pUM->devParams.mtu[LM_CLI_IDX_NDIS] == mtu) 2427 { 2428 break; 2429 } 2430 2431 pUM->devParams.mtu[LM_CLI_IDX_NDIS] = mtu; 2432 err = mac_maxsdu_update(pUM->pMac, pUM->devParams.mtu[LM_CLI_IDX_NDIS]); 2433 pUM->lm_dev.params.mtu[LM_CLI_IDX_NDIS] = pUM->devParams.mtu[LM_CLI_IDX_NDIS]; 2434 break; 2435 2436 case MAC_PROP_PRIVATE: 2437 2438 err = BnxeSetPrivateProperty(pUM, pr_name, pr_valsize, pr_val); 2439 break; 2440 } 2441 2442 if (!err && reprogram) 2443 { 2444 if (pUM->plumbed) BnxeUpdatePhy(pUM); 2445 } 2446 2447 BNXE_LOCK_EXIT_GLD(pUM); 2448 return err; 2449 } 2450 2451 #endif /* MC_SETPROP */ 2452 2453 2454 #ifdef MC_GETPROP 2455 2456 static int BnxeGetPrivateProperty(um_device_t * pUM, 2457 const char * pr_name, 2458 uint_t pr_valsize, 2459 void * pr_val) 2460 { 2461 BnxeLinkCfg * lnk_cfg = &pUM->curcfg.lnkcfg; 2462 BnxeLinkCfg * hw_cfg = &pUM->hwinit.lnkcfg; 2463 int value; 2464 int err = 0; 2465 2466 if (strcmp(pr_name, "_adv_2500fdx_cap") == 0) 2467 { 2468 value = lnk_cfg->param_2500fdx; 2469 } 2470 else if (strcmp(pr_name, "_en_2500fdx_cap") == 0) 2471 { 2472 value = hw_cfg->param_2500fdx; 2473 } 2474 else if (strcmp(pr_name, "_adv_txpause_cap") == 0) 2475 { 2476 value = lnk_cfg->param_txpause; 2477 } 2478 else if (strcmp(pr_name, "_en_txpause_cap") == 0) 2479 { 2480 value = hw_cfg->param_txpause; 2481 } 2482 else if (strcmp(pr_name, "_txpause") == 0) 2483 { 2484 value = pUM->props.link_txpause; 2485 } 2486 else if (strcmp(pr_name, "_adv_rxpause_cap") == 0) 2487 { 2488 value = lnk_cfg->param_rxpause; 2489 } 2490 else if (strcmp(pr_name, "_en_rxpause_cap") == 0) 2491 { 2492 value = hw_cfg->param_rxpause; 2493 } 2494 else if (strcmp(pr_name, "_rxpause") == 0) 2495 { 2496 value = pUM->props.link_rxpause; 2497 } 2498 else if (strcmp(pr_name, "_autoneg_flow") == 0) 2499 { 2500 value = pUM->hwinit.flow_autoneg; 2501 } 2502 else if (strcmp(pr_name, "_checksum") == 0) 2503 { 2504 value = pUM->devParams.checksum; 2505 } 2506 else if (strcmp(pr_name, "_tx_ring_policy") == 0) 2507 { 2508 value = pUM->devParams.routeTxRingPolicy; 2509 } 2510 else if (strcmp(pr_name, "_num_rings") == 0) 2511 { 2512 value = pUM->devParams.numRings; 2513 } 2514 else if (strcmp(pr_name, "_rx_descs") == 0) 2515 { 2516 value = pUM->devParams.numRxDesc[LM_CLI_IDX_NDIS]; 2517 } 2518 else if (strcmp(pr_name, "_rx_free_reclaim") == 0) 2519 { 2520 value = pUM->devParams.maxRxFree; 2521 } 2522 else if (strcmp(pr_name, "_tx_descs") == 0) 2523 { 2524 value = pUM->devParams.numTxDesc[LM_CLI_IDX_NDIS]; 2525 } 2526 else if (strcmp(pr_name, "_tx_free_reclaim") == 0) 2527 { 2528 value = pUM->devParams.maxTxFree; 2529 } 2530 else if (strcmp(pr_name, "_rx_copy_threshold") == 0) 2531 { 2532 value = pUM->devParams.rxCopyThreshold; 2533 } 2534 else if (strcmp(pr_name, "_tx_copy_threshold") == 0) 2535 { 2536 value = pUM->devParams.txCopyThreshold; 2537 } 2538 else if (strcmp(pr_name, "_interrupt_coalesce") == 0) 2539 { 2540 value = pUM->devParams.intrCoalesce; 2541 } 2542 else if (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0) 2543 { 2544 value = pUM->devParams.intrRxPerSec; 2545 } 2546 else if (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0) 2547 { 2548 value = pUM->devParams.intrTxPerSec; 2549 } 2550 else if (strcmp(pr_name, "_disable_msix") == 0) 2551 { 2552 value = pUM->devParams.disableMsix; 2553 } 2554 else if (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0) 2555 { 2556 value = pUM->devParams.l2_fw_flow_ctrl; 2557 } 2558 else if (strcmp(pr_name, "_autogreeen_enable") == 0) 2559 { 2560 value = pUM->devParams.autogreeenEnable; 2561 } 2562 else if (strcmp(pr_name, "_lso_enable") == 0) 2563 { 2564 value = pUM->devParams.lsoEnable; 2565 } 2566 else if (strcmp(pr_name, "_log_enable") == 0) 2567 { 2568 value = pUM->devParams.logEnable; 2569 } 2570 else if (strcmp(pr_name, "_fcoe_enable") == 0) 2571 { 2572 value = pUM->devParams.fcoeEnable; 2573 } 2574 else 2575 { 2576 err = ENOTSUP; 2577 } 2578 2579 if (!err) 2580 { 2581 (void)snprintf(pr_val, pr_valsize, "%d", value); 2582 } 2583 2584 return err; 2585 } 2586 2587 2588 static int BnxeMacGetProperty(void * barg, 2589 const char * pr_name, 2590 mac_prop_id_t pr_num, 2591 uint_t pr_valsize, 2592 void * pr_val) 2593 { 2594 um_device_t * pUM = barg; 2595 link_flowctrl_t link_flowctrl; 2596 link_state_t link_state; 2597 link_duplex_t link_duplex; 2598 uint64_t link_speed; 2599 mac_ether_media_t link_media; 2600 BnxeLinkCfg * lnk_cfg = &pUM->curcfg.lnkcfg; 2601 BnxeLinkCfg * hw_cfg = &pUM->hwinit.lnkcfg; 2602 2603 switch (pr_num) 2604 { 2605 case MAC_PROP_MTU: 2606 2607 ASSERT(pr_valsize >= sizeof(u32_t)); 2608 2609 bcopy(&pUM->devParams.mtu[LM_CLI_IDX_NDIS], pr_val, sizeof(u32_t)); 2610 break; 2611 2612 case MAC_PROP_DUPLEX: 2613 2614 ASSERT(pr_valsize >= sizeof(link_duplex_t)); 2615 2616 link_duplex = pUM->props.link_duplex ? 2617 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; 2618 bcopy(&link_duplex, pr_val, sizeof(link_duplex_t)); 2619 break; 2620 2621 case MAC_PROP_SPEED: 2622 2623 ASSERT(pr_valsize >= sizeof(link_speed)); 2624 2625 link_speed = (pUM->props.link_speed * 1000000ULL); 2626 bcopy(&link_speed, pr_val, sizeof(link_speed)); 2627 break; 2628 2629 case MAC_PROP_STATUS: 2630 2631 ASSERT(pr_valsize >= sizeof(link_state_t)); 2632 2633 link_state = pUM->props.link_speed ? 2634 LINK_STATE_UP : LINK_STATE_DOWN; 2635 bcopy(&link_state, pr_val, sizeof(link_state_t)); 2636 break; 2637 2638 case MAC_PROP_MEDIA: 2639 ASSERT(pr_valsize >= sizeof(mac_ether_media_t)); 2640 2641 link_media = bnxe_phy_to_media(pUM); 2642 bcopy(&link_media, pr_val, sizeof(mac_ether_media_t)); 2643 break; 2644 2645 case MAC_PROP_AUTONEG: 2646 2647 *(uint8_t *)pr_val = lnk_cfg->link_autoneg; 2648 break; 2649 2650 case MAC_PROP_FLOWCTRL: 2651 2652 ASSERT(pr_valsize >= sizeof(link_flowctrl_t)); 2653 2654 if (!lnk_cfg->param_rxpause && !lnk_cfg->param_txpause) 2655 { 2656 link_flowctrl = LINK_FLOWCTRL_NONE; 2657 } 2658 if (lnk_cfg->param_rxpause && !lnk_cfg->param_txpause) 2659 { 2660 link_flowctrl = LINK_FLOWCTRL_RX; 2661 } 2662 if (!lnk_cfg->param_rxpause && lnk_cfg->param_txpause) 2663 { 2664 link_flowctrl = LINK_FLOWCTRL_TX; 2665 } 2666 if (lnk_cfg->param_rxpause && lnk_cfg->param_txpause) 2667 { 2668 link_flowctrl = LINK_FLOWCTRL_BI; 2669 } 2670 2671 bcopy(&link_flowctrl, pr_val, sizeof(link_flowctrl_t)); 2672 break; 2673 2674 case MAC_PROP_ADV_10GFDX_CAP: 2675 2676 *(uint8_t *)pr_val = lnk_cfg->param_10000fdx; 2677 break; 2678 2679 case MAC_PROP_EN_10GFDX_CAP: 2680 2681 *(uint8_t *)pr_val = hw_cfg->param_10000fdx; 2682 break; 2683 2684 case MAC_PROP_ADV_1000FDX_CAP: 2685 2686 *(uint8_t *)pr_val = lnk_cfg->param_1000fdx; 2687 break; 2688 2689 case MAC_PROP_EN_1000FDX_CAP: 2690 2691 *(uint8_t *)pr_val = hw_cfg->param_1000fdx; 2692 break; 2693 2694 case MAC_PROP_ADV_1000HDX_CAP: 2695 case MAC_PROP_EN_1000HDX_CAP: 2696 2697 *(uint8_t *)pr_val = 0; 2698 break; 2699 2700 case MAC_PROP_ADV_100FDX_CAP: 2701 2702 *(uint8_t *)pr_val = lnk_cfg->param_100fdx; 2703 break; 2704 2705 case MAC_PROP_EN_100FDX_CAP: 2706 2707 *(uint8_t *)pr_val = hw_cfg->param_100fdx; 2708 break; 2709 2710 case MAC_PROP_ADV_100HDX_CAP: 2711 2712 *(uint8_t *)pr_val = lnk_cfg->param_100hdx; 2713 break; 2714 2715 case MAC_PROP_EN_100HDX_CAP: 2716 2717 *(uint8_t *)pr_val = hw_cfg->param_100hdx; 2718 break; 2719 2720 case MAC_PROP_ADV_100T4_CAP: 2721 case MAC_PROP_EN_100T4_CAP: 2722 2723 *(uint8_t *)pr_val = 0; 2724 break; 2725 2726 case MAC_PROP_ADV_10FDX_CAP: 2727 2728 *(uint8_t *)pr_val = lnk_cfg->param_10fdx; 2729 break; 2730 2731 case MAC_PROP_EN_10FDX_CAP: 2732 2733 *(uint8_t *)pr_val = hw_cfg->param_10fdx; 2734 break; 2735 2736 case MAC_PROP_ADV_10HDX_CAP: 2737 2738 *(uint8_t *)pr_val = lnk_cfg->param_10hdx; 2739 break; 2740 2741 case MAC_PROP_EN_10HDX_CAP: 2742 2743 *(uint8_t *)pr_val = hw_cfg->param_10hdx; 2744 break; 2745 2746 case MAC_PROP_PRIVATE: 2747 2748 return BnxeGetPrivateProperty(pUM, 2749 pr_name, 2750 pr_valsize, 2751 pr_val); 2752 2753 default: 2754 2755 return ENOTSUP; 2756 } 2757 2758 return 0; 2759 } 2760 2761 #endif /* MC_GETPROP */ 2762 2763 2764 #ifdef MC_PROPINFO 2765 2766 static void BnxeMacPrivatePropertyInfo(um_device_t * pUM, 2767 const char * pr_name, 2768 mac_prop_info_handle_t prh) 2769 { 2770 char valstr[64]; 2771 BnxeLinkCfg * default_cfg = &bnxeLinkCfg; 2772 int default_val; 2773 2774 bzero(valstr, sizeof (valstr)); 2775 2776 if ((strcmp(pr_name, "_adv_2500fdx_cap") == 0) || 2777 (strcmp(pr_name, "_adv_txpause_cap") == 0) || 2778 (strcmp(pr_name, "_txpause") == 0) || 2779 (strcmp(pr_name, "_adv_rxpause_cap") == 0) || 2780 (strcmp(pr_name, "_rxpause") == 0) || 2781 (strcmp(pr_name, "_checksum") == 0) || 2782 (strcmp(pr_name, "_num_rings") == 0) || 2783 (strcmp(pr_name, "_rx_descs") == 0) || 2784 (strcmp(pr_name, "_tx_descs") == 0) || 2785 (strcmp(pr_name, "_interrupt_coalesce") == 0) || 2786 (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0) || 2787 (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0) || 2788 (strcmp(pr_name, "_disable_msix") == 0) || 2789 (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0) || 2790 (strcmp(pr_name, "_lso_enable") == 0)) 2791 { 2792 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 2793 return; 2794 } 2795 2796 if (strcmp(pr_name, "_autoneg_flow") == 0) 2797 { 2798 default_val = B_TRUE; 2799 } 2800 else if (strcmp(pr_name, "_tx_ring_policy") == 0) 2801 { 2802 default_val = BNXE_ROUTE_RING_TCPUDP; 2803 } 2804 else if (strcmp(pr_name, "_rx_free_reclaim") == 0) 2805 { 2806 default_val = USER_OPTION_RX_MAX_FREE_DEFAULT; 2807 } 2808 else if (strcmp(pr_name, "_tx_free_reclaim") == 0) 2809 { 2810 default_val = USER_OPTION_TX_MAX_FREE_DEFAULT; 2811 } 2812 else if (strcmp(pr_name, "_rx_copy_threshold") == 0) 2813 { 2814 default_val = USER_OPTION_RX_DCOPY_THRESH_DEFAULT; 2815 } 2816 else if (strcmp(pr_name, "_tx_copy_threshold") == 0) 2817 { 2818 default_val = USER_OPTION_TX_DCOPY_THRESH_DEFAULT; 2819 } 2820 else if (strcmp(pr_name, "_autogreeen_enable") == 0) 2821 { 2822 default_val = B_TRUE; 2823 } 2824 else if (strcmp(pr_name, "_log_enable") == 0) 2825 { 2826 default_val = B_TRUE; 2827 } 2828 else if (strcmp(pr_name, "_fcoe_enable") == 0) 2829 { 2830 default_val = B_TRUE; 2831 } 2832 else 2833 { 2834 return; 2835 } 2836 2837 snprintf(valstr, sizeof (valstr), "%d", default_val); 2838 mac_prop_info_set_default_str(prh, valstr); 2839 } 2840 2841 2842 static void BnxeMacPropertyInfo(void * barg, 2843 const char * pr_name, 2844 mac_prop_id_t pr_num, 2845 mac_prop_info_handle_t prh) 2846 { 2847 um_device_t * pUM = barg; 2848 link_flowctrl_t link_flowctrl; 2849 BnxeLinkCfg * default_cfg = &bnxeLinkCfg; 2850 2851 switch (pr_num) 2852 { 2853 case MAC_PROP_STATUS: 2854 case MAC_PROP_SPEED: 2855 case MAC_PROP_DUPLEX: 2856 2857 case MAC_PROP_ADV_10GFDX_CAP: 2858 case MAC_PROP_ADV_1000FDX_CAP: 2859 case MAC_PROP_ADV_1000HDX_CAP: 2860 case MAC_PROP_ADV_100FDX_CAP: 2861 case MAC_PROP_ADV_100HDX_CAP: 2862 case MAC_PROP_ADV_100T4_CAP: 2863 case MAC_PROP_ADV_10FDX_CAP: 2864 case MAC_PROP_ADV_10HDX_CAP: 2865 2866 case MAC_PROP_EN_1000HDX_CAP: 2867 case MAC_PROP_EN_100T4_CAP: 2868 2869 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 2870 break; 2871 2872 case MAC_PROP_EN_10GFDX_CAP: 2873 2874 mac_prop_info_set_default_uint8(prh, default_cfg->param_10000fdx); 2875 break; 2876 2877 case MAC_PROP_EN_1000FDX_CAP: 2878 2879 mac_prop_info_set_default_uint8(prh, default_cfg->param_1000fdx); 2880 break; 2881 2882 case MAC_PROP_EN_100FDX_CAP: 2883 2884 mac_prop_info_set_default_uint8(prh, default_cfg->param_100fdx); 2885 break; 2886 2887 case MAC_PROP_EN_100HDX_CAP: 2888 2889 mac_prop_info_set_default_uint8(prh, default_cfg->param_100hdx); 2890 break; 2891 2892 case MAC_PROP_EN_10FDX_CAP: 2893 2894 mac_prop_info_set_default_uint8(prh, default_cfg->param_10fdx); 2895 break; 2896 2897 case MAC_PROP_EN_10HDX_CAP: 2898 2899 mac_prop_info_set_default_uint8(prh, default_cfg->param_10hdx); 2900 break; 2901 2902 case MAC_PROP_MTU: 2903 2904 mac_prop_info_set_range_uint32(prh, 2905 USER_OPTION_MTU_MIN, 2906 USER_OPTION_MTU_MAX); 2907 break; 2908 2909 case MAC_PROP_AUTONEG: 2910 2911 mac_prop_info_set_default_uint8(prh, default_cfg->link_autoneg); 2912 break; 2913 2914 case MAC_PROP_FLOWCTRL: 2915 2916 if (!default_cfg->param_rxpause && !default_cfg->param_txpause) 2917 { 2918 link_flowctrl = LINK_FLOWCTRL_NONE; 2919 } 2920 2921 if (default_cfg->param_rxpause && !default_cfg->param_txpause) 2922 { 2923 link_flowctrl = LINK_FLOWCTRL_RX; 2924 } 2925 2926 if (!default_cfg->param_rxpause && default_cfg->param_txpause) 2927 { 2928 link_flowctrl = LINK_FLOWCTRL_TX; 2929 } 2930 2931 if (default_cfg->param_rxpause && default_cfg->param_txpause) 2932 { 2933 link_flowctrl = LINK_FLOWCTRL_BI; 2934 } 2935 2936 mac_prop_info_set_default_link_flowctrl(prh, link_flowctrl); 2937 break; 2938 2939 case MAC_PROP_PRIVATE: 2940 2941 BnxeMacPrivatePropertyInfo(pUM, pr_name, prh); 2942 break; 2943 } 2944 } 2945 2946 #endif /* MC_PROPINFO */ 2947 2948 2949 static mac_callbacks_t bnxe_callbacks = 2950 { 2951 ( 2952 MC_IOCTL 2953 #ifdef MC_RESOURCES 2954 | MC_RESOURCES 2955 #endif 2956 #ifdef MC_SETPROP 2957 | MC_SETPROP 2958 #endif 2959 #ifdef MC_GETPROP 2960 | MC_GETPROP 2961 #endif 2962 #ifdef MC_PROPINFO 2963 | MC_PROPINFO 2964 #endif 2965 | MC_GETCAPAB 2966 ), 2967 BnxeMacStats, 2968 BnxeMacStart, 2969 BnxeMacStop, 2970 BnxeMacPromiscuous, 2971 BnxeMacMulticast, 2972 NULL, 2973 BnxeMacTx, 2974 #ifdef MC_RESOURCES 2975 BnxeMacResources, 2976 #else 2977 NULL, 2978 #endif 2979 BnxeMacIoctl, 2980 BnxeMacGetCapability, 2981 #ifdef MC_OPEN 2982 NULL, 2983 NULL, 2984 #endif 2985 #ifdef MC_SETPROP 2986 BnxeMacSetProperty, 2987 #endif 2988 #ifdef MC_GETPROP 2989 BnxeMacGetProperty, 2990 #endif 2991 #ifdef MC_PROPINFO 2992 BnxeMacPropertyInfo 2993 #endif 2994 }; 2995 2996 2997 boolean_t BnxeGldInit(um_device_t * pUM) 2998 { 2999 mac_register_t * pMac; 3000 int rc; 3001 3002 atomic_swap_32(&pUM->plumbed, B_FALSE); 3003 3004 if ((pMac = mac_alloc(MAC_VERSION)) == NULL) 3005 { 3006 BnxeLogWarn(pUM, "Failed to allocate GLD MAC memory"); 3007 return B_FALSE; 3008 } 3009 3010 pMac->m_driver = pUM; 3011 pMac->m_dip = pUM->pDev; 3012 pMac->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 3013 pMac->m_callbacks = &bnxe_callbacks; 3014 pMac->m_min_sdu = 0; 3015 pMac->m_max_sdu = pUM->devParams.mtu[LM_CLI_IDX_NDIS]; 3016 pMac->m_src_addr = &(pUM->lm_dev.params.mac_addr[0]); 3017 3018 #ifdef MC_OPEN 3019 pMac->m_margin = VLAN_TAGSZ; 3020 #endif 3021 3022 #ifdef MC_SETPROP 3023 pMac->m_priv_props = bnxeLink_priv_props; 3024 #endif 3025 3026 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS) 3027 bnxe_callbacks.mc_unicst = 3028 (!pUM->devParams.numRings) ? BnxeMacUnicast : NULL; 3029 #else 3030 bnxe_callbacks.mc_unicst = BnxeMacUnicast; 3031 #endif 3032 3033 rc = mac_register(pMac, &pUM->pMac); 3034 3035 mac_free(pMac); 3036 3037 if (rc != 0) 3038 { 3039 BnxeLogWarn(pUM, "Failed to register with GLD (%d)", rc); 3040 return B_FALSE; 3041 } 3042 3043 /* Always report the initial link state as unknown. */ 3044 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN); 3045 3046 return B_TRUE; 3047 } 3048 3049 3050 boolean_t BnxeGldFini(um_device_t * pUM) 3051 { 3052 int cnt; 3053 3054 if (pUM->plumbed) 3055 { 3056 BnxeLogWarn(pUM, "Detaching device from GLD that is started!"); 3057 return B_FALSE; 3058 } 3059 3060 /* We must not detach until all packets held by stack are retrieved. */ 3061 if (!BnxeWaitForPacketsFromClient(pUM, LM_CLI_IDX_NDIS)) 3062 { 3063 return B_FALSE; 3064 } 3065 3066 if (pUM->pMac) 3067 { 3068 if (mac_unregister(pUM->pMac)) 3069 { 3070 BnxeLogWarn(pUM, "Failed to unregister with the GLD"); 3071 return B_FALSE; 3072 } 3073 } 3074 3075 return B_TRUE; 3076 } 3077 3078 3079 void BnxeGldLink(um_device_t * pUM, 3080 link_state_t state) 3081 { 3082 mac_link_update(pUM->pMac, state); 3083 } 3084 3085