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