1 /* 2 * CDDL HEADER START 3 * 4 * Copyright(c) 2007-2009 Intel Corporation. All rights reserved. 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #include "ixgbe_sw.h" 29 30 /* 31 * Retrieve a value for one of the statistics. 32 */ 33 int 34 ixgbe_m_stat(void *arg, uint_t stat, uint64_t *val) 35 { 36 ixgbe_t *ixgbe = (ixgbe_t *)arg; 37 struct ixgbe_hw *hw = &ixgbe->hw; 38 ixgbe_stat_t *ixgbe_ks; 39 int i; 40 41 ixgbe_ks = (ixgbe_stat_t *)ixgbe->ixgbe_ks->ks_data; 42 43 mutex_enter(&ixgbe->gen_lock); 44 45 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 46 mutex_exit(&ixgbe->gen_lock); 47 return (ECANCELED); 48 } 49 50 switch (stat) { 51 case MAC_STAT_IFSPEED: 52 *val = ixgbe->link_speed * 1000000ull; 53 break; 54 55 case MAC_STAT_MULTIRCV: 56 ixgbe_ks->mprc.value.ui64 += 57 IXGBE_READ_REG(hw, IXGBE_MPRC); 58 *val = ixgbe_ks->mprc.value.ui64; 59 break; 60 61 case MAC_STAT_BRDCSTRCV: 62 ixgbe_ks->bprc.value.ui64 += 63 IXGBE_READ_REG(hw, IXGBE_BPRC); 64 *val = ixgbe_ks->bprc.value.ui64; 65 break; 66 67 case MAC_STAT_MULTIXMT: 68 ixgbe_ks->mptc.value.ui64 += 69 IXGBE_READ_REG(hw, IXGBE_MPTC); 70 *val = ixgbe_ks->mptc.value.ui64; 71 break; 72 73 case MAC_STAT_BRDCSTXMT: 74 ixgbe_ks->bptc.value.ui64 += 75 IXGBE_READ_REG(hw, IXGBE_BPTC); 76 *val = ixgbe_ks->bptc.value.ui64; 77 break; 78 79 case MAC_STAT_NORCVBUF: 80 for (i = 0; i < 8; i++) { 81 ixgbe_ks->rnbc.value.ui64 += 82 IXGBE_READ_REG(hw, IXGBE_RNBC(i)); 83 } 84 *val = ixgbe_ks->rnbc.value.ui64; 85 break; 86 87 case MAC_STAT_IERRORS: 88 ixgbe_ks->crcerrs.value.ui64 += 89 IXGBE_READ_REG(hw, IXGBE_CRCERRS); 90 ixgbe_ks->illerrc.value.ui64 += 91 IXGBE_READ_REG(hw, IXGBE_ILLERRC); 92 ixgbe_ks->errbc.value.ui64 += 93 IXGBE_READ_REG(hw, IXGBE_ERRBC); 94 ixgbe_ks->rlec.value.ui64 += 95 IXGBE_READ_REG(hw, IXGBE_RLEC); 96 *val = ixgbe_ks->crcerrs.value.ui64 + 97 ixgbe_ks->illerrc.value.ui64 + 98 ixgbe_ks->errbc.value.ui64 + 99 ixgbe_ks->rlec.value.ui64; 100 break; 101 102 case MAC_STAT_RBYTES: 103 ixgbe_ks->tor.value.ui64 = 0; 104 for (i = 0; i < 16; i++) { 105 ixgbe_ks->qbrc[i].value.ui64 += 106 IXGBE_READ_REG(hw, IXGBE_QBRC(i)); 107 ixgbe_ks->tor.value.ui64 += 108 ixgbe_ks->qbrc[i].value.ui64; 109 } 110 *val = ixgbe_ks->tor.value.ui64; 111 break; 112 113 case MAC_STAT_OBYTES: 114 ixgbe_ks->tot.value.ui64 = 0; 115 for (i = 0; i < 16; i++) { 116 if (hw->mac.type >= ixgbe_mac_82599EB) { 117 ixgbe_ks->qbtc[i].value.ui64 += 118 IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); 119 ixgbe_ks->qbtc[i].value.ui64 += ((uint64_t) 120 IXGBE_READ_REG(hw, IXGBE_QBTC_H(i))) << 32; 121 } else { 122 ixgbe_ks->qbtc[i].value.ui64 += 123 IXGBE_READ_REG(hw, IXGBE_QBTC(i)); 124 } 125 ixgbe_ks->tot.value.ui64 += 126 ixgbe_ks->qbtc[i].value.ui64; 127 } 128 *val = ixgbe_ks->tot.value.ui64; 129 break; 130 131 case MAC_STAT_IPACKETS: 132 ixgbe_ks->tpr.value.ui64 += 133 IXGBE_READ_REG(hw, IXGBE_TPR); 134 *val = ixgbe_ks->tpr.value.ui64; 135 break; 136 137 case MAC_STAT_OPACKETS: 138 ixgbe_ks->tpt.value.ui64 += 139 IXGBE_READ_REG(hw, IXGBE_TPT); 140 *val = ixgbe_ks->tpt.value.ui64; 141 break; 142 143 /* RFC 1643 stats */ 144 case ETHER_STAT_FCS_ERRORS: 145 ixgbe_ks->crcerrs.value.ui64 += 146 IXGBE_READ_REG(hw, IXGBE_CRCERRS); 147 *val = ixgbe_ks->crcerrs.value.ui64; 148 break; 149 150 case ETHER_STAT_TOOLONG_ERRORS: 151 ixgbe_ks->roc.value.ui64 += 152 IXGBE_READ_REG(hw, IXGBE_ROC); 153 *val = ixgbe_ks->roc.value.ui64; 154 break; 155 156 case ETHER_STAT_MACRCV_ERRORS: 157 ixgbe_ks->crcerrs.value.ui64 += 158 IXGBE_READ_REG(hw, IXGBE_CRCERRS); 159 ixgbe_ks->illerrc.value.ui64 += 160 IXGBE_READ_REG(hw, IXGBE_ILLERRC); 161 ixgbe_ks->errbc.value.ui64 += 162 IXGBE_READ_REG(hw, IXGBE_ERRBC); 163 ixgbe_ks->rlec.value.ui64 += 164 IXGBE_READ_REG(hw, IXGBE_RLEC); 165 *val = ixgbe_ks->crcerrs.value.ui64 + 166 ixgbe_ks->illerrc.value.ui64 + 167 ixgbe_ks->errbc.value.ui64 + 168 ixgbe_ks->rlec.value.ui64; 169 break; 170 171 /* MII/GMII stats */ 172 case ETHER_STAT_XCVR_ADDR: 173 /* The Internal PHY's MDI address for each MAC is 1 */ 174 *val = 1; 175 break; 176 177 case ETHER_STAT_XCVR_ID: 178 *val = hw->phy.id; 179 break; 180 181 case ETHER_STAT_XCVR_INUSE: 182 switch (ixgbe->link_speed) { 183 case IXGBE_LINK_SPEED_1GB_FULL: 184 *val = 185 (hw->phy.media_type == ixgbe_media_type_copper) ? 186 XCVR_1000T : XCVR_1000X; 187 break; 188 case IXGBE_LINK_SPEED_100_FULL: 189 *val = (hw->phy.media_type == ixgbe_media_type_copper) ? 190 XCVR_100T2 : XCVR_100X; 191 break; 192 default: 193 *val = XCVR_NONE; 194 break; 195 } 196 break; 197 198 case ETHER_STAT_CAP_10GFDX: 199 *val = 1; 200 break; 201 202 case ETHER_STAT_CAP_1000FDX: 203 *val = 1; 204 break; 205 206 case ETHER_STAT_CAP_100FDX: 207 *val = 1; 208 break; 209 210 case ETHER_STAT_CAP_ASMPAUSE: 211 *val = ixgbe->param_asym_pause_cap; 212 break; 213 214 case ETHER_STAT_CAP_PAUSE: 215 *val = ixgbe->param_pause_cap; 216 break; 217 218 case ETHER_STAT_CAP_AUTONEG: 219 *val = 1; 220 break; 221 222 case ETHER_STAT_ADV_CAP_10GFDX: 223 *val = ixgbe->param_adv_10000fdx_cap; 224 break; 225 226 case ETHER_STAT_ADV_CAP_1000FDX: 227 *val = ixgbe->param_adv_1000fdx_cap; 228 break; 229 230 case ETHER_STAT_ADV_CAP_100FDX: 231 *val = ixgbe->param_adv_100fdx_cap; 232 break; 233 234 case ETHER_STAT_ADV_CAP_ASMPAUSE: 235 *val = ixgbe->param_adv_asym_pause_cap; 236 break; 237 238 case ETHER_STAT_ADV_CAP_PAUSE: 239 *val = ixgbe->param_adv_pause_cap; 240 break; 241 242 case ETHER_STAT_ADV_CAP_AUTONEG: 243 *val = ixgbe->param_adv_autoneg_cap; 244 break; 245 246 case ETHER_STAT_LP_CAP_10GFDX: 247 *val = ixgbe->param_lp_10000fdx_cap; 248 break; 249 250 case ETHER_STAT_LP_CAP_1000FDX: 251 *val = ixgbe->param_lp_1000fdx_cap; 252 break; 253 254 case ETHER_STAT_LP_CAP_100FDX: 255 *val = ixgbe->param_lp_100fdx_cap; 256 break; 257 258 case ETHER_STAT_LP_CAP_ASMPAUSE: 259 *val = ixgbe->param_lp_asym_pause_cap; 260 break; 261 262 case ETHER_STAT_LP_CAP_PAUSE: 263 *val = ixgbe->param_lp_pause_cap; 264 break; 265 266 case ETHER_STAT_LP_CAP_AUTONEG: 267 *val = ixgbe->param_lp_autoneg_cap; 268 break; 269 270 case ETHER_STAT_LINK_ASMPAUSE: 271 *val = ixgbe->param_asym_pause_cap; 272 break; 273 274 case ETHER_STAT_LINK_PAUSE: 275 *val = ixgbe->param_pause_cap; 276 break; 277 278 case ETHER_STAT_LINK_AUTONEG: 279 *val = hw->mac.autoneg; 280 break; 281 case ETHER_STAT_LINK_DUPLEX: 282 *val = LINK_DUPLEX_FULL; 283 break; 284 285 case ETHER_STAT_TOOSHORT_ERRORS: 286 ixgbe_ks->ruc.value.ui64 += 287 IXGBE_READ_REG(hw, IXGBE_RUC); 288 *val = ixgbe_ks->ruc.value.ui64; 289 break; 290 291 case ETHER_STAT_CAP_REMFAULT: 292 *val = ixgbe->param_rem_fault; 293 break; 294 295 case ETHER_STAT_ADV_REMFAULT: 296 *val = ixgbe->param_adv_rem_fault; 297 break; 298 299 case ETHER_STAT_LP_REMFAULT: 300 *val = ixgbe->param_lp_rem_fault; 301 break; 302 303 case ETHER_STAT_JABBER_ERRORS: 304 ixgbe_ks->rjc.value.ui64 += 305 IXGBE_READ_REG(hw, IXGBE_RJC); 306 *val = ixgbe_ks->rjc.value.ui64; 307 break; 308 309 default: 310 mutex_exit(&ixgbe->gen_lock); 311 return (ENOTSUP); 312 } 313 314 mutex_exit(&ixgbe->gen_lock); 315 316 if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) 317 ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_UNAFFECTED); 318 319 return (0); 320 } 321 322 /* 323 * Bring the device out of the reset/quiesced state that it 324 * was in when the interface was registered. 325 */ 326 int 327 ixgbe_m_start(void *arg) 328 { 329 ixgbe_t *ixgbe = (ixgbe_t *)arg; 330 331 mutex_enter(&ixgbe->gen_lock); 332 333 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 334 mutex_exit(&ixgbe->gen_lock); 335 return (ECANCELED); 336 } 337 338 if (ixgbe_start(ixgbe, B_TRUE) != IXGBE_SUCCESS) { 339 mutex_exit(&ixgbe->gen_lock); 340 return (EIO); 341 } 342 343 ixgbe->ixgbe_state |= IXGBE_STARTED; 344 345 mutex_exit(&ixgbe->gen_lock); 346 347 /* 348 * Enable and start the watchdog timer 349 */ 350 ixgbe_enable_watchdog_timer(ixgbe); 351 352 return (0); 353 } 354 355 /* 356 * Stop the device and put it in a reset/quiesced state such 357 * that the interface can be unregistered. 358 */ 359 void 360 ixgbe_m_stop(void *arg) 361 { 362 ixgbe_t *ixgbe = (ixgbe_t *)arg; 363 364 mutex_enter(&ixgbe->gen_lock); 365 366 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 367 mutex_exit(&ixgbe->gen_lock); 368 return; 369 } 370 371 ixgbe->ixgbe_state &= ~IXGBE_STARTED; 372 373 ixgbe_stop(ixgbe, B_TRUE); 374 375 mutex_exit(&ixgbe->gen_lock); 376 377 /* 378 * Disable and stop the watchdog timer 379 */ 380 ixgbe_disable_watchdog_timer(ixgbe); 381 } 382 383 /* 384 * Set the promiscuity of the device. 385 */ 386 int 387 ixgbe_m_promisc(void *arg, boolean_t on) 388 { 389 ixgbe_t *ixgbe = (ixgbe_t *)arg; 390 uint32_t reg_val; 391 struct ixgbe_hw *hw = &ixgbe->hw; 392 393 mutex_enter(&ixgbe->gen_lock); 394 395 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 396 mutex_exit(&ixgbe->gen_lock); 397 return (ECANCELED); 398 } 399 reg_val = IXGBE_READ_REG(hw, IXGBE_FCTRL); 400 401 if (on) 402 reg_val |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); 403 else 404 reg_val &= (~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE)); 405 406 IXGBE_WRITE_REG(&ixgbe->hw, IXGBE_FCTRL, reg_val); 407 408 mutex_exit(&ixgbe->gen_lock); 409 410 return (0); 411 } 412 413 /* 414 * Add/remove the addresses to/from the set of multicast 415 * addresses for which the device will receive packets. 416 */ 417 int 418 ixgbe_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr) 419 { 420 ixgbe_t *ixgbe = (ixgbe_t *)arg; 421 int result; 422 423 mutex_enter(&ixgbe->gen_lock); 424 425 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 426 mutex_exit(&ixgbe->gen_lock); 427 return (ECANCELED); 428 } 429 430 result = (add) ? ixgbe_multicst_add(ixgbe, mcst_addr) 431 : ixgbe_multicst_remove(ixgbe, mcst_addr); 432 433 mutex_exit(&ixgbe->gen_lock); 434 435 return (result); 436 } 437 438 /* 439 * Pass on M_IOCTL messages passed to the DLD, and support 440 * private IOCTLs for debugging and ndd. 441 */ 442 void 443 ixgbe_m_ioctl(void *arg, queue_t *q, mblk_t *mp) 444 { 445 ixgbe_t *ixgbe = (ixgbe_t *)arg; 446 struct iocblk *iocp; 447 enum ioc_reply status; 448 449 iocp = (struct iocblk *)(uintptr_t)mp->b_rptr; 450 iocp->ioc_error = 0; 451 452 mutex_enter(&ixgbe->gen_lock); 453 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 454 mutex_exit(&ixgbe->gen_lock); 455 miocnak(q, mp, 0, EINVAL); 456 return; 457 } 458 mutex_exit(&ixgbe->gen_lock); 459 460 switch (iocp->ioc_cmd) { 461 case LB_GET_INFO_SIZE: 462 case LB_GET_INFO: 463 case LB_GET_MODE: 464 case LB_SET_MODE: 465 status = ixgbe_loopback_ioctl(ixgbe, iocp, mp); 466 break; 467 468 default: 469 status = IOC_INVAL; 470 break; 471 } 472 473 /* 474 * Decide how to reply 475 */ 476 switch (status) { 477 default: 478 case IOC_INVAL: 479 /* 480 * Error, reply with a NAK and EINVAL or the specified error 481 */ 482 miocnak(q, mp, 0, iocp->ioc_error == 0 ? 483 EINVAL : iocp->ioc_error); 484 break; 485 486 case IOC_DONE: 487 /* 488 * OK, reply already sent 489 */ 490 break; 491 492 case IOC_ACK: 493 /* 494 * OK, reply with an ACK 495 */ 496 miocack(q, mp, 0, 0); 497 break; 498 499 case IOC_REPLY: 500 /* 501 * OK, send prepared reply as ACK or NAK 502 */ 503 mp->b_datap->db_type = iocp->ioc_error == 0 ? 504 M_IOCACK : M_IOCNAK; 505 qreply(q, mp); 506 break; 507 } 508 } 509 510 /* 511 * Obtain the MAC's capabilities and associated data from 512 * the driver. 513 */ 514 boolean_t 515 ixgbe_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 516 { 517 ixgbe_t *ixgbe = (ixgbe_t *)arg; 518 519 switch (cap) { 520 case MAC_CAPAB_HCKSUM: { 521 uint32_t *tx_hcksum_flags = cap_data; 522 523 /* 524 * We advertise our capabilities only if tx hcksum offload is 525 * enabled. On receive, the stack will accept checksummed 526 * packets anyway, even if we haven't said we can deliver 527 * them. 528 */ 529 if (!ixgbe->tx_hcksum_enable) 530 return (B_FALSE); 531 532 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM; 533 break; 534 } 535 case MAC_CAPAB_LSO: { 536 mac_capab_lso_t *cap_lso = cap_data; 537 538 if (ixgbe->lso_enable) { 539 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; 540 cap_lso->lso_basic_tcp_ipv4.lso_max = IXGBE_LSO_MAXLEN; 541 break; 542 } else { 543 return (B_FALSE); 544 } 545 } 546 case MAC_CAPAB_RINGS: { 547 mac_capab_rings_t *cap_rings = cap_data; 548 549 switch (cap_rings->mr_type) { 550 case MAC_RING_TYPE_RX: 551 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 552 cap_rings->mr_rnum = ixgbe->num_rx_rings; 553 cap_rings->mr_gnum = ixgbe->num_rx_groups; 554 cap_rings->mr_rget = ixgbe_fill_ring; 555 cap_rings->mr_gget = ixgbe_fill_group; 556 cap_rings->mr_gaddring = NULL; 557 cap_rings->mr_gremring = NULL; 558 break; 559 case MAC_RING_TYPE_TX: 560 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 561 cap_rings->mr_rnum = ixgbe->num_tx_rings; 562 cap_rings->mr_gnum = 0; 563 cap_rings->mr_rget = ixgbe_fill_ring; 564 cap_rings->mr_gget = NULL; 565 break; 566 default: 567 break; 568 } 569 break; 570 } 571 default: 572 return (B_FALSE); 573 } 574 return (B_TRUE); 575 } 576 577 int 578 ixgbe_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 579 uint_t pr_valsize, const void *pr_val) 580 { 581 ixgbe_t *ixgbe = (ixgbe_t *)arg; 582 struct ixgbe_hw *hw = &ixgbe->hw; 583 int err = 0; 584 uint32_t flow_control; 585 uint32_t cur_mtu, new_mtu; 586 uint32_t rx_size; 587 uint32_t tx_size; 588 589 mutex_enter(&ixgbe->gen_lock); 590 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 591 mutex_exit(&ixgbe->gen_lock); 592 return (ECANCELED); 593 } 594 595 if (ixgbe->loopback_mode != IXGBE_LB_NONE && 596 ixgbe_param_locked(pr_num)) { 597 /* 598 * All en_* parameters are locked (read-only) 599 * while the device is in any sort of loopback mode. 600 */ 601 mutex_exit(&ixgbe->gen_lock); 602 return (EBUSY); 603 } 604 605 switch (pr_num) { 606 case MAC_PROP_EN_10GFDX_CAP: 607 /* read/write on copper, read-only on serdes */ 608 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) { 609 err = ENOTSUP; 610 break; 611 } else { 612 ixgbe->param_en_10000fdx_cap = *(uint8_t *)pr_val; 613 ixgbe->param_adv_10000fdx_cap = *(uint8_t *)pr_val; 614 goto setup_link; 615 } 616 case MAC_PROP_EN_1000FDX_CAP: 617 /* read/write on copper, read-only on serdes */ 618 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) { 619 err = ENOTSUP; 620 break; 621 } else { 622 ixgbe->param_en_1000fdx_cap = *(uint8_t *)pr_val; 623 ixgbe->param_adv_1000fdx_cap = *(uint8_t *)pr_val; 624 goto setup_link; 625 } 626 case MAC_PROP_EN_100FDX_CAP: 627 /* read/write on copper, read-only on serdes */ 628 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) { 629 err = ENOTSUP; 630 break; 631 } else { 632 ixgbe->param_en_100fdx_cap = *(uint8_t *)pr_val; 633 ixgbe->param_adv_100fdx_cap = *(uint8_t *)pr_val; 634 goto setup_link; 635 } 636 case MAC_PROP_AUTONEG: 637 /* read/write on copper, read-only on serdes */ 638 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) { 639 err = ENOTSUP; 640 break; 641 } else { 642 ixgbe->param_adv_autoneg_cap = *(uint8_t *)pr_val; 643 goto setup_link; 644 } 645 case MAC_PROP_FLOWCTRL: 646 bcopy(pr_val, &flow_control, sizeof (flow_control)); 647 648 switch (flow_control) { 649 default: 650 err = EINVAL; 651 break; 652 case LINK_FLOWCTRL_NONE: 653 hw->fc.requested_mode = ixgbe_fc_none; 654 break; 655 case LINK_FLOWCTRL_RX: 656 hw->fc.requested_mode = ixgbe_fc_rx_pause; 657 break; 658 case LINK_FLOWCTRL_TX: 659 hw->fc.requested_mode = ixgbe_fc_tx_pause; 660 break; 661 case LINK_FLOWCTRL_BI: 662 hw->fc.requested_mode = ixgbe_fc_full; 663 break; 664 } 665 setup_link: 666 if (err == 0) { 667 if (ixgbe_driver_setup_link(ixgbe, B_TRUE) != 668 IXGBE_SUCCESS) 669 err = EINVAL; 670 } 671 break; 672 case MAC_PROP_ADV_10GFDX_CAP: 673 case MAC_PROP_ADV_1000FDX_CAP: 674 case MAC_PROP_ADV_100FDX_CAP: 675 case MAC_PROP_STATUS: 676 case MAC_PROP_SPEED: 677 case MAC_PROP_DUPLEX: 678 err = ENOTSUP; /* read-only prop. Can't set this. */ 679 break; 680 case MAC_PROP_MTU: 681 cur_mtu = ixgbe->default_mtu; 682 bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 683 if (new_mtu == cur_mtu) { 684 err = 0; 685 break; 686 } 687 688 if (new_mtu < DEFAULT_MTU || new_mtu > MAX_MTU) { 689 err = EINVAL; 690 break; 691 } 692 693 if (ixgbe->ixgbe_state & IXGBE_STARTED) { 694 err = EBUSY; 695 break; 696 } 697 698 err = mac_maxsdu_update(ixgbe->mac_hdl, new_mtu); 699 if (err == 0) { 700 ixgbe->default_mtu = new_mtu; 701 ixgbe->max_frame_size = ixgbe->default_mtu + 702 sizeof (struct ether_vlan_header) + ETHERFCSL; 703 704 /* 705 * Set rx buffer size 706 */ 707 rx_size = ixgbe->max_frame_size + IPHDR_ALIGN_ROOM; 708 ixgbe->rx_buf_size = ((rx_size >> 10) + ((rx_size & 709 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 710 711 /* 712 * Set tx buffer size 713 */ 714 tx_size = ixgbe->max_frame_size; 715 ixgbe->tx_buf_size = ((tx_size >> 10) + ((tx_size & 716 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 717 } 718 break; 719 case MAC_PROP_PRIVATE: 720 err = ixgbe_set_priv_prop(ixgbe, pr_name, pr_valsize, pr_val); 721 break; 722 default: 723 err = EINVAL; 724 break; 725 } 726 mutex_exit(&ixgbe->gen_lock); 727 return (err); 728 } 729 730 int 731 ixgbe_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 732 uint_t pr_flags, uint_t pr_valsize, void *pr_val, uint_t *perm) 733 { 734 ixgbe_t *ixgbe = (ixgbe_t *)arg; 735 struct ixgbe_hw *hw = &ixgbe->hw; 736 int err = 0; 737 uint32_t flow_control; 738 uint64_t tmp = 0; 739 boolean_t is_default = (pr_flags & MAC_PROP_DEFAULT); 740 mac_propval_range_t range; 741 742 if (pr_valsize == 0) 743 return (EINVAL); 744 745 *perm = MAC_PROP_PERM_READ; 746 747 bzero(pr_val, pr_valsize); 748 749 switch (pr_num) { 750 case MAC_PROP_DUPLEX: 751 if (pr_valsize >= sizeof (link_duplex_t)) { 752 bcopy(&ixgbe->link_duplex, pr_val, 753 sizeof (link_duplex_t)); 754 } else 755 err = EINVAL; 756 break; 757 case MAC_PROP_SPEED: 758 if (pr_valsize >= sizeof (uint64_t)) { 759 tmp = ixgbe->link_speed * 1000000ull; 760 bcopy(&tmp, pr_val, sizeof (tmp)); 761 } else 762 err = EINVAL; 763 break; 764 case MAC_PROP_AUTONEG: 765 if (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) 766 *perm = MAC_PROP_PERM_RW; 767 *(uint8_t *)pr_val = 768 (is_default ? 1 : ixgbe->param_adv_autoneg_cap); 769 break; 770 case MAC_PROP_FLOWCTRL: 771 *perm = MAC_PROP_PERM_RW; 772 if (pr_valsize >= sizeof (uint32_t)) { 773 if (is_default) { 774 flow_control = LINK_FLOWCTRL_NONE; 775 bcopy(&flow_control, pr_val, 776 sizeof (flow_control)); 777 break; 778 } 779 switch (hw->fc.requested_mode) { 780 case ixgbe_fc_none: 781 flow_control = LINK_FLOWCTRL_NONE; 782 break; 783 case ixgbe_fc_rx_pause: 784 flow_control = LINK_FLOWCTRL_RX; 785 break; 786 case ixgbe_fc_tx_pause: 787 flow_control = LINK_FLOWCTRL_TX; 788 break; 789 case ixgbe_fc_full: 790 flow_control = LINK_FLOWCTRL_BI; 791 break; 792 } 793 bcopy(&flow_control, pr_val, sizeof (flow_control)); 794 } else 795 err = EINVAL; 796 break; 797 case MAC_PROP_ADV_10GFDX_CAP: 798 *(uint8_t *)pr_val = (is_default ? 1 : 799 ixgbe->param_adv_10000fdx_cap); 800 break; 801 case MAC_PROP_EN_10GFDX_CAP: 802 if (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) 803 *perm = MAC_PROP_PERM_RW; 804 *(uint8_t *)pr_val = 805 (is_default ? 1 : ixgbe->param_en_10000fdx_cap); 806 break; 807 case MAC_PROP_ADV_1000FDX_CAP: 808 *(uint8_t *)pr_val = (is_default ? 1 : 809 ixgbe->param_adv_1000fdx_cap); 810 break; 811 case MAC_PROP_EN_1000FDX_CAP: 812 if (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) 813 *perm = MAC_PROP_PERM_RW; 814 *(uint8_t *)pr_val = 815 (is_default ? 1 : ixgbe->param_en_1000fdx_cap); 816 break; 817 case MAC_PROP_ADV_100FDX_CAP: 818 *(uint8_t *)pr_val = 819 (is_default ? 1 : ixgbe->param_adv_100fdx_cap); 820 break; 821 case MAC_PROP_EN_100FDX_CAP: 822 if (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) 823 *perm = MAC_PROP_PERM_RW; 824 *(uint8_t *)pr_val = 825 (is_default ? 1 : ixgbe->param_en_100fdx_cap); 826 break; 827 case MAC_PROP_PRIVATE: 828 err = ixgbe_get_priv_prop(ixgbe, pr_name, 829 pr_flags, pr_valsize, pr_val, perm); 830 break; 831 case MAC_PROP_MTU: 832 if (!(pr_flags & MAC_PROP_POSSIBLE)) 833 return (ENOTSUP); 834 if (pr_valsize < sizeof (mac_propval_range_t)) 835 return (EINVAL); 836 range.mpr_count = 1; 837 range.mpr_type = MAC_PROPVAL_UINT32; 838 range.range_uint32[0].mpur_min = DEFAULT_MTU; 839 range.range_uint32[0].mpur_max = MAX_MTU; 840 bcopy(&range, pr_val, sizeof (range)); 841 break; 842 default: 843 err = EINVAL; 844 break; 845 } 846 return (err); 847 } 848 849 boolean_t 850 ixgbe_param_locked(mac_prop_id_t pr_num) 851 { 852 /* 853 * All en_* parameters are locked (read-only) while 854 * the device is in any sort of loopback mode ... 855 */ 856 switch (pr_num) { 857 case MAC_PROP_EN_10GFDX_CAP: 858 case MAC_PROP_EN_1000FDX_CAP: 859 case MAC_PROP_EN_100FDX_CAP: 860 case MAC_PROP_AUTONEG: 861 case MAC_PROP_FLOWCTRL: 862 return (B_TRUE); 863 } 864 return (B_FALSE); 865 } 866 867 /* ARGSUSED */ 868 int 869 ixgbe_set_priv_prop(ixgbe_t *ixgbe, const char *pr_name, 870 uint_t pr_valsize, const void *pr_val) 871 { 872 int err = 0; 873 long result; 874 struct ixgbe_hw *hw = &ixgbe->hw; 875 int i; 876 877 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 878 if (pr_val == NULL) { 879 err = EINVAL; 880 return (err); 881 } 882 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 883 if (result < MIN_TX_COPY_THRESHOLD || 884 result > MAX_TX_COPY_THRESHOLD) 885 err = EINVAL; 886 else { 887 ixgbe->tx_copy_thresh = (uint32_t)result; 888 } 889 return (err); 890 } 891 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 892 if (pr_val == NULL) { 893 err = EINVAL; 894 return (err); 895 } 896 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 897 if (result < MIN_TX_RECYCLE_THRESHOLD || 898 result > MAX_TX_RECYCLE_THRESHOLD) 899 err = EINVAL; 900 else { 901 ixgbe->tx_recycle_thresh = (uint32_t)result; 902 } 903 return (err); 904 } 905 if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 906 if (pr_val == NULL) { 907 err = EINVAL; 908 return (err); 909 } 910 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 911 if (result < MIN_TX_OVERLOAD_THRESHOLD || 912 result > MAX_TX_OVERLOAD_THRESHOLD) 913 err = EINVAL; 914 else { 915 ixgbe->tx_overload_thresh = (uint32_t)result; 916 } 917 return (err); 918 } 919 if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 920 if (pr_val == NULL) { 921 err = EINVAL; 922 return (err); 923 } 924 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 925 if (result < MIN_TX_RESCHED_THRESHOLD || 926 result > MAX_TX_RESCHED_THRESHOLD) 927 err = EINVAL; 928 else { 929 ixgbe->tx_resched_thresh = (uint32_t)result; 930 } 931 return (err); 932 } 933 if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 934 if (pr_val == NULL) { 935 err = EINVAL; 936 return (err); 937 } 938 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 939 if (result < MIN_RX_COPY_THRESHOLD || 940 result > MAX_RX_COPY_THRESHOLD) 941 err = EINVAL; 942 else { 943 ixgbe->rx_copy_thresh = (uint32_t)result; 944 } 945 return (err); 946 } 947 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 948 if (pr_val == NULL) { 949 err = EINVAL; 950 return (err); 951 } 952 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 953 if (result < MIN_RX_LIMIT_PER_INTR || 954 result > MAX_RX_LIMIT_PER_INTR) 955 err = EINVAL; 956 else { 957 ixgbe->rx_limit_per_intr = (uint32_t)result; 958 } 959 return (err); 960 } 961 if (strcmp(pr_name, "_intr_throttling") == 0) { 962 if (pr_val == NULL) { 963 err = EINVAL; 964 return (err); 965 } 966 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 967 968 if (result < ixgbe->capab->min_intr_throttle || 969 result > ixgbe->capab->max_intr_throttle) 970 err = EINVAL; 971 else { 972 ixgbe->intr_throttling[0] = (uint32_t)result; 973 974 /* 975 * 82599 requires the interupt throttling rate is 976 * a multiple of 8. This is enforced by the register 977 * definiton. 978 */ 979 if (hw->mac.type == ixgbe_mac_82599EB) 980 ixgbe->intr_throttling[0] = 981 ixgbe->intr_throttling[0] & 0xFF8; 982 983 for (i = 0; i < MAX_INTR_VECTOR; i++) 984 ixgbe->intr_throttling[i] = 985 ixgbe->intr_throttling[0]; 986 987 /* Set interrupt throttling rate */ 988 for (i = 0; i < ixgbe->intr_cnt; i++) 989 IXGBE_WRITE_REG(hw, IXGBE_EITR(i), 990 ixgbe->intr_throttling[i]); 991 } 992 return (err); 993 } 994 return (ENOTSUP); 995 } 996 997 int 998 ixgbe_get_priv_prop(ixgbe_t *ixgbe, const char *pr_name, 999 uint_t pr_flags, uint_t pr_valsize, void *pr_val, uint_t *perm) 1000 { 1001 int err = ENOTSUP; 1002 boolean_t is_default = (pr_flags & MAC_PROP_DEFAULT); 1003 int value; 1004 1005 *perm = MAC_PROP_PERM_RW; 1006 1007 if (strcmp(pr_name, "_adv_pause_cap") == 0) { 1008 *perm = MAC_PROP_PERM_READ; 1009 value = (is_default ? 1 : ixgbe->param_adv_pause_cap); 1010 err = 0; 1011 goto done; 1012 } 1013 if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 1014 *perm = MAC_PROP_PERM_READ; 1015 value = (is_default ? 1 : ixgbe->param_adv_asym_pause_cap); 1016 err = 0; 1017 goto done; 1018 } 1019 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 1020 value = (is_default ? DEFAULT_TX_COPY_THRESHOLD : 1021 ixgbe->tx_copy_thresh); 1022 err = 0; 1023 goto done; 1024 } 1025 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 1026 value = (is_default ? DEFAULT_TX_RECYCLE_THRESHOLD : 1027 ixgbe->tx_recycle_thresh); 1028 err = 0; 1029 goto done; 1030 } 1031 if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 1032 value = (is_default ? DEFAULT_TX_OVERLOAD_THRESHOLD : 1033 ixgbe->tx_overload_thresh); 1034 err = 0; 1035 goto done; 1036 } 1037 if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 1038 value = (is_default ? DEFAULT_TX_RESCHED_THRESHOLD : 1039 ixgbe->tx_resched_thresh); 1040 err = 0; 1041 goto done; 1042 } 1043 if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 1044 value = (is_default ? DEFAULT_RX_COPY_THRESHOLD : 1045 ixgbe->rx_copy_thresh); 1046 err = 0; 1047 goto done; 1048 } 1049 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 1050 value = (is_default ? DEFAULT_RX_LIMIT_PER_INTR : 1051 ixgbe->rx_limit_per_intr); 1052 err = 0; 1053 goto done; 1054 } 1055 if (strcmp(pr_name, "_intr_throttling") == 0) { 1056 value = (is_default ? ixgbe->capab->def_intr_throttle : 1057 ixgbe->intr_throttling[0]); 1058 err = 0; 1059 goto done; 1060 } 1061 done: 1062 if (err == 0) { 1063 (void) snprintf(pr_val, pr_valsize, "%d", value); 1064 } 1065 return (err); 1066 } 1067