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