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