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 2012 Nexenta Systems, Inc. All rights reserved. 29 * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved. 30 * Copyright (c) 2017, Joyent, Inc. 31 */ 32 33 #include "ixgbe_sw.h" 34 35 /* 36 * Bring the device out of the reset/quiesced state that it 37 * was in when the interface was registered. 38 */ 39 int 40 ixgbe_m_start(void *arg) 41 { 42 ixgbe_t *ixgbe = (ixgbe_t *)arg; 43 44 mutex_enter(&ixgbe->gen_lock); 45 46 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 47 mutex_exit(&ixgbe->gen_lock); 48 return (ECANCELED); 49 } 50 51 if (ixgbe_start(ixgbe, B_TRUE) != IXGBE_SUCCESS) { 52 mutex_exit(&ixgbe->gen_lock); 53 return (EIO); 54 } 55 56 atomic_or_32(&ixgbe->ixgbe_state, IXGBE_STARTED); 57 58 mutex_exit(&ixgbe->gen_lock); 59 60 /* 61 * Enable and start the watchdog timer 62 */ 63 ixgbe_enable_watchdog_timer(ixgbe); 64 65 return (0); 66 } 67 68 /* 69 * Stop the device and put it in a reset/quiesced state such 70 * that the interface can be unregistered. 71 */ 72 void 73 ixgbe_m_stop(void *arg) 74 { 75 ixgbe_t *ixgbe = (ixgbe_t *)arg; 76 77 mutex_enter(&ixgbe->gen_lock); 78 79 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 80 mutex_exit(&ixgbe->gen_lock); 81 return; 82 } 83 84 atomic_and_32(&ixgbe->ixgbe_state, ~IXGBE_STARTED); 85 86 ixgbe_stop(ixgbe, B_TRUE); 87 88 mutex_exit(&ixgbe->gen_lock); 89 90 /* 91 * Disable and stop the watchdog timer 92 */ 93 ixgbe_disable_watchdog_timer(ixgbe); 94 } 95 96 /* 97 * Set the promiscuity of the device. 98 */ 99 int 100 ixgbe_m_promisc(void *arg, boolean_t on) 101 { 102 ixgbe_t *ixgbe = (ixgbe_t *)arg; 103 uint32_t reg_val; 104 struct ixgbe_hw *hw = &ixgbe->hw; 105 106 mutex_enter(&ixgbe->gen_lock); 107 108 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 109 mutex_exit(&ixgbe->gen_lock); 110 return (ECANCELED); 111 } 112 reg_val = IXGBE_READ_REG(hw, IXGBE_FCTRL); 113 114 if (on) 115 reg_val |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); 116 else 117 reg_val &= (~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE)); 118 119 IXGBE_WRITE_REG(&ixgbe->hw, IXGBE_FCTRL, reg_val); 120 121 mutex_exit(&ixgbe->gen_lock); 122 123 return (0); 124 } 125 126 /* 127 * Add/remove the addresses to/from the set of multicast 128 * addresses for which the device will receive packets. 129 */ 130 int 131 ixgbe_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr) 132 { 133 ixgbe_t *ixgbe = (ixgbe_t *)arg; 134 int result; 135 136 mutex_enter(&ixgbe->gen_lock); 137 138 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 139 mutex_exit(&ixgbe->gen_lock); 140 return (ECANCELED); 141 } 142 143 result = (add) ? ixgbe_multicst_add(ixgbe, mcst_addr) 144 : ixgbe_multicst_remove(ixgbe, mcst_addr); 145 146 mutex_exit(&ixgbe->gen_lock); 147 148 return (result); 149 } 150 151 /* 152 * Pass on M_IOCTL messages passed to the DLD, and support 153 * private IOCTLs for debugging and ndd. 154 */ 155 void 156 ixgbe_m_ioctl(void *arg, queue_t *q, mblk_t *mp) 157 { 158 ixgbe_t *ixgbe = (ixgbe_t *)arg; 159 struct iocblk *iocp; 160 enum ioc_reply status; 161 162 iocp = (struct iocblk *)(uintptr_t)mp->b_rptr; 163 iocp->ioc_error = 0; 164 165 mutex_enter(&ixgbe->gen_lock); 166 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 167 mutex_exit(&ixgbe->gen_lock); 168 miocnak(q, mp, 0, EINVAL); 169 return; 170 } 171 mutex_exit(&ixgbe->gen_lock); 172 173 switch (iocp->ioc_cmd) { 174 case LB_GET_INFO_SIZE: 175 case LB_GET_INFO: 176 case LB_GET_MODE: 177 case LB_SET_MODE: 178 status = ixgbe_loopback_ioctl(ixgbe, iocp, mp); 179 break; 180 181 default: 182 status = IOC_INVAL; 183 break; 184 } 185 186 /* 187 * Decide how to reply 188 */ 189 switch (status) { 190 default: 191 case IOC_INVAL: 192 /* 193 * Error, reply with a NAK and EINVAL or the specified error 194 */ 195 miocnak(q, mp, 0, iocp->ioc_error == 0 ? 196 EINVAL : iocp->ioc_error); 197 break; 198 199 case IOC_DONE: 200 /* 201 * OK, reply already sent 202 */ 203 break; 204 205 case IOC_ACK: 206 /* 207 * OK, reply with an ACK 208 */ 209 miocack(q, mp, 0, 0); 210 break; 211 212 case IOC_REPLY: 213 /* 214 * OK, send prepared reply as ACK or NAK 215 */ 216 mp->b_datap->db_type = iocp->ioc_error == 0 ? 217 M_IOCACK : M_IOCNAK; 218 qreply(q, mp); 219 break; 220 } 221 } 222 223 /* 224 * Obtain the MAC's capabilities and associated data from 225 * the driver. 226 */ 227 boolean_t 228 ixgbe_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 229 { 230 ixgbe_t *ixgbe = (ixgbe_t *)arg; 231 232 switch (cap) { 233 case MAC_CAPAB_HCKSUM: { 234 uint32_t *tx_hcksum_flags = cap_data; 235 236 /* 237 * We advertise our capabilities only if tx hcksum offload is 238 * enabled. On receive, the stack will accept checksummed 239 * packets anyway, even if we haven't said we can deliver 240 * them. 241 */ 242 if (!ixgbe->tx_hcksum_enable) 243 return (B_FALSE); 244 245 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM; 246 break; 247 } 248 case MAC_CAPAB_LSO: { 249 mac_capab_lso_t *cap_lso = cap_data; 250 251 if (ixgbe->lso_enable) { 252 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; 253 cap_lso->lso_basic_tcp_ipv4.lso_max = IXGBE_LSO_MAXLEN; 254 break; 255 } else { 256 return (B_FALSE); 257 } 258 } 259 case MAC_CAPAB_RINGS: { 260 mac_capab_rings_t *cap_rings = cap_data; 261 262 switch (cap_rings->mr_type) { 263 case MAC_RING_TYPE_RX: 264 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 265 cap_rings->mr_rnum = ixgbe->num_rx_rings; 266 cap_rings->mr_gnum = ixgbe->num_rx_groups; 267 cap_rings->mr_rget = ixgbe_fill_ring; 268 cap_rings->mr_gget = ixgbe_fill_group; 269 cap_rings->mr_gaddring = NULL; 270 cap_rings->mr_gremring = NULL; 271 break; 272 case MAC_RING_TYPE_TX: 273 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 274 cap_rings->mr_rnum = ixgbe->num_tx_rings; 275 cap_rings->mr_gnum = 0; 276 cap_rings->mr_rget = ixgbe_fill_ring; 277 cap_rings->mr_gget = NULL; 278 break; 279 default: 280 break; 281 } 282 break; 283 } 284 case MAC_CAPAB_TRANSCEIVER: { 285 mac_capab_transceiver_t *mct = cap_data; 286 287 /* 288 * Rather than try and guess based on the media type whether or 289 * not we have a transceiver we can read, we instead will let 290 * the actual function calls figure that out for us. 291 */ 292 mct->mct_flags = 0; 293 mct->mct_ntransceivers = 1; 294 mct->mct_info = ixgbe_transceiver_info; 295 mct->mct_read = ixgbe_transceiver_read; 296 return (B_TRUE); 297 } 298 default: 299 return (B_FALSE); 300 } 301 return (B_TRUE); 302 } 303 304 int 305 ixgbe_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 306 uint_t pr_valsize, const void *pr_val) 307 { 308 ixgbe_t *ixgbe = (ixgbe_t *)arg; 309 struct ixgbe_hw *hw = &ixgbe->hw; 310 int err = 0; 311 uint32_t flow_control; 312 uint32_t cur_mtu, new_mtu; 313 uint32_t rx_size; 314 uint32_t tx_size; 315 ixgbe_link_speed speeds = 0; 316 317 mutex_enter(&ixgbe->gen_lock); 318 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 319 mutex_exit(&ixgbe->gen_lock); 320 return (ECANCELED); 321 } 322 323 /* 324 * We cannot always rely on the common code maintaining 325 * hw->phy.speeds_supported, therefore we fall back to use the recorded 326 * supported speeds which were obtained during instance init in 327 * ixgbe_init_params(). 328 */ 329 speeds = hw->phy.speeds_supported; 330 if (speeds == 0) 331 speeds = ixgbe->speeds_supported; 332 333 if (ixgbe->loopback_mode != IXGBE_LB_NONE && 334 ixgbe_param_locked(pr_num)) { 335 /* 336 * All en_* parameters are locked (read-only) 337 * while the device is in any sort of loopback mode. 338 */ 339 mutex_exit(&ixgbe->gen_lock); 340 return (EBUSY); 341 } 342 343 /* 344 * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked 345 * read-only on non-baseT PHYs. 346 */ 347 switch (pr_num) { 348 case MAC_PROP_EN_10GFDX_CAP: 349 if (hw->phy.media_type == ixgbe_media_type_copper && 350 speeds & IXGBE_LINK_SPEED_10GB_FULL) { 351 ixgbe->param_en_10000fdx_cap = *(uint8_t *)pr_val; 352 goto setup_link; 353 } else { 354 err = ENOTSUP; 355 break; 356 } 357 case MAC_PROP_EN_5000FDX_CAP: 358 if (hw->phy.media_type == ixgbe_media_type_copper && 359 speeds & IXGBE_LINK_SPEED_5GB_FULL) { 360 ixgbe->param_en_5000fdx_cap = *(uint8_t *)pr_val; 361 goto setup_link; 362 } else { 363 err = ENOTSUP; 364 break; 365 } 366 case MAC_PROP_EN_2500FDX_CAP: 367 if (hw->phy.media_type == ixgbe_media_type_copper && 368 speeds & IXGBE_LINK_SPEED_2_5GB_FULL) { 369 ixgbe->param_en_2500fdx_cap = *(uint8_t *)pr_val; 370 goto setup_link; 371 } else { 372 err = ENOTSUP; 373 break; 374 } 375 case MAC_PROP_EN_1000FDX_CAP: 376 if (hw->phy.media_type == ixgbe_media_type_copper && 377 speeds & IXGBE_LINK_SPEED_1GB_FULL) { 378 ixgbe->param_en_1000fdx_cap = *(uint8_t *)pr_val; 379 goto setup_link; 380 } else { 381 err = ENOTSUP; 382 break; 383 } 384 case MAC_PROP_EN_100FDX_CAP: 385 if (hw->phy.media_type == ixgbe_media_type_copper && 386 speeds & IXGBE_LINK_SPEED_100_FULL) { 387 ixgbe->param_en_100fdx_cap = *(uint8_t *)pr_val; 388 goto setup_link; 389 } else { 390 err = ENOTSUP; 391 break; 392 } 393 case MAC_PROP_AUTONEG: 394 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) { 395 err = ENOTSUP; 396 break; 397 } else { 398 ixgbe->param_adv_autoneg_cap = *(uint8_t *)pr_val; 399 goto setup_link; 400 } 401 case MAC_PROP_FLOWCTRL: 402 bcopy(pr_val, &flow_control, sizeof (flow_control)); 403 404 switch (flow_control) { 405 default: 406 err = EINVAL; 407 break; 408 case LINK_FLOWCTRL_NONE: 409 hw->fc.requested_mode = ixgbe_fc_none; 410 break; 411 case LINK_FLOWCTRL_RX: 412 hw->fc.requested_mode = ixgbe_fc_rx_pause; 413 break; 414 case LINK_FLOWCTRL_TX: 415 hw->fc.requested_mode = ixgbe_fc_tx_pause; 416 break; 417 case LINK_FLOWCTRL_BI: 418 hw->fc.requested_mode = ixgbe_fc_full; 419 break; 420 } 421 setup_link: 422 if (err == 0) { 423 if (ixgbe_driver_setup_link(ixgbe, B_TRUE) != 424 IXGBE_SUCCESS) 425 err = EINVAL; 426 } 427 break; 428 case MAC_PROP_ADV_10GFDX_CAP: 429 case MAC_PROP_ADV_5000FDX_CAP: 430 case MAC_PROP_ADV_2500FDX_CAP: 431 case MAC_PROP_ADV_1000FDX_CAP: 432 case MAC_PROP_ADV_100FDX_CAP: 433 case MAC_PROP_STATUS: 434 case MAC_PROP_SPEED: 435 case MAC_PROP_DUPLEX: 436 err = ENOTSUP; /* read-only prop. Can't set this. */ 437 break; 438 case MAC_PROP_MTU: 439 cur_mtu = ixgbe->default_mtu; 440 bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 441 if (new_mtu == cur_mtu) { 442 err = 0; 443 break; 444 } 445 446 if (new_mtu < DEFAULT_MTU || new_mtu > ixgbe->capab->max_mtu) { 447 err = EINVAL; 448 break; 449 } 450 451 if (ixgbe->ixgbe_state & IXGBE_STARTED) { 452 err = EBUSY; 453 break; 454 } 455 456 err = mac_maxsdu_update(ixgbe->mac_hdl, new_mtu); 457 if (err == 0) { 458 ixgbe->default_mtu = new_mtu; 459 ixgbe->max_frame_size = ixgbe->default_mtu + 460 sizeof (struct ether_vlan_header) + ETHERFCSL; 461 462 /* 463 * Set rx buffer size 464 */ 465 rx_size = ixgbe->max_frame_size + IPHDR_ALIGN_ROOM; 466 ixgbe->rx_buf_size = ((rx_size >> 10) + ((rx_size & 467 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 468 469 /* 470 * Set tx buffer size 471 */ 472 tx_size = ixgbe->max_frame_size; 473 ixgbe->tx_buf_size = ((tx_size >> 10) + ((tx_size & 474 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 475 } 476 break; 477 case MAC_PROP_PRIVATE: 478 err = ixgbe_set_priv_prop(ixgbe, pr_name, pr_valsize, pr_val); 479 break; 480 default: 481 err = ENOTSUP; 482 break; 483 } 484 mutex_exit(&ixgbe->gen_lock); 485 return (err); 486 } 487 488 int 489 ixgbe_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 490 uint_t pr_valsize, void *pr_val) 491 { 492 ixgbe_t *ixgbe = (ixgbe_t *)arg; 493 struct ixgbe_hw *hw = &ixgbe->hw; 494 int err = 0; 495 uint32_t flow_control; 496 uint64_t tmp = 0; 497 ixgbe_link_speed speeds = 0; 498 499 /* 500 * We cannot always rely on the common code maintaining 501 * hw->phy.speeds_supported, therefore we fall back to use the recorded 502 * supported speeds which were obtained during instance init in 503 * ixgbe_init_params(). 504 */ 505 speeds = hw->phy.speeds_supported; 506 if (speeds == 0) 507 speeds = ixgbe->speeds_supported; 508 509 switch (pr_num) { 510 case MAC_PROP_DUPLEX: 511 ASSERT(pr_valsize >= sizeof (link_duplex_t)); 512 bcopy(&ixgbe->link_duplex, pr_val, 513 sizeof (link_duplex_t)); 514 break; 515 case MAC_PROP_SPEED: 516 ASSERT(pr_valsize >= sizeof (uint64_t)); 517 tmp = ixgbe->link_speed * 1000000ull; 518 bcopy(&tmp, pr_val, sizeof (tmp)); 519 break; 520 case MAC_PROP_AUTONEG: 521 *(uint8_t *)pr_val = ixgbe->param_adv_autoneg_cap; 522 break; 523 case MAC_PROP_FLOWCTRL: 524 ASSERT(pr_valsize >= sizeof (uint32_t)); 525 526 switch (hw->fc.requested_mode) { 527 case ixgbe_fc_none: 528 flow_control = LINK_FLOWCTRL_NONE; 529 break; 530 case ixgbe_fc_rx_pause: 531 flow_control = LINK_FLOWCTRL_RX; 532 break; 533 case ixgbe_fc_tx_pause: 534 flow_control = LINK_FLOWCTRL_TX; 535 break; 536 case ixgbe_fc_full: 537 flow_control = LINK_FLOWCTRL_BI; 538 break; 539 } 540 bcopy(&flow_control, pr_val, sizeof (flow_control)); 541 break; 542 case MAC_PROP_ADV_10GFDX_CAP: 543 if (speeds & IXGBE_LINK_SPEED_10GB_FULL) 544 *(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap; 545 else 546 err = ENOTSUP; 547 break; 548 case MAC_PROP_EN_10GFDX_CAP: 549 if (speeds & IXGBE_LINK_SPEED_10GB_FULL) 550 *(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap; 551 else 552 err = ENOTSUP; 553 break; 554 case MAC_PROP_ADV_5000FDX_CAP: 555 if (speeds & IXGBE_LINK_SPEED_5GB_FULL) 556 *(uint8_t *)pr_val = ixgbe->param_adv_5000fdx_cap; 557 else 558 err = ENOTSUP; 559 break; 560 case MAC_PROP_EN_5000FDX_CAP: 561 if (speeds & IXGBE_LINK_SPEED_5GB_FULL) 562 *(uint8_t *)pr_val = ixgbe->param_en_5000fdx_cap; 563 else 564 err = ENOTSUP; 565 break; 566 case MAC_PROP_ADV_2500FDX_CAP: 567 if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) 568 *(uint8_t *)pr_val = ixgbe->param_adv_2500fdx_cap; 569 else 570 err = ENOTSUP; 571 break; 572 case MAC_PROP_EN_2500FDX_CAP: 573 if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) 574 *(uint8_t *)pr_val = ixgbe->param_en_2500fdx_cap; 575 else 576 err = ENOTSUP; 577 break; 578 case MAC_PROP_ADV_1000FDX_CAP: 579 if (speeds & IXGBE_LINK_SPEED_1GB_FULL) 580 *(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap; 581 else 582 err = ENOTSUP; 583 break; 584 case MAC_PROP_EN_1000FDX_CAP: 585 if (speeds & IXGBE_LINK_SPEED_1GB_FULL) 586 *(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap; 587 else 588 err = ENOTSUP; 589 break; 590 case MAC_PROP_ADV_100FDX_CAP: 591 if (speeds & IXGBE_LINK_SPEED_100_FULL) 592 *(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap; 593 else 594 err = ENOTSUP; 595 break; 596 case MAC_PROP_EN_100FDX_CAP: 597 if (speeds & IXGBE_LINK_SPEED_100_FULL) 598 *(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap; 599 else 600 err = ENOTSUP; 601 break; 602 case MAC_PROP_PRIVATE: 603 err = ixgbe_get_priv_prop(ixgbe, pr_name, 604 pr_valsize, pr_val); 605 break; 606 default: 607 err = ENOTSUP; 608 break; 609 } 610 return (err); 611 } 612 613 void 614 ixgbe_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num, 615 mac_prop_info_handle_t prh) 616 { 617 ixgbe_t *ixgbe = (ixgbe_t *)arg; 618 struct ixgbe_hw *hw = &ixgbe->hw; 619 uint_t perm; 620 uint8_t value; 621 ixgbe_link_speed speeds = 0; 622 623 /* 624 * We cannot always rely on the common code maintaining 625 * hw->phy.speeds_supported, therefore we fall back to use the 626 * recorded supported speeds which were obtained during instance init in 627 * ixgbe_init_params(). 628 */ 629 speeds = hw->phy.speeds_supported; 630 if (speeds == 0) 631 speeds = ixgbe->speeds_supported; 632 633 switch (pr_num) { 634 case MAC_PROP_DUPLEX: 635 case MAC_PROP_SPEED: 636 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 637 break; 638 639 case MAC_PROP_ADV_100FDX_CAP: 640 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 641 value = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0; 642 mac_prop_info_set_default_uint8(prh, value); 643 break; 644 645 case MAC_PROP_ADV_1000FDX_CAP: 646 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 647 value = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0; 648 mac_prop_info_set_default_uint8(prh, value); 649 break; 650 651 case MAC_PROP_ADV_2500FDX_CAP: 652 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 653 value = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0; 654 mac_prop_info_set_default_uint8(prh, value); 655 break; 656 657 case MAC_PROP_ADV_5000FDX_CAP: 658 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 659 value = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0; 660 mac_prop_info_set_default_uint8(prh, value); 661 break; 662 663 case MAC_PROP_ADV_10GFDX_CAP: 664 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 665 value = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0; 666 mac_prop_info_set_default_uint8(prh, value); 667 break; 668 669 /* 670 * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked 671 * read-only on non-baseT (SFP) PHYs. 672 */ 673 case MAC_PROP_AUTONEG: 674 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 675 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 676 mac_prop_info_set_perm(prh, perm); 677 mac_prop_info_set_default_uint8(prh, 1); 678 break; 679 680 case MAC_PROP_EN_10GFDX_CAP: 681 if (speeds & IXGBE_LINK_SPEED_10GB_FULL) { 682 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 683 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 684 mac_prop_info_set_perm(prh, perm); 685 mac_prop_info_set_default_uint8(prh, 1); 686 } 687 break; 688 689 case MAC_PROP_EN_5000FDX_CAP: 690 if (speeds & IXGBE_LINK_SPEED_5GB_FULL) { 691 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 692 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 693 mac_prop_info_set_perm(prh, perm); 694 mac_prop_info_set_default_uint8(prh, 1); 695 } 696 break; 697 698 case MAC_PROP_EN_2500FDX_CAP: 699 if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) { 700 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 701 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 702 mac_prop_info_set_perm(prh, perm); 703 mac_prop_info_set_default_uint8(prh, 1); 704 } 705 break; 706 707 case MAC_PROP_EN_1000FDX_CAP: 708 if (speeds & IXGBE_LINK_SPEED_1GB_FULL) { 709 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 710 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 711 mac_prop_info_set_perm(prh, perm); 712 mac_prop_info_set_default_uint8(prh, 1); 713 } 714 break; 715 716 case MAC_PROP_EN_100FDX_CAP: 717 if (speeds & IXGBE_LINK_SPEED_100_FULL) { 718 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 719 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 720 mac_prop_info_set_perm(prh, perm); 721 mac_prop_info_set_default_uint8(prh, 1); 722 } 723 break; 724 725 case MAC_PROP_FLOWCTRL: 726 mac_prop_info_set_default_link_flowctrl(prh, 727 LINK_FLOWCTRL_NONE); 728 break; 729 730 case MAC_PROP_MTU: 731 mac_prop_info_set_range_uint32(prh, 732 DEFAULT_MTU, ixgbe->capab->max_mtu); 733 break; 734 735 case MAC_PROP_PRIVATE: { 736 char valstr[64]; 737 int value; 738 739 bzero(valstr, sizeof (valstr)); 740 741 if (strcmp(pr_name, "_adv_pause_cap") == 0 || 742 strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 743 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 744 return; 745 } 746 747 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 748 value = DEFAULT_TX_COPY_THRESHOLD; 749 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 750 value = DEFAULT_TX_RECYCLE_THRESHOLD; 751 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 752 value = DEFAULT_TX_OVERLOAD_THRESHOLD; 753 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 754 value = DEFAULT_TX_RESCHED_THRESHOLD; 755 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 756 value = DEFAULT_RX_COPY_THRESHOLD; 757 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 758 value = DEFAULT_RX_LIMIT_PER_INTR; 759 } if (strcmp(pr_name, "_intr_throttling") == 0) { 760 value = ixgbe->capab->def_intr_throttle; 761 } else { 762 return; 763 } 764 765 (void) snprintf(valstr, sizeof (valstr), "%x", value); 766 } 767 } 768 } 769 770 boolean_t 771 ixgbe_param_locked(mac_prop_id_t pr_num) 772 { 773 /* 774 * All en_* parameters are locked (read-only) while 775 * the device is in any sort of loopback mode ... 776 */ 777 switch (pr_num) { 778 case MAC_PROP_EN_10GFDX_CAP: 779 case MAC_PROP_EN_5000FDX_CAP: 780 case MAC_PROP_EN_2500FDX_CAP: 781 case MAC_PROP_EN_1000FDX_CAP: 782 case MAC_PROP_EN_100FDX_CAP: 783 case MAC_PROP_AUTONEG: 784 case MAC_PROP_FLOWCTRL: 785 return (B_TRUE); 786 } 787 return (B_FALSE); 788 } 789 790 /* ARGSUSED */ 791 int 792 ixgbe_set_priv_prop(ixgbe_t *ixgbe, const char *pr_name, 793 uint_t pr_valsize, const void *pr_val) 794 { 795 int err = 0; 796 long result; 797 struct ixgbe_hw *hw = &ixgbe->hw; 798 int i; 799 800 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 801 if (pr_val == NULL) { 802 err = EINVAL; 803 return (err); 804 } 805 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 806 if (result < MIN_TX_COPY_THRESHOLD || 807 result > MAX_TX_COPY_THRESHOLD) 808 err = EINVAL; 809 else { 810 ixgbe->tx_copy_thresh = (uint32_t)result; 811 } 812 return (err); 813 } 814 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 815 if (pr_val == NULL) { 816 err = EINVAL; 817 return (err); 818 } 819 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 820 if (result < MIN_TX_RECYCLE_THRESHOLD || 821 result > MAX_TX_RECYCLE_THRESHOLD) 822 err = EINVAL; 823 else { 824 ixgbe->tx_recycle_thresh = (uint32_t)result; 825 } 826 return (err); 827 } 828 if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 829 if (pr_val == NULL) { 830 err = EINVAL; 831 return (err); 832 } 833 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 834 if (result < MIN_TX_OVERLOAD_THRESHOLD || 835 result > MAX_TX_OVERLOAD_THRESHOLD) 836 err = EINVAL; 837 else { 838 ixgbe->tx_overload_thresh = (uint32_t)result; 839 } 840 return (err); 841 } 842 if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 843 if (pr_val == NULL) { 844 err = EINVAL; 845 return (err); 846 } 847 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 848 if (result < MIN_TX_RESCHED_THRESHOLD || 849 result > MAX_TX_RESCHED_THRESHOLD) 850 err = EINVAL; 851 else { 852 ixgbe->tx_resched_thresh = (uint32_t)result; 853 } 854 return (err); 855 } 856 if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 857 if (pr_val == NULL) { 858 err = EINVAL; 859 return (err); 860 } 861 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 862 if (result < MIN_RX_COPY_THRESHOLD || 863 result > MAX_RX_COPY_THRESHOLD) 864 err = EINVAL; 865 else { 866 ixgbe->rx_copy_thresh = (uint32_t)result; 867 } 868 return (err); 869 } 870 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 871 if (pr_val == NULL) { 872 err = EINVAL; 873 return (err); 874 } 875 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 876 if (result < MIN_RX_LIMIT_PER_INTR || 877 result > MAX_RX_LIMIT_PER_INTR) 878 err = EINVAL; 879 else { 880 ixgbe->rx_limit_per_intr = (uint32_t)result; 881 } 882 return (err); 883 } 884 if (strcmp(pr_name, "_intr_throttling") == 0) { 885 if (pr_val == NULL) { 886 err = EINVAL; 887 return (err); 888 } 889 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 890 891 if (result < ixgbe->capab->min_intr_throttle || 892 result > ixgbe->capab->max_intr_throttle) 893 err = EINVAL; 894 else { 895 ixgbe->intr_throttling[0] = (uint32_t)result; 896 897 /* 898 * 82599, X540 and X550 require the interrupt throttling 899 * rate is a multiple of 8. This is enforced by the 900 * register definiton. 901 */ 902 if (hw->mac.type == ixgbe_mac_82599EB || 903 hw->mac.type == ixgbe_mac_X540 || 904 hw->mac.type == ixgbe_mac_X550 || 905 hw->mac.type == ixgbe_mac_X550EM_x) { 906 ixgbe->intr_throttling[0] = 907 ixgbe->intr_throttling[0] & 0xFF8; 908 } 909 910 for (i = 0; i < MAX_INTR_VECTOR; i++) 911 ixgbe->intr_throttling[i] = 912 ixgbe->intr_throttling[0]; 913 914 /* Set interrupt throttling rate */ 915 for (i = 0; i < ixgbe->intr_cnt; i++) 916 IXGBE_WRITE_REG(hw, IXGBE_EITR(i), 917 ixgbe->intr_throttling[i]); 918 } 919 return (err); 920 } 921 return (ENOTSUP); 922 } 923 924 int 925 ixgbe_get_priv_prop(ixgbe_t *ixgbe, const char *pr_name, 926 uint_t pr_valsize, void *pr_val) 927 { 928 int err = ENOTSUP; 929 int value; 930 931 if (strcmp(pr_name, "_adv_pause_cap") == 0) { 932 value = ixgbe->param_adv_pause_cap; 933 err = 0; 934 goto done; 935 } 936 if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 937 value = ixgbe->param_adv_asym_pause_cap; 938 err = 0; 939 goto done; 940 } 941 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 942 value = ixgbe->tx_copy_thresh; 943 err = 0; 944 goto done; 945 } 946 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 947 value = ixgbe->tx_recycle_thresh; 948 err = 0; 949 goto done; 950 } 951 if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 952 value = ixgbe->tx_overload_thresh; 953 err = 0; 954 goto done; 955 } 956 if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 957 value = ixgbe->tx_resched_thresh; 958 err = 0; 959 goto done; 960 } 961 if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 962 value = ixgbe->rx_copy_thresh; 963 err = 0; 964 goto done; 965 } 966 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 967 value = ixgbe->rx_limit_per_intr; 968 err = 0; 969 goto done; 970 } 971 if (strcmp(pr_name, "_intr_throttling") == 0) { 972 value = ixgbe->intr_throttling[0]; 973 err = 0; 974 goto done; 975 } 976 done: 977 if (err == 0) { 978 (void) snprintf(pr_val, pr_valsize, "%d", value); 979 } 980 return (err); 981 } 982