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(c) 2007-2010 Intel Corporation. All rights reserved. 24 */ 25 26 /* 27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 28 * Copyright 2013, Nexenta Systems, Inc. All rights reserved. 29 * Copyright 2014 Pluribus Networks Inc. 30 * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved. 31 * Copyright (c) 2017, Joyent, Inc. 32 * Copyright 2023 Oxide Computer Company 33 */ 34 35 #include "igb_sw.h" 36 37 int 38 igb_m_stat(void *arg, uint_t stat, uint64_t *val) 39 { 40 igb_t *igb = (igb_t *)arg; 41 struct e1000_hw *hw = &igb->hw; 42 igb_stat_t *igb_ks; 43 uint32_t low_val, high_val; 44 45 igb_ks = (igb_stat_t *)igb->igb_ks->ks_data; 46 47 mutex_enter(&igb->gen_lock); 48 49 if (igb->igb_state & IGB_SUSPENDED) { 50 mutex_exit(&igb->gen_lock); 51 return (ECANCELED); 52 } 53 54 switch (stat) { 55 case MAC_STAT_IFSPEED: 56 *val = igb->link_speed * 1000000ull; 57 break; 58 59 case MAC_STAT_MULTIRCV: 60 igb->stat_mprc += E1000_READ_REG(hw, E1000_MPRC); 61 *val = igb->stat_mprc; 62 break; 63 64 case MAC_STAT_BRDCSTRCV: 65 igb->stat_bprc += E1000_READ_REG(hw, E1000_BPRC); 66 *val = igb->stat_bprc; 67 break; 68 69 case MAC_STAT_MULTIXMT: 70 igb->stat_mptc += E1000_READ_REG(hw, E1000_MPTC); 71 *val = igb->stat_mptc; 72 break; 73 74 case MAC_STAT_BRDCSTXMT: 75 igb->stat_bptc += E1000_READ_REG(hw, E1000_BPTC); 76 *val = igb->stat_bptc; 77 break; 78 79 case MAC_STAT_NORCVBUF: 80 igb->stat_rnbc += E1000_READ_REG(hw, E1000_RNBC); 81 *val = igb->stat_rnbc; 82 break; 83 84 case MAC_STAT_IERRORS: 85 igb->stat_rxerrc += E1000_READ_REG(hw, E1000_RXERRC); 86 igb->stat_algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC); 87 igb_ks->rlec.value.ui64 += 88 E1000_READ_REG(hw, E1000_RLEC); 89 igb->stat_crcerrs += E1000_READ_REG(hw, E1000_CRCERRS); 90 igb->stat_cexterr += E1000_READ_REG(hw, E1000_CEXTERR); 91 *val = igb->stat_rxerrc + 92 igb->stat_algnerrc + 93 igb_ks->rlec.value.ui64 + 94 igb->stat_crcerrs + 95 igb->stat_cexterr; 96 break; 97 98 case MAC_STAT_NOXMTBUF: 99 *val = 0; 100 break; 101 102 case MAC_STAT_OERRORS: 103 igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL); 104 *val = igb->stat_ecol; 105 break; 106 107 case MAC_STAT_COLLISIONS: 108 igb->stat_colc += E1000_READ_REG(hw, E1000_COLC); 109 *val = igb->stat_colc; 110 break; 111 112 case MAC_STAT_RBYTES: 113 /* 114 * The 64-bit register will reset whenever the upper 115 * 32 bits are read. So we need to read the lower 116 * 32 bits first, then read the upper 32 bits. 117 */ 118 low_val = E1000_READ_REG(hw, E1000_TORL); 119 high_val = E1000_READ_REG(hw, E1000_TORH); 120 igb->stat_tor += (uint64_t)high_val << 32 | (uint64_t)low_val; 121 *val = igb->stat_tor; 122 break; 123 124 case MAC_STAT_IPACKETS: 125 igb->stat_tpr += E1000_READ_REG(hw, E1000_TPR); 126 *val = igb->stat_tpr; 127 break; 128 129 case MAC_STAT_OBYTES: 130 /* 131 * The 64-bit register will reset whenever the upper 132 * 32 bits are read. So we need to read the lower 133 * 32 bits first, then read the upper 32 bits. 134 */ 135 low_val = E1000_READ_REG(hw, E1000_TOTL); 136 high_val = E1000_READ_REG(hw, E1000_TOTH); 137 igb->stat_tot += (uint64_t)high_val << 32 | (uint64_t)low_val; 138 *val = igb->stat_tot; 139 break; 140 141 case MAC_STAT_OPACKETS: 142 igb->stat_tpt += E1000_READ_REG(hw, E1000_TPT); 143 *val = igb->stat_tpt; 144 break; 145 146 /* RFC 1643 stats */ 147 case ETHER_STAT_ALIGN_ERRORS: 148 igb->stat_algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC); 149 *val = igb->stat_algnerrc; 150 break; 151 152 case ETHER_STAT_FCS_ERRORS: 153 igb->stat_crcerrs += E1000_READ_REG(hw, E1000_CRCERRS); 154 *val = igb->stat_crcerrs; 155 break; 156 157 case ETHER_STAT_FIRST_COLLISIONS: 158 igb->stat_scc += E1000_READ_REG(hw, E1000_SCC); 159 *val = igb->stat_scc; 160 break; 161 162 case ETHER_STAT_MULTI_COLLISIONS: 163 igb->stat_mcc += E1000_READ_REG(hw, E1000_MCC); 164 *val = igb->stat_mcc; 165 break; 166 167 case ETHER_STAT_SQE_ERRORS: 168 igb->stat_sec += E1000_READ_REG(hw, E1000_SEC); 169 *val = igb->stat_sec; 170 break; 171 172 case ETHER_STAT_DEFER_XMTS: 173 igb->stat_dc += E1000_READ_REG(hw, E1000_DC); 174 *val = igb->stat_dc; 175 break; 176 177 case ETHER_STAT_TX_LATE_COLLISIONS: 178 igb->stat_latecol += E1000_READ_REG(hw, E1000_LATECOL); 179 *val = igb->stat_latecol; 180 break; 181 182 case ETHER_STAT_EX_COLLISIONS: 183 igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL); 184 *val = igb->stat_ecol; 185 break; 186 187 case ETHER_STAT_MACXMT_ERRORS: 188 igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL); 189 *val = igb->stat_ecol; 190 break; 191 192 case ETHER_STAT_CARRIER_ERRORS: 193 igb->stat_cexterr += E1000_READ_REG(hw, E1000_CEXTERR); 194 *val = igb->stat_cexterr; 195 break; 196 197 case ETHER_STAT_TOOLONG_ERRORS: 198 igb->stat_roc += E1000_READ_REG(hw, E1000_ROC); 199 *val = igb->stat_roc; 200 break; 201 202 case ETHER_STAT_MACRCV_ERRORS: 203 igb->stat_rxerrc += E1000_READ_REG(hw, E1000_RXERRC); 204 *val = igb->stat_rxerrc; 205 break; 206 207 /* MII/GMII stats */ 208 case ETHER_STAT_XCVR_ADDR: 209 *val = hw->phy.addr; 210 break; 211 212 case ETHER_STAT_XCVR_ID: 213 *val = hw->phy.id | hw->phy.revision; 214 break; 215 216 case ETHER_STAT_XCVR_INUSE: 217 *val = (uint64_t)e1000_link_to_media(hw, igb->link_speed); 218 break; 219 220 case ETHER_STAT_CAP_1000FDX: 221 *val = igb->param_1000fdx_cap; 222 break; 223 224 case ETHER_STAT_CAP_1000HDX: 225 *val = igb->param_1000hdx_cap; 226 break; 227 228 case ETHER_STAT_CAP_100FDX: 229 *val = igb->param_100fdx_cap; 230 break; 231 232 case ETHER_STAT_CAP_100HDX: 233 *val = igb->param_100hdx_cap; 234 break; 235 236 case ETHER_STAT_CAP_10FDX: 237 *val = igb->param_10fdx_cap; 238 break; 239 240 case ETHER_STAT_CAP_10HDX: 241 *val = igb->param_10hdx_cap; 242 break; 243 244 case ETHER_STAT_CAP_ASMPAUSE: 245 *val = igb->param_asym_pause_cap; 246 break; 247 248 case ETHER_STAT_CAP_PAUSE: 249 *val = igb->param_pause_cap; 250 break; 251 252 case ETHER_STAT_CAP_AUTONEG: 253 *val = igb->param_autoneg_cap; 254 break; 255 256 case ETHER_STAT_ADV_CAP_1000FDX: 257 *val = igb->param_adv_1000fdx_cap; 258 break; 259 260 case ETHER_STAT_ADV_CAP_1000HDX: 261 *val = igb->param_adv_1000hdx_cap; 262 break; 263 264 case ETHER_STAT_ADV_CAP_100FDX: 265 *val = igb->param_adv_100fdx_cap; 266 break; 267 268 case ETHER_STAT_ADV_CAP_100HDX: 269 *val = igb->param_adv_100hdx_cap; 270 break; 271 272 case ETHER_STAT_ADV_CAP_10FDX: 273 *val = igb->param_adv_10fdx_cap; 274 break; 275 276 case ETHER_STAT_ADV_CAP_10HDX: 277 *val = igb->param_adv_10hdx_cap; 278 break; 279 280 case ETHER_STAT_ADV_CAP_ASMPAUSE: 281 *val = igb->param_adv_asym_pause_cap; 282 break; 283 284 case ETHER_STAT_ADV_CAP_PAUSE: 285 *val = igb->param_adv_pause_cap; 286 break; 287 288 case ETHER_STAT_ADV_CAP_AUTONEG: 289 *val = hw->mac.autoneg; 290 break; 291 292 case ETHER_STAT_LP_CAP_1000FDX: 293 *val = igb->param_lp_1000fdx_cap; 294 break; 295 296 case ETHER_STAT_LP_CAP_1000HDX: 297 *val = igb->param_lp_1000hdx_cap; 298 break; 299 300 case ETHER_STAT_LP_CAP_100FDX: 301 *val = igb->param_lp_100fdx_cap; 302 break; 303 304 case ETHER_STAT_LP_CAP_100HDX: 305 *val = igb->param_lp_100hdx_cap; 306 break; 307 308 case ETHER_STAT_LP_CAP_10FDX: 309 *val = igb->param_lp_10fdx_cap; 310 break; 311 312 case ETHER_STAT_LP_CAP_10HDX: 313 *val = igb->param_lp_10hdx_cap; 314 break; 315 316 case ETHER_STAT_LP_CAP_ASMPAUSE: 317 *val = igb->param_lp_asym_pause_cap; 318 break; 319 320 case ETHER_STAT_LP_CAP_PAUSE: 321 *val = igb->param_lp_pause_cap; 322 break; 323 324 case ETHER_STAT_LP_CAP_AUTONEG: 325 *val = igb->param_lp_autoneg_cap; 326 break; 327 328 case ETHER_STAT_LINK_ASMPAUSE: 329 *val = igb->param_asym_pause_cap; 330 break; 331 332 case ETHER_STAT_LINK_PAUSE: 333 *val = igb->param_pause_cap; 334 break; 335 336 case ETHER_STAT_LINK_AUTONEG: 337 *val = hw->mac.autoneg; 338 break; 339 340 case ETHER_STAT_LINK_DUPLEX: 341 *val = (igb->link_duplex == FULL_DUPLEX) ? 342 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; 343 break; 344 345 case ETHER_STAT_TOOSHORT_ERRORS: 346 igb->stat_ruc += E1000_READ_REG(hw, E1000_RUC); 347 *val = igb->stat_ruc; 348 break; 349 350 case ETHER_STAT_CAP_REMFAULT: 351 *val = igb->param_rem_fault; 352 break; 353 354 case ETHER_STAT_ADV_REMFAULT: 355 *val = igb->param_adv_rem_fault; 356 break; 357 358 case ETHER_STAT_LP_REMFAULT: 359 *val = igb->param_lp_rem_fault; 360 break; 361 362 case ETHER_STAT_JABBER_ERRORS: 363 igb->stat_rjc += E1000_READ_REG(hw, E1000_RJC); 364 *val = igb->stat_rjc; 365 break; 366 367 case ETHER_STAT_CAP_100T4: 368 *val = igb->param_100t4_cap; 369 break; 370 371 case ETHER_STAT_ADV_CAP_100T4: 372 *val = igb->param_adv_100t4_cap; 373 break; 374 375 case ETHER_STAT_LP_CAP_100T4: 376 *val = igb->param_lp_100t4_cap; 377 break; 378 379 default: 380 mutex_exit(&igb->gen_lock); 381 return (ENOTSUP); 382 } 383 384 mutex_exit(&igb->gen_lock); 385 386 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) { 387 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED); 388 return (EIO); 389 } 390 391 return (0); 392 } 393 394 /* 395 * Bring the device out of the reset/quiesced state that it 396 * was in when the interface was registered. 397 */ 398 int 399 igb_m_start(void *arg) 400 { 401 igb_t *igb = (igb_t *)arg; 402 403 mutex_enter(&igb->gen_lock); 404 405 if (igb->igb_state & IGB_SUSPENDED) { 406 mutex_exit(&igb->gen_lock); 407 return (ECANCELED); 408 } 409 410 if (igb_start(igb, B_TRUE) != IGB_SUCCESS) { 411 mutex_exit(&igb->gen_lock); 412 return (EIO); 413 } 414 415 atomic_or_32(&igb->igb_state, IGB_STARTED); 416 417 mutex_exit(&igb->gen_lock); 418 419 /* 420 * Enable and start the watchdog timer 421 */ 422 igb_enable_watchdog_timer(igb); 423 424 return (0); 425 } 426 427 /* 428 * Stop the device and put it in a reset/quiesced state such 429 * that the interface can be unregistered. 430 */ 431 void 432 igb_m_stop(void *arg) 433 { 434 igb_t *igb = (igb_t *)arg; 435 436 mutex_enter(&igb->gen_lock); 437 438 if (igb->igb_state & IGB_SUSPENDED) { 439 mutex_exit(&igb->gen_lock); 440 return; 441 } 442 443 atomic_and_32(&igb->igb_state, ~IGB_STARTED); 444 445 igb_stop(igb, B_TRUE); 446 447 mutex_exit(&igb->gen_lock); 448 449 /* 450 * Disable and stop the watchdog timer 451 */ 452 igb_disable_watchdog_timer(igb); 453 } 454 455 /* 456 * Set the promiscuity of the device. 457 */ 458 int 459 igb_m_promisc(void *arg, boolean_t on) 460 { 461 igb_t *igb = (igb_t *)arg; 462 uint32_t reg_val; 463 464 mutex_enter(&igb->gen_lock); 465 466 if (igb->igb_state & IGB_SUSPENDED) { 467 mutex_exit(&igb->gen_lock); 468 return (ECANCELED); 469 } 470 471 reg_val = E1000_READ_REG(&igb->hw, E1000_RCTL); 472 473 if (on) 474 reg_val |= (E1000_RCTL_UPE | E1000_RCTL_MPE); 475 else 476 reg_val &= (~(E1000_RCTL_UPE | E1000_RCTL_MPE)); 477 478 E1000_WRITE_REG(&igb->hw, E1000_RCTL, reg_val); 479 480 mutex_exit(&igb->gen_lock); 481 482 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) { 483 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED); 484 return (EIO); 485 } 486 487 return (0); 488 } 489 490 /* 491 * Add/remove the addresses to/from the set of multicast 492 * addresses for which the device will receive packets. 493 */ 494 int 495 igb_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr) 496 { 497 igb_t *igb = (igb_t *)arg; 498 int result; 499 500 mutex_enter(&igb->gen_lock); 501 502 if (igb->igb_state & IGB_SUSPENDED) { 503 mutex_exit(&igb->gen_lock); 504 return (ECANCELED); 505 } 506 507 result = (add) ? igb_multicst_add(igb, mcst_addr) 508 : igb_multicst_remove(igb, mcst_addr); 509 510 mutex_exit(&igb->gen_lock); 511 512 return (result); 513 } 514 515 /* 516 * Pass on M_IOCTL messages passed to the DLD, and support 517 * private IOCTLs for debugging and ndd. 518 */ 519 void 520 igb_m_ioctl(void *arg, queue_t *q, mblk_t *mp) 521 { 522 igb_t *igb = (igb_t *)arg; 523 struct iocblk *iocp; 524 enum ioc_reply status; 525 526 iocp = (struct iocblk *)(uintptr_t)mp->b_rptr; 527 iocp->ioc_error = 0; 528 529 mutex_enter(&igb->gen_lock); 530 if (igb->igb_state & IGB_SUSPENDED) { 531 mutex_exit(&igb->gen_lock); 532 miocnak(q, mp, 0, EINVAL); 533 return; 534 } 535 mutex_exit(&igb->gen_lock); 536 537 switch (iocp->ioc_cmd) { 538 case LB_GET_INFO_SIZE: 539 case LB_GET_INFO: 540 case LB_GET_MODE: 541 case LB_SET_MODE: 542 status = igb_loopback_ioctl(igb, iocp, mp); 543 break; 544 545 default: 546 status = IOC_INVAL; 547 break; 548 } 549 550 /* 551 * Decide how to reply 552 */ 553 switch (status) { 554 default: 555 case IOC_INVAL: 556 /* 557 * Error, reply with a NAK and EINVAL or the specified error 558 */ 559 miocnak(q, mp, 0, iocp->ioc_error == 0 ? 560 EINVAL : iocp->ioc_error); 561 break; 562 563 case IOC_DONE: 564 /* 565 * OK, reply already sent 566 */ 567 break; 568 569 case IOC_ACK: 570 /* 571 * OK, reply with an ACK 572 */ 573 miocack(q, mp, 0, 0); 574 break; 575 576 case IOC_REPLY: 577 /* 578 * OK, send prepared reply as ACK or NAK 579 */ 580 mp->b_datap->db_type = iocp->ioc_error == 0 ? 581 M_IOCACK : M_IOCNAK; 582 qreply(q, mp); 583 break; 584 } 585 } 586 587 /* 588 * Add a MAC address to the target RX group. 589 */ 590 static int 591 igb_addmac(void *arg, const uint8_t *mac_addr) 592 { 593 igb_rx_group_t *rx_group = (igb_rx_group_t *)arg; 594 igb_t *igb = rx_group->igb; 595 struct e1000_hw *hw = &igb->hw; 596 int i, slot; 597 598 mutex_enter(&igb->gen_lock); 599 600 if (igb->igb_state & IGB_SUSPENDED) { 601 mutex_exit(&igb->gen_lock); 602 return (ECANCELED); 603 } 604 605 if (igb->unicst_avail == 0) { 606 /* no slots available */ 607 mutex_exit(&igb->gen_lock); 608 return (ENOSPC); 609 } 610 611 /* 612 * The slots from 0 to igb->num_rx_groups are reserved slots which 613 * are 1 to 1 mapped with group index directly. The other slots are 614 * shared between the all of groups. While adding a MAC address, 615 * it will try to set the reserved slots first, then the shared slots. 616 */ 617 slot = -1; 618 if (igb->unicst_addr[rx_group->index].mac.set == 1) { 619 /* 620 * The reserved slot for current group is used, find the free 621 * slots in the shared slots. 622 */ 623 for (i = igb->num_rx_groups; i < igb->unicst_total; i++) { 624 if (igb->unicst_addr[i].mac.set == 0) { 625 slot = i; 626 break; 627 } 628 } 629 } else 630 slot = rx_group->index; 631 632 if (slot == -1) { 633 /* no slots available in the shared slots */ 634 mutex_exit(&igb->gen_lock); 635 return (ENOSPC); 636 } 637 638 /* Set VMDq according to the mode supported by hardware. */ 639 e1000_rar_set_vmdq(hw, mac_addr, slot, igb->vmdq_mode, rx_group->index); 640 641 bcopy(mac_addr, igb->unicst_addr[slot].mac.addr, ETHERADDRL); 642 igb->unicst_addr[slot].mac.group_index = rx_group->index; 643 igb->unicst_addr[slot].mac.set = 1; 644 igb->unicst_avail--; 645 646 mutex_exit(&igb->gen_lock); 647 648 return (0); 649 } 650 651 /* 652 * Remove a MAC address from the specified RX group. 653 */ 654 static int 655 igb_remmac(void *arg, const uint8_t *mac_addr) 656 { 657 igb_rx_group_t *rx_group = (igb_rx_group_t *)arg; 658 igb_t *igb = rx_group->igb; 659 struct e1000_hw *hw = &igb->hw; 660 int slot; 661 662 mutex_enter(&igb->gen_lock); 663 664 if (igb->igb_state & IGB_SUSPENDED) { 665 mutex_exit(&igb->gen_lock); 666 return (ECANCELED); 667 } 668 669 slot = igb_unicst_find(igb, mac_addr); 670 if (slot == -1) { 671 mutex_exit(&igb->gen_lock); 672 return (EINVAL); 673 } 674 675 if (igb->unicst_addr[slot].mac.set == 0) { 676 mutex_exit(&igb->gen_lock); 677 return (EINVAL); 678 } 679 680 /* Clear the MAC ddress in the slot */ 681 e1000_rar_clear(hw, slot); 682 igb->unicst_addr[slot].mac.set = 0; 683 igb->unicst_avail++; 684 685 mutex_exit(&igb->gen_lock); 686 687 return (0); 688 } 689 690 /* 691 * Enable interrupt on the specificed rx ring. 692 */ 693 int 694 igb_rx_ring_intr_enable(mac_intr_handle_t intrh) 695 { 696 igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh; 697 igb_t *igb = rx_ring->igb; 698 struct e1000_hw *hw = &igb->hw; 699 uint32_t index = rx_ring->index; 700 701 if (igb->intr_type == DDI_INTR_TYPE_MSIX) { 702 /* Interrupt enabling for MSI-X */ 703 igb->eims_mask |= (E1000_EICR_RX_QUEUE0 << index); 704 E1000_WRITE_REG(hw, E1000_EIMS, igb->eims_mask); 705 E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask); 706 } else { 707 ASSERT(index == 0); 708 /* Interrupt enabling for MSI and legacy */ 709 igb->ims_mask |= E1000_IMS_RXT0; 710 E1000_WRITE_REG(hw, E1000_IMS, igb->ims_mask); 711 } 712 713 E1000_WRITE_FLUSH(hw); 714 715 return (0); 716 } 717 718 /* 719 * Disable interrupt on the specificed rx ring. 720 */ 721 int 722 igb_rx_ring_intr_disable(mac_intr_handle_t intrh) 723 { 724 igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh; 725 igb_t *igb = rx_ring->igb; 726 struct e1000_hw *hw = &igb->hw; 727 uint32_t index = rx_ring->index; 728 729 if (igb->intr_type == DDI_INTR_TYPE_MSIX) { 730 /* Interrupt disabling for MSI-X */ 731 igb->eims_mask &= ~(E1000_EICR_RX_QUEUE0 << index); 732 E1000_WRITE_REG(hw, E1000_EIMC, 733 (E1000_EICR_RX_QUEUE0 << index)); 734 E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask); 735 } else { 736 ASSERT(index == 0); 737 /* Interrupt disabling for MSI and legacy */ 738 igb->ims_mask &= ~E1000_IMS_RXT0; 739 E1000_WRITE_REG(hw, E1000_IMC, E1000_IMS_RXT0); 740 } 741 742 E1000_WRITE_FLUSH(hw); 743 744 return (0); 745 } 746 747 /* 748 * Get the global ring index by a ring index within a group. 749 */ 750 int 751 igb_get_rx_ring_index(igb_t *igb, int gindex, int rindex) 752 { 753 igb_rx_ring_t *rx_ring; 754 int i; 755 756 for (i = 0; i < igb->num_rx_rings; i++) { 757 rx_ring = &igb->rx_rings[i]; 758 if (rx_ring->group_index == gindex) 759 rindex--; 760 if (rindex < 0) 761 return (i); 762 } 763 764 return (-1); 765 } 766 767 static int 768 igb_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num) 769 { 770 igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)rh; 771 772 mutex_enter(&rx_ring->rx_lock); 773 rx_ring->ring_gen_num = mr_gen_num; 774 mutex_exit(&rx_ring->rx_lock); 775 return (0); 776 } 777 778 /* 779 * Callback funtion for MAC layer to register all rings. 780 */ 781 /* ARGSUSED */ 782 void 783 igb_fill_ring(void *arg, mac_ring_type_t rtype, const int rg_index, 784 const int index, mac_ring_info_t *infop, mac_ring_handle_t rh) 785 { 786 igb_t *igb = (igb_t *)arg; 787 mac_intr_t *mintr = &infop->mri_intr; 788 789 switch (rtype) { 790 case MAC_RING_TYPE_RX: { 791 igb_rx_ring_t *rx_ring; 792 int global_index; 793 794 /* 795 * 'index' is the ring index within the group. 796 * We need the global ring index by searching in group. 797 */ 798 global_index = igb_get_rx_ring_index(igb, rg_index, index); 799 800 ASSERT(global_index >= 0); 801 802 rx_ring = &igb->rx_rings[global_index]; 803 rx_ring->ring_handle = rh; 804 805 infop->mri_driver = (mac_ring_driver_t)rx_ring; 806 infop->mri_start = igb_ring_start; 807 infop->mri_stop = NULL; 808 infop->mri_poll = (mac_ring_poll_t)igb_rx_ring_poll; 809 infop->mri_stat = igb_rx_ring_stat; 810 811 mintr->mi_handle = (mac_intr_handle_t)rx_ring; 812 mintr->mi_enable = igb_rx_ring_intr_enable; 813 mintr->mi_disable = igb_rx_ring_intr_disable; 814 if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) { 815 mintr->mi_ddi_handle = 816 igb->htable[rx_ring->intr_vector]; 817 } 818 break; 819 } 820 case MAC_RING_TYPE_TX: { 821 ASSERT(index < igb->num_tx_rings); 822 823 igb_tx_ring_t *tx_ring = &igb->tx_rings[index]; 824 tx_ring->ring_handle = rh; 825 826 infop->mri_driver = (mac_ring_driver_t)tx_ring; 827 infop->mri_start = NULL; 828 infop->mri_stop = NULL; 829 infop->mri_tx = igb_tx_ring_send; 830 infop->mri_stat = igb_tx_ring_stat; 831 if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) { 832 mintr->mi_ddi_handle = 833 igb->htable[tx_ring->intr_vector]; 834 } 835 break; 836 } 837 default: 838 break; 839 } 840 } 841 842 void 843 igb_fill_group(void *arg, mac_ring_type_t rtype, const int index, 844 mac_group_info_t *infop, mac_group_handle_t gh) 845 { 846 igb_t *igb = (igb_t *)arg; 847 848 switch (rtype) { 849 case MAC_RING_TYPE_RX: { 850 igb_rx_group_t *rx_group; 851 852 ASSERT((index >= 0) && (index < igb->num_rx_groups)); 853 854 rx_group = &igb->rx_groups[index]; 855 rx_group->group_handle = gh; 856 857 infop->mgi_driver = (mac_group_driver_t)rx_group; 858 infop->mgi_start = NULL; 859 infop->mgi_stop = NULL; 860 infop->mgi_addmac = igb_addmac; 861 infop->mgi_remmac = igb_remmac; 862 infop->mgi_count = (igb->num_rx_rings / igb->num_rx_groups); 863 864 break; 865 } 866 case MAC_RING_TYPE_TX: 867 break; 868 default: 869 break; 870 } 871 } 872 873 static int 874 igb_led_set(void *arg, mac_led_mode_t mode, uint_t flags) 875 { 876 igb_t *igb = arg; 877 878 if (flags != 0) 879 return (EINVAL); 880 881 if (mode != MAC_LED_DEFAULT && 882 mode != MAC_LED_IDENT && 883 mode != MAC_LED_OFF && 884 mode != MAC_LED_ON) 885 return (ENOTSUP); 886 887 if (mode != MAC_LED_DEFAULT && !igb->igb_led_setup) { 888 if (e1000_setup_led(&igb->hw) != E1000_SUCCESS) 889 return (EIO); 890 891 igb->igb_led_setup = B_TRUE; 892 } 893 894 switch (mode) { 895 case MAC_LED_DEFAULT: 896 if (igb->igb_led_setup) { 897 if (e1000_cleanup_led(&igb->hw) != E1000_SUCCESS) 898 return (EIO); 899 igb->igb_led_setup = B_FALSE; 900 } 901 break; 902 case MAC_LED_IDENT: 903 if (e1000_blink_led(&igb->hw) != E1000_SUCCESS) 904 return (EIO); 905 break; 906 case MAC_LED_OFF: 907 if (e1000_led_off(&igb->hw) != E1000_SUCCESS) 908 return (EIO); 909 break; 910 case MAC_LED_ON: 911 if (e1000_led_on(&igb->hw) != E1000_SUCCESS) 912 return (EIO); 913 break; 914 default: 915 return (ENOTSUP); 916 } 917 918 return (0); 919 } 920 921 /* 922 * Obtain the MAC's capabilities and associated data from 923 * the driver. 924 */ 925 boolean_t 926 igb_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 927 { 928 igb_t *igb = (igb_t *)arg; 929 930 switch (cap) { 931 case MAC_CAPAB_HCKSUM: { 932 uint32_t *tx_hcksum_flags = cap_data; 933 934 /* 935 * We advertise our capabilities only if tx hcksum offload is 936 * enabled. On receive, the stack will accept checksummed 937 * packets anyway, even if we haven't said we can deliver 938 * them. 939 */ 940 if (!igb->tx_hcksum_enable) 941 return (B_FALSE); 942 943 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM; 944 break; 945 } 946 case MAC_CAPAB_LSO: { 947 mac_capab_lso_t *cap_lso = cap_data; 948 949 if (igb->lso_enable) { 950 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4 | 951 LSO_TX_BASIC_TCP_IPV6; 952 cap_lso->lso_basic_tcp_ipv4.lso_max = IGB_LSO_MAXLEN; 953 cap_lso->lso_basic_tcp_ipv6.lso_max = IGB_LSO_MAXLEN; 954 break; 955 } else { 956 return (B_FALSE); 957 } 958 } 959 case MAC_CAPAB_RINGS: { 960 mac_capab_rings_t *cap_rings = cap_data; 961 962 switch (cap_rings->mr_type) { 963 case MAC_RING_TYPE_RX: 964 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 965 cap_rings->mr_rnum = igb->num_rx_rings; 966 cap_rings->mr_gnum = igb->num_rx_groups; 967 cap_rings->mr_rget = igb_fill_ring; 968 cap_rings->mr_gget = igb_fill_group; 969 cap_rings->mr_gaddring = NULL; 970 cap_rings->mr_gremring = NULL; 971 972 break; 973 case MAC_RING_TYPE_TX: 974 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 975 cap_rings->mr_rnum = igb->num_tx_rings; 976 cap_rings->mr_gnum = 0; 977 cap_rings->mr_rget = igb_fill_ring; 978 cap_rings->mr_gget = NULL; 979 980 break; 981 default: 982 break; 983 } 984 break; 985 } 986 987 case MAC_CAPAB_LED: { 988 mac_capab_led_t *cap_led = cap_data; 989 990 cap_led->mcl_flags = 0; 991 cap_led->mcl_modes = MAC_LED_DEFAULT; 992 if (igb->hw.mac.ops.blink_led != NULL && 993 igb->hw.mac.ops.blink_led != e1000_null_ops_generic) { 994 cap_led->mcl_modes |= MAC_LED_IDENT; 995 } 996 if (igb->hw.mac.ops.led_off != NULL && 997 igb->hw.mac.ops.led_off != e1000_null_ops_generic) { 998 cap_led->mcl_modes |= MAC_LED_OFF; 999 } 1000 if (igb->hw.mac.ops.led_on != NULL && 1001 igb->hw.mac.ops.led_on != e1000_null_ops_generic) { 1002 cap_led->mcl_modes |= MAC_LED_ON; 1003 } 1004 cap_led->mcl_set = igb_led_set; 1005 break; 1006 } 1007 1008 default: 1009 return (B_FALSE); 1010 } 1011 return (B_TRUE); 1012 } 1013 1014 int 1015 igb_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 1016 uint_t pr_valsize, const void *pr_val) 1017 { 1018 igb_t *igb = (igb_t *)arg; 1019 struct e1000_hw *hw = &igb->hw; 1020 int err = 0; 1021 uint32_t flow_control; 1022 uint32_t cur_mtu, new_mtu; 1023 uint32_t rx_size; 1024 uint32_t tx_size; 1025 1026 mutex_enter(&igb->gen_lock); 1027 if (igb->igb_state & IGB_SUSPENDED) { 1028 mutex_exit(&igb->gen_lock); 1029 return (ECANCELED); 1030 } 1031 1032 if (igb->loopback_mode != IGB_LB_NONE && igb_param_locked(pr_num)) { 1033 /* 1034 * All en_* parameters are locked (read-only) 1035 * while the device is in any sort of loopback mode. 1036 */ 1037 mutex_exit(&igb->gen_lock); 1038 return (EBUSY); 1039 } 1040 1041 switch (pr_num) { 1042 case MAC_PROP_EN_1000FDX_CAP: 1043 /* read/write on copper, read-only on serdes */ 1044 if (hw->phy.media_type != e1000_media_type_copper) { 1045 err = ENOTSUP; 1046 break; 1047 } 1048 igb->param_en_1000fdx_cap = *(uint8_t *)pr_val; 1049 igb->param_adv_1000fdx_cap = *(uint8_t *)pr_val; 1050 goto setup_link; 1051 case MAC_PROP_EN_100FDX_CAP: 1052 if (hw->phy.media_type != e1000_media_type_copper) { 1053 err = ENOTSUP; 1054 break; 1055 } 1056 igb->param_en_100fdx_cap = *(uint8_t *)pr_val; 1057 igb->param_adv_100fdx_cap = *(uint8_t *)pr_val; 1058 goto setup_link; 1059 case MAC_PROP_EN_100HDX_CAP: 1060 if (hw->phy.media_type != e1000_media_type_copper) { 1061 err = ENOTSUP; 1062 break; 1063 } 1064 igb->param_en_100hdx_cap = *(uint8_t *)pr_val; 1065 igb->param_adv_100hdx_cap = *(uint8_t *)pr_val; 1066 goto setup_link; 1067 case MAC_PROP_EN_10FDX_CAP: 1068 if (hw->phy.media_type != e1000_media_type_copper) { 1069 err = ENOTSUP; 1070 break; 1071 } 1072 igb->param_en_10fdx_cap = *(uint8_t *)pr_val; 1073 igb->param_adv_10fdx_cap = *(uint8_t *)pr_val; 1074 goto setup_link; 1075 case MAC_PROP_EN_10HDX_CAP: 1076 if (hw->phy.media_type != e1000_media_type_copper) { 1077 err = ENOTSUP; 1078 break; 1079 } 1080 igb->param_en_10hdx_cap = *(uint8_t *)pr_val; 1081 igb->param_adv_10hdx_cap = *(uint8_t *)pr_val; 1082 goto setup_link; 1083 case MAC_PROP_AUTONEG: 1084 if (hw->phy.media_type != e1000_media_type_copper) { 1085 err = ENOTSUP; 1086 break; 1087 } 1088 igb->param_adv_autoneg_cap = *(uint8_t *)pr_val; 1089 goto setup_link; 1090 case MAC_PROP_FLOWCTRL: 1091 bcopy(pr_val, &flow_control, sizeof (flow_control)); 1092 1093 switch (flow_control) { 1094 default: 1095 err = EINVAL; 1096 break; 1097 case LINK_FLOWCTRL_NONE: 1098 hw->fc.requested_mode = e1000_fc_none; 1099 break; 1100 case LINK_FLOWCTRL_RX: 1101 hw->fc.requested_mode = e1000_fc_rx_pause; 1102 break; 1103 case LINK_FLOWCTRL_TX: 1104 hw->fc.requested_mode = e1000_fc_tx_pause; 1105 break; 1106 case LINK_FLOWCTRL_BI: 1107 hw->fc.requested_mode = e1000_fc_full; 1108 break; 1109 } 1110 setup_link: 1111 if (err == 0) { 1112 if (igb_setup_link(igb, B_TRUE) != IGB_SUCCESS) 1113 err = EINVAL; 1114 } 1115 break; 1116 case MAC_PROP_ADV_1000FDX_CAP: 1117 case MAC_PROP_ADV_1000HDX_CAP: 1118 case MAC_PROP_ADV_100T4_CAP: 1119 case MAC_PROP_ADV_100FDX_CAP: 1120 case MAC_PROP_ADV_100HDX_CAP: 1121 case MAC_PROP_ADV_10FDX_CAP: 1122 case MAC_PROP_ADV_10HDX_CAP: 1123 case MAC_PROP_EN_1000HDX_CAP: 1124 case MAC_PROP_EN_100T4_CAP: 1125 case MAC_PROP_STATUS: 1126 case MAC_PROP_SPEED: 1127 case MAC_PROP_DUPLEX: 1128 case MAC_PROP_MEDIA: 1129 err = ENOTSUP; /* read-only prop. Can't set this. */ 1130 break; 1131 case MAC_PROP_MTU: 1132 /* adapter must be stopped for an MTU change */ 1133 if (igb->igb_state & IGB_STARTED) { 1134 err = EBUSY; 1135 break; 1136 } 1137 1138 cur_mtu = igb->default_mtu; 1139 bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 1140 if (new_mtu == cur_mtu) { 1141 err = 0; 1142 break; 1143 } 1144 1145 if (new_mtu < MIN_MTU || new_mtu > MAX_MTU) { 1146 err = EINVAL; 1147 break; 1148 } 1149 1150 err = mac_maxsdu_update(igb->mac_hdl, new_mtu); 1151 if (err == 0) { 1152 igb->default_mtu = new_mtu; 1153 igb->max_frame_size = igb->default_mtu + 1154 sizeof (struct ether_vlan_header) + ETHERFCSL; 1155 1156 /* 1157 * Set rx buffer size 1158 */ 1159 rx_size = igb->max_frame_size + IPHDR_ALIGN_ROOM; 1160 igb->rx_buf_size = ((rx_size >> 10) + ((rx_size & 1161 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 1162 1163 /* 1164 * Set tx buffer size 1165 */ 1166 tx_size = igb->max_frame_size; 1167 igb->tx_buf_size = ((tx_size >> 10) + ((tx_size & 1168 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 1169 } 1170 break; 1171 case MAC_PROP_PRIVATE: 1172 err = igb_set_priv_prop(igb, pr_name, pr_valsize, pr_val); 1173 break; 1174 default: 1175 err = ENOTSUP; 1176 break; 1177 } 1178 1179 mutex_exit(&igb->gen_lock); 1180 1181 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) { 1182 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED); 1183 return (EIO); 1184 } 1185 1186 return (err); 1187 } 1188 1189 int 1190 igb_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 1191 uint_t pr_valsize, void *pr_val) 1192 { 1193 igb_t *igb = (igb_t *)arg; 1194 struct e1000_hw *hw = &igb->hw; 1195 int err = 0; 1196 uint32_t flow_control; 1197 uint64_t tmp = 0; 1198 1199 switch (pr_num) { 1200 case MAC_PROP_DUPLEX: 1201 ASSERT(pr_valsize >= sizeof (link_duplex_t)); 1202 bcopy(&igb->link_duplex, pr_val, sizeof (link_duplex_t)); 1203 break; 1204 case MAC_PROP_SPEED: 1205 ASSERT(pr_valsize >= sizeof (uint64_t)); 1206 tmp = igb->link_speed * 1000000ull; 1207 bcopy(&tmp, pr_val, sizeof (tmp)); 1208 break; 1209 case MAC_PROP_AUTONEG: 1210 ASSERT(pr_valsize >= sizeof (uint8_t)); 1211 *(uint8_t *)pr_val = igb->param_adv_autoneg_cap; 1212 break; 1213 case MAC_PROP_FLOWCTRL: 1214 ASSERT(pr_valsize >= sizeof (uint32_t)); 1215 switch (hw->fc.requested_mode) { 1216 case e1000_fc_none: 1217 flow_control = LINK_FLOWCTRL_NONE; 1218 break; 1219 case e1000_fc_rx_pause: 1220 flow_control = LINK_FLOWCTRL_RX; 1221 break; 1222 case e1000_fc_tx_pause: 1223 flow_control = LINK_FLOWCTRL_TX; 1224 break; 1225 case e1000_fc_full: 1226 flow_control = LINK_FLOWCTRL_BI; 1227 break; 1228 } 1229 bcopy(&flow_control, pr_val, sizeof (flow_control)); 1230 break; 1231 case MAC_PROP_ADV_1000FDX_CAP: 1232 *(uint8_t *)pr_val = igb->param_adv_1000fdx_cap; 1233 break; 1234 case MAC_PROP_EN_1000FDX_CAP: 1235 *(uint8_t *)pr_val = igb->param_en_1000fdx_cap; 1236 break; 1237 case MAC_PROP_ADV_1000HDX_CAP: 1238 *(uint8_t *)pr_val = igb->param_adv_1000hdx_cap; 1239 break; 1240 case MAC_PROP_EN_1000HDX_CAP: 1241 *(uint8_t *)pr_val = igb->param_en_1000hdx_cap; 1242 break; 1243 case MAC_PROP_ADV_100T4_CAP: 1244 *(uint8_t *)pr_val = igb->param_adv_100t4_cap; 1245 break; 1246 case MAC_PROP_EN_100T4_CAP: 1247 *(uint8_t *)pr_val = igb->param_en_100t4_cap; 1248 break; 1249 case MAC_PROP_ADV_100FDX_CAP: 1250 *(uint8_t *)pr_val = igb->param_adv_100fdx_cap; 1251 break; 1252 case MAC_PROP_EN_100FDX_CAP: 1253 *(uint8_t *)pr_val = igb->param_en_100fdx_cap; 1254 break; 1255 case MAC_PROP_ADV_100HDX_CAP: 1256 *(uint8_t *)pr_val = igb->param_adv_100hdx_cap; 1257 break; 1258 case MAC_PROP_EN_100HDX_CAP: 1259 *(uint8_t *)pr_val = igb->param_en_100hdx_cap; 1260 break; 1261 case MAC_PROP_ADV_10FDX_CAP: 1262 *(uint8_t *)pr_val = igb->param_adv_10fdx_cap; 1263 break; 1264 case MAC_PROP_EN_10FDX_CAP: 1265 *(uint8_t *)pr_val = igb->param_en_10fdx_cap; 1266 break; 1267 case MAC_PROP_ADV_10HDX_CAP: 1268 *(uint8_t *)pr_val = igb->param_adv_10hdx_cap; 1269 break; 1270 case MAC_PROP_EN_10HDX_CAP: 1271 *(uint8_t *)pr_val = igb->param_en_10hdx_cap; 1272 break; 1273 case MAC_PROP_MEDIA: 1274 *(mac_ether_media_t *)pr_val = e1000_link_to_media(hw, 1275 igb->link_speed); 1276 break; 1277 case MAC_PROP_PRIVATE: 1278 err = igb_get_priv_prop(igb, pr_name, pr_valsize, pr_val); 1279 break; 1280 default: 1281 err = ENOTSUP; 1282 break; 1283 } 1284 return (err); 1285 } 1286 1287 void 1288 igb_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num, 1289 mac_prop_info_handle_t prh) 1290 { 1291 igb_t *igb = (igb_t *)arg; 1292 struct e1000_hw *hw = &igb->hw; 1293 uint16_t phy_status, phy_ext_status; 1294 1295 switch (pr_num) { 1296 case MAC_PROP_DUPLEX: 1297 case MAC_PROP_SPEED: 1298 case MAC_PROP_ADV_1000FDX_CAP: 1299 case MAC_PROP_ADV_1000HDX_CAP: 1300 case MAC_PROP_EN_1000HDX_CAP: 1301 case MAC_PROP_ADV_100T4_CAP: 1302 case MAC_PROP_EN_100T4_CAP: 1303 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1304 break; 1305 1306 case MAC_PROP_EN_1000FDX_CAP: 1307 if (hw->phy.media_type != e1000_media_type_copper) { 1308 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1309 } else { 1310 (void) e1000_read_phy_reg(hw, PHY_EXT_STATUS, 1311 &phy_ext_status); 1312 mac_prop_info_set_default_uint8(prh, 1313 ((phy_ext_status & IEEE_ESR_1000T_FD_CAPS) || 1314 (phy_ext_status & IEEE_ESR_1000X_FD_CAPS)) ? 1 : 0); 1315 } 1316 break; 1317 1318 case MAC_PROP_ADV_100FDX_CAP: 1319 case MAC_PROP_EN_100FDX_CAP: 1320 if (hw->phy.media_type != e1000_media_type_copper) { 1321 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1322 } else { 1323 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 1324 mac_prop_info_set_default_uint8(prh, 1325 ((phy_status & MII_SR_100X_FD_CAPS) || 1326 (phy_status & MII_SR_100T2_FD_CAPS)) ? 1 : 0); 1327 } 1328 break; 1329 1330 case MAC_PROP_ADV_100HDX_CAP: 1331 case MAC_PROP_EN_100HDX_CAP: 1332 if (hw->phy.media_type != e1000_media_type_copper) { 1333 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1334 } else { 1335 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 1336 mac_prop_info_set_default_uint8(prh, 1337 ((phy_status & MII_SR_100X_HD_CAPS) || 1338 (phy_status & MII_SR_100T2_HD_CAPS)) ? 1 : 0); 1339 } 1340 break; 1341 1342 case MAC_PROP_ADV_10FDX_CAP: 1343 case MAC_PROP_EN_10FDX_CAP: 1344 if (hw->phy.media_type != e1000_media_type_copper) { 1345 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1346 } else { 1347 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 1348 mac_prop_info_set_default_uint8(prh, 1349 (phy_status & MII_SR_10T_FD_CAPS) ? 1 : 0); 1350 } 1351 break; 1352 1353 case MAC_PROP_ADV_10HDX_CAP: 1354 case MAC_PROP_EN_10HDX_CAP: 1355 if (hw->phy.media_type != e1000_media_type_copper) { 1356 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1357 } else { 1358 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 1359 mac_prop_info_set_default_uint8(prh, 1360 (phy_status & MII_SR_10T_HD_CAPS) ? 1 : 0); 1361 } 1362 break; 1363 1364 case MAC_PROP_AUTONEG: 1365 if (hw->phy.media_type != e1000_media_type_copper) { 1366 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1367 } else { 1368 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 1369 mac_prop_info_set_default_uint8(prh, 1370 (phy_status & MII_SR_AUTONEG_CAPS) ? 1 : 0); 1371 } 1372 break; 1373 1374 case MAC_PROP_FLOWCTRL: 1375 mac_prop_info_set_default_link_flowctrl(prh, LINK_FLOWCTRL_BI); 1376 break; 1377 1378 case MAC_PROP_MTU: 1379 mac_prop_info_set_range_uint32(prh, MIN_MTU, MAX_MTU); 1380 break; 1381 1382 case MAC_PROP_PRIVATE: 1383 igb_priv_prop_info(igb, pr_name, prh); 1384 break; 1385 } 1386 1387 } 1388 1389 boolean_t 1390 igb_param_locked(mac_prop_id_t pr_num) 1391 { 1392 /* 1393 * All en_* parameters are locked (read-only) while 1394 * the device is in any sort of loopback mode ... 1395 */ 1396 switch (pr_num) { 1397 case MAC_PROP_EN_1000FDX_CAP: 1398 case MAC_PROP_EN_1000HDX_CAP: 1399 case MAC_PROP_EN_100T4_CAP: 1400 case MAC_PROP_EN_100FDX_CAP: 1401 case MAC_PROP_EN_100HDX_CAP: 1402 case MAC_PROP_EN_10FDX_CAP: 1403 case MAC_PROP_EN_10HDX_CAP: 1404 case MAC_PROP_AUTONEG: 1405 case MAC_PROP_FLOWCTRL: 1406 return (B_TRUE); 1407 } 1408 return (B_FALSE); 1409 } 1410 1411 /* ARGSUSED */ 1412 int 1413 igb_set_priv_prop(igb_t *igb, const char *pr_name, 1414 uint_t pr_valsize, const void *pr_val) 1415 { 1416 int err = 0; 1417 long result; 1418 struct e1000_hw *hw = &igb->hw; 1419 int i; 1420 1421 if (strcmp(pr_name, "_eee_support") == 0) { 1422 if (pr_val == NULL) 1423 return (EINVAL); 1424 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1425 switch (result) { 1426 case 0: 1427 case 1: 1428 /* 1429 * For now, only supported on I350/I354. 1430 * Add new mac.type values (or use < instead) 1431 * as new cards offer up EEE. 1432 */ 1433 switch (hw->mac.type) { 1434 case e1000_i350: 1435 /* Must set this prior to the set call. */ 1436 hw->dev_spec._82575.eee_disable = !result; 1437 if (e1000_set_eee_i350(hw, result, 1438 result) != E1000_SUCCESS) 1439 err = EIO; 1440 break; 1441 case e1000_i354: 1442 /* Must set this prior to the set call. */ 1443 hw->dev_spec._82575.eee_disable = !result; 1444 if (e1000_set_eee_i354(hw, result, 1445 result) != E1000_SUCCESS) 1446 err = EIO; 1447 break; 1448 default: 1449 return (ENXIO); 1450 } 1451 break; 1452 default: 1453 err = EINVAL; 1454 /* FALLTHRU */ 1455 } 1456 return (err); 1457 } 1458 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 1459 if (pr_val == NULL) { 1460 err = EINVAL; 1461 return (err); 1462 } 1463 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1464 if (result < MIN_TX_COPY_THRESHOLD || 1465 result > MAX_TX_COPY_THRESHOLD) 1466 err = EINVAL; 1467 else { 1468 igb->tx_copy_thresh = (uint32_t)result; 1469 } 1470 return (err); 1471 } 1472 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 1473 if (pr_val == NULL) { 1474 err = EINVAL; 1475 return (err); 1476 } 1477 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1478 if (result < MIN_TX_RECYCLE_THRESHOLD || 1479 result > MAX_TX_RECYCLE_THRESHOLD) 1480 err = EINVAL; 1481 else { 1482 igb->tx_recycle_thresh = (uint32_t)result; 1483 } 1484 return (err); 1485 } 1486 if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 1487 if (pr_val == NULL) { 1488 err = EINVAL; 1489 return (err); 1490 } 1491 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1492 if (result < MIN_TX_OVERLOAD_THRESHOLD || 1493 result > MAX_TX_OVERLOAD_THRESHOLD) 1494 err = EINVAL; 1495 else { 1496 igb->tx_overload_thresh = (uint32_t)result; 1497 } 1498 return (err); 1499 } 1500 if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 1501 if (pr_val == NULL) { 1502 err = EINVAL; 1503 return (err); 1504 } 1505 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1506 if (result < MIN_TX_RESCHED_THRESHOLD || 1507 result > MAX_TX_RESCHED_THRESHOLD || 1508 result > igb->tx_ring_size) 1509 err = EINVAL; 1510 else { 1511 igb->tx_resched_thresh = (uint32_t)result; 1512 } 1513 return (err); 1514 } 1515 if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 1516 if (pr_val == NULL) { 1517 err = EINVAL; 1518 return (err); 1519 } 1520 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1521 if (result < MIN_RX_COPY_THRESHOLD || 1522 result > MAX_RX_COPY_THRESHOLD) 1523 err = EINVAL; 1524 else { 1525 igb->rx_copy_thresh = (uint32_t)result; 1526 } 1527 return (err); 1528 } 1529 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 1530 if (pr_val == NULL) { 1531 err = EINVAL; 1532 return (err); 1533 } 1534 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1535 if (result < MIN_RX_LIMIT_PER_INTR || 1536 result > MAX_RX_LIMIT_PER_INTR) 1537 err = EINVAL; 1538 else { 1539 igb->rx_limit_per_intr = (uint32_t)result; 1540 } 1541 return (err); 1542 } 1543 if (strcmp(pr_name, "_intr_throttling") == 0) { 1544 if (pr_val == NULL) { 1545 err = EINVAL; 1546 return (err); 1547 } 1548 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1549 1550 if (result < igb->capab->min_intr_throttle || 1551 result > igb->capab->max_intr_throttle) 1552 err = EINVAL; 1553 else { 1554 igb->intr_throttling[0] = (uint32_t)result; 1555 1556 for (i = 0; i < MAX_NUM_EITR; i++) 1557 igb->intr_throttling[i] = 1558 igb->intr_throttling[0]; 1559 1560 /* Set interrupt throttling rate */ 1561 for (i = 0; i < igb->intr_cnt; i++) 1562 E1000_WRITE_REG(hw, E1000_EITR(i), 1563 igb->intr_throttling[i]); 1564 } 1565 return (err); 1566 } 1567 return (ENOTSUP); 1568 } 1569 1570 int 1571 igb_get_priv_prop(igb_t *igb, const char *pr_name, uint_t pr_valsize, 1572 void *pr_val) 1573 { 1574 int value; 1575 1576 if (strcmp(pr_name, "_adv_pause_cap") == 0) { 1577 value = igb->param_adv_pause_cap; 1578 } else if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 1579 value = igb->param_adv_asym_pause_cap; 1580 } else if (strcmp(pr_name, "_eee_support") == 0) { 1581 /* 1582 * For now, only supported on I350. Add new mac.type values 1583 * (or use < instead) as new cards offer up EEE. 1584 */ 1585 switch (igb->hw.mac.type) { 1586 case e1000_i350: 1587 case e1000_i354: 1588 value = !(igb->hw.dev_spec._82575.eee_disable); 1589 break; 1590 default: 1591 value = 0; 1592 } 1593 } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 1594 value = igb->tx_copy_thresh; 1595 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 1596 value = igb->tx_recycle_thresh; 1597 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 1598 value = igb->tx_overload_thresh; 1599 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 1600 value = igb->tx_resched_thresh; 1601 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 1602 value = igb->rx_copy_thresh; 1603 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 1604 value = igb->rx_limit_per_intr; 1605 } else if (strcmp(pr_name, "_intr_throttling") == 0) { 1606 value = igb->intr_throttling[0]; 1607 } else { 1608 return (ENOTSUP); 1609 } 1610 1611 (void) snprintf(pr_val, pr_valsize, "%d", value); 1612 return (0); 1613 } 1614 1615 void 1616 igb_priv_prop_info(igb_t *igb, const char *pr_name, mac_prop_info_handle_t prh) 1617 { 1618 char valstr[64]; 1619 int value; 1620 1621 if (strcmp(pr_name, "_adv_pause_cap") == 0 || 1622 strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 1623 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1624 return; 1625 } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 1626 value = DEFAULT_TX_COPY_THRESHOLD; 1627 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 1628 value = DEFAULT_TX_RECYCLE_THRESHOLD; 1629 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 1630 value = DEFAULT_TX_OVERLOAD_THRESHOLD; 1631 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 1632 value = DEFAULT_TX_RESCHED_THRESHOLD; 1633 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 1634 value = DEFAULT_RX_COPY_THRESHOLD; 1635 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 1636 value = DEFAULT_RX_LIMIT_PER_INTR; 1637 } else if (strcmp(pr_name, "_intr_throttling") == 0) { 1638 value = igb->capab->def_intr_throttle; 1639 } else { 1640 return; 1641 } 1642 1643 (void) snprintf(valstr, sizeof (valstr), "%d", value); 1644 mac_prop_info_set_default_str(prh, valstr); 1645 } 1646