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