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) 2019, 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 static int 224 ixgbe_led_set(void *arg, mac_led_mode_t mode, uint_t flags) 225 { 226 ixgbe_t *ixgbe = arg; 227 struct ixgbe_hw *hw = &ixgbe->hw; 228 uint32_t lidx = ixgbe->ixgbe_led_index; 229 230 if (flags != 0) 231 return (EINVAL); 232 233 if (mode != MAC_LED_DEFAULT && 234 mode != MAC_LED_IDENT && 235 mode != MAC_LED_OFF && 236 mode != MAC_LED_ON) 237 return (ENOTSUP); 238 239 if (ixgbe->ixgbe_led_blink && mode != MAC_LED_IDENT) { 240 if (ixgbe_blink_led_stop(hw, lidx) != IXGBE_SUCCESS) { 241 return (EIO); 242 } 243 ixgbe->ixgbe_led_blink = B_FALSE; 244 } 245 246 if (mode != MAC_LED_DEFAULT && !ixgbe->ixgbe_led_active) { 247 ixgbe->ixgbe_led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 248 ixgbe->ixgbe_led_active = B_TRUE; 249 } 250 251 switch (mode) { 252 case MAC_LED_DEFAULT: 253 if (ixgbe->ixgbe_led_active) { 254 IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ixgbe->ixgbe_led_reg); 255 ixgbe->ixgbe_led_active = B_FALSE; 256 } 257 break; 258 case MAC_LED_IDENT: 259 if (ixgbe_blink_led_start(hw, lidx) != IXGBE_SUCCESS) 260 return (EIO); 261 ixgbe->ixgbe_led_blink = B_TRUE; 262 break; 263 case MAC_LED_OFF: 264 if (ixgbe_led_off(hw, lidx) != IXGBE_SUCCESS) 265 return (EIO); 266 break; 267 case MAC_LED_ON: 268 if (ixgbe_led_on(hw, lidx) != IXGBE_SUCCESS) 269 return (EIO); 270 break; 271 default: 272 return (ENOTSUP); 273 } 274 275 return (0); 276 } 277 278 /* 279 * Obtain the MAC's capabilities and associated data from 280 * the driver. 281 */ 282 boolean_t 283 ixgbe_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 284 { 285 ixgbe_t *ixgbe = (ixgbe_t *)arg; 286 287 switch (cap) { 288 case MAC_CAPAB_HCKSUM: { 289 uint32_t *tx_hcksum_flags = cap_data; 290 291 /* 292 * We advertise our capabilities only if tx hcksum offload is 293 * enabled. On receive, the stack will accept checksummed 294 * packets anyway, even if we haven't said we can deliver 295 * them. 296 */ 297 if (!ixgbe->tx_hcksum_enable) 298 return (B_FALSE); 299 300 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM; 301 break; 302 } 303 case MAC_CAPAB_LSO: { 304 mac_capab_lso_t *cap_lso = cap_data; 305 306 if (ixgbe->lso_enable) { 307 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4 | 308 LSO_TX_BASIC_TCP_IPV6; 309 cap_lso->lso_basic_tcp_ipv4.lso_max = IXGBE_LSO_MAXLEN; 310 cap_lso->lso_basic_tcp_ipv6.lso_max = IXGBE_LSO_MAXLEN; 311 break; 312 } else { 313 return (B_FALSE); 314 } 315 } 316 case MAC_CAPAB_RINGS: { 317 mac_capab_rings_t *cap_rings = cap_data; 318 319 switch (cap_rings->mr_type) { 320 case MAC_RING_TYPE_RX: 321 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 322 cap_rings->mr_rnum = ixgbe->num_rx_rings; 323 cap_rings->mr_gnum = ixgbe->num_rx_groups; 324 cap_rings->mr_rget = ixgbe_fill_ring; 325 cap_rings->mr_gget = ixgbe_fill_group; 326 cap_rings->mr_gaddring = NULL; 327 cap_rings->mr_gremring = NULL; 328 break; 329 case MAC_RING_TYPE_TX: 330 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 331 cap_rings->mr_rnum = ixgbe->num_tx_rings; 332 cap_rings->mr_gnum = 0; 333 cap_rings->mr_rget = ixgbe_fill_ring; 334 cap_rings->mr_gget = NULL; 335 break; 336 default: 337 break; 338 } 339 break; 340 } 341 case MAC_CAPAB_TRANSCEIVER: { 342 mac_capab_transceiver_t *mct = cap_data; 343 344 /* 345 * Rather than try and guess based on the media type whether or 346 * not we have a transceiver we can read, we instead will let 347 * the actual function calls figure that out for us. 348 */ 349 mct->mct_flags = 0; 350 mct->mct_ntransceivers = 1; 351 mct->mct_info = ixgbe_transceiver_info; 352 mct->mct_read = ixgbe_transceiver_read; 353 return (B_TRUE); 354 } 355 case MAC_CAPAB_LED: { 356 mac_capab_led_t *mcl = cap_data; 357 358 mcl->mcl_flags = 0; 359 mcl->mcl_modes = MAC_LED_DEFAULT | MAC_LED_ON | MAC_LED_OFF | 360 MAC_LED_IDENT; 361 mcl->mcl_set = ixgbe_led_set; 362 break; 363 364 } 365 default: 366 return (B_FALSE); 367 } 368 return (B_TRUE); 369 } 370 371 int 372 ixgbe_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 373 uint_t pr_valsize, const void *pr_val) 374 { 375 ixgbe_t *ixgbe = (ixgbe_t *)arg; 376 struct ixgbe_hw *hw = &ixgbe->hw; 377 int err = 0; 378 uint32_t flow_control; 379 uint32_t cur_mtu, new_mtu; 380 uint32_t rx_size; 381 uint32_t tx_size; 382 ixgbe_link_speed speeds = 0; 383 384 mutex_enter(&ixgbe->gen_lock); 385 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) { 386 mutex_exit(&ixgbe->gen_lock); 387 return (ECANCELED); 388 } 389 390 /* 391 * We cannot always rely on the common code maintaining 392 * hw->phy.speeds_supported, therefore we fall back to use the recorded 393 * supported speeds which were obtained during instance init in 394 * ixgbe_init_params(). 395 */ 396 speeds = hw->phy.speeds_supported; 397 if (speeds == 0) 398 speeds = ixgbe->speeds_supported; 399 400 if (ixgbe->loopback_mode != IXGBE_LB_NONE && 401 ixgbe_param_locked(pr_num)) { 402 /* 403 * All en_* parameters are locked (read-only) 404 * while the device is in any sort of loopback mode. 405 */ 406 mutex_exit(&ixgbe->gen_lock); 407 return (EBUSY); 408 } 409 410 /* 411 * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked 412 * read-only on non-baseT PHYs. 413 */ 414 switch (pr_num) { 415 case MAC_PROP_EN_10GFDX_CAP: 416 if (hw->phy.media_type == ixgbe_media_type_copper && 417 speeds & IXGBE_LINK_SPEED_10GB_FULL) { 418 ixgbe->param_en_10000fdx_cap = *(uint8_t *)pr_val; 419 goto setup_link; 420 } else { 421 err = ENOTSUP; 422 break; 423 } 424 case MAC_PROP_EN_5000FDX_CAP: 425 if (hw->phy.media_type == ixgbe_media_type_copper && 426 speeds & IXGBE_LINK_SPEED_5GB_FULL) { 427 ixgbe->param_en_5000fdx_cap = *(uint8_t *)pr_val; 428 goto setup_link; 429 } else { 430 err = ENOTSUP; 431 break; 432 } 433 case MAC_PROP_EN_2500FDX_CAP: 434 if (hw->phy.media_type == ixgbe_media_type_copper && 435 speeds & IXGBE_LINK_SPEED_2_5GB_FULL) { 436 ixgbe->param_en_2500fdx_cap = *(uint8_t *)pr_val; 437 goto setup_link; 438 } else { 439 err = ENOTSUP; 440 break; 441 } 442 case MAC_PROP_EN_1000FDX_CAP: 443 if (hw->phy.media_type == ixgbe_media_type_copper && 444 speeds & IXGBE_LINK_SPEED_1GB_FULL) { 445 ixgbe->param_en_1000fdx_cap = *(uint8_t *)pr_val; 446 goto setup_link; 447 } else { 448 err = ENOTSUP; 449 break; 450 } 451 case MAC_PROP_EN_100FDX_CAP: 452 if (hw->phy.media_type == ixgbe_media_type_copper && 453 speeds & IXGBE_LINK_SPEED_100_FULL) { 454 ixgbe->param_en_100fdx_cap = *(uint8_t *)pr_val; 455 goto setup_link; 456 } else { 457 err = ENOTSUP; 458 break; 459 } 460 case MAC_PROP_AUTONEG: 461 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) { 462 err = ENOTSUP; 463 break; 464 } else { 465 ixgbe->param_adv_autoneg_cap = *(uint8_t *)pr_val; 466 goto setup_link; 467 } 468 case MAC_PROP_FLOWCTRL: 469 bcopy(pr_val, &flow_control, sizeof (flow_control)); 470 471 switch (flow_control) { 472 default: 473 err = EINVAL; 474 break; 475 case LINK_FLOWCTRL_NONE: 476 hw->fc.requested_mode = ixgbe_fc_none; 477 break; 478 case LINK_FLOWCTRL_RX: 479 hw->fc.requested_mode = ixgbe_fc_rx_pause; 480 break; 481 case LINK_FLOWCTRL_TX: 482 hw->fc.requested_mode = ixgbe_fc_tx_pause; 483 break; 484 case LINK_FLOWCTRL_BI: 485 hw->fc.requested_mode = ixgbe_fc_full; 486 break; 487 } 488 setup_link: 489 if (err == 0) { 490 if (ixgbe_driver_setup_link(ixgbe, B_TRUE) != 491 IXGBE_SUCCESS) 492 err = EINVAL; 493 } 494 break; 495 case MAC_PROP_ADV_10GFDX_CAP: 496 case MAC_PROP_ADV_5000FDX_CAP: 497 case MAC_PROP_ADV_2500FDX_CAP: 498 case MAC_PROP_ADV_1000FDX_CAP: 499 case MAC_PROP_ADV_100FDX_CAP: 500 case MAC_PROP_STATUS: 501 case MAC_PROP_SPEED: 502 case MAC_PROP_DUPLEX: 503 case MAC_PROP_MEDIA: 504 err = ENOTSUP; /* read-only prop. Can't set this. */ 505 break; 506 case MAC_PROP_MTU: 507 cur_mtu = ixgbe->default_mtu; 508 bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 509 if (new_mtu == cur_mtu) { 510 err = 0; 511 break; 512 } 513 514 if (new_mtu < DEFAULT_MTU || new_mtu > ixgbe->capab->max_mtu) { 515 err = EINVAL; 516 break; 517 } 518 519 if (ixgbe->ixgbe_state & IXGBE_STARTED) { 520 err = EBUSY; 521 break; 522 } 523 524 err = mac_maxsdu_update(ixgbe->mac_hdl, new_mtu); 525 if (err == 0) { 526 ixgbe->default_mtu = new_mtu; 527 ixgbe->max_frame_size = ixgbe->default_mtu + 528 sizeof (struct ether_vlan_header) + ETHERFCSL; 529 530 /* 531 * Set rx buffer size 532 */ 533 rx_size = ixgbe->max_frame_size + IPHDR_ALIGN_ROOM; 534 ixgbe->rx_buf_size = ((rx_size >> 10) + ((rx_size & 535 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 536 537 /* 538 * Set tx buffer size 539 */ 540 tx_size = ixgbe->max_frame_size; 541 ixgbe->tx_buf_size = ((tx_size >> 10) + ((tx_size & 542 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 543 } 544 break; 545 case MAC_PROP_PRIVATE: 546 err = ixgbe_set_priv_prop(ixgbe, pr_name, pr_valsize, pr_val); 547 break; 548 default: 549 err = ENOTSUP; 550 break; 551 } 552 mutex_exit(&ixgbe->gen_lock); 553 return (err); 554 } 555 556 int 557 ixgbe_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 558 uint_t pr_valsize, void *pr_val) 559 { 560 ixgbe_t *ixgbe = (ixgbe_t *)arg; 561 struct ixgbe_hw *hw = &ixgbe->hw; 562 int err = 0; 563 uint32_t flow_control; 564 uint64_t tmp = 0; 565 ixgbe_link_speed speeds = 0; 566 567 /* 568 * We cannot always rely on the common code maintaining 569 * hw->phy.speeds_supported, therefore we fall back to use the recorded 570 * supported speeds which were obtained during instance init in 571 * ixgbe_init_params(). 572 */ 573 speeds = hw->phy.speeds_supported; 574 if (speeds == 0) 575 speeds = ixgbe->speeds_supported; 576 577 switch (pr_num) { 578 case MAC_PROP_DUPLEX: 579 ASSERT(pr_valsize >= sizeof (link_duplex_t)); 580 bcopy(&ixgbe->link_duplex, pr_val, 581 sizeof (link_duplex_t)); 582 break; 583 case MAC_PROP_SPEED: 584 ASSERT(pr_valsize >= sizeof (uint64_t)); 585 tmp = ixgbe->link_speed * 1000000ull; 586 bcopy(&tmp, pr_val, sizeof (tmp)); 587 break; 588 case MAC_PROP_MEDIA: 589 mutex_enter(&ixgbe->gen_lock); 590 *(mac_ether_media_t *)pr_val = ixgbe_phy_to_media(ixgbe); 591 mutex_exit(&ixgbe->gen_lock); 592 break; 593 case MAC_PROP_AUTONEG: 594 *(uint8_t *)pr_val = ixgbe->param_adv_autoneg_cap; 595 break; 596 case MAC_PROP_FLOWCTRL: 597 ASSERT(pr_valsize >= sizeof (uint32_t)); 598 599 switch (hw->fc.requested_mode) { 600 case ixgbe_fc_none: 601 flow_control = LINK_FLOWCTRL_NONE; 602 break; 603 case ixgbe_fc_rx_pause: 604 flow_control = LINK_FLOWCTRL_RX; 605 break; 606 case ixgbe_fc_tx_pause: 607 flow_control = LINK_FLOWCTRL_TX; 608 break; 609 case ixgbe_fc_full: 610 flow_control = LINK_FLOWCTRL_BI; 611 break; 612 } 613 bcopy(&flow_control, pr_val, sizeof (flow_control)); 614 break; 615 case MAC_PROP_ADV_10GFDX_CAP: 616 if (speeds & IXGBE_LINK_SPEED_10GB_FULL) 617 *(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap; 618 else 619 err = ENOTSUP; 620 break; 621 case MAC_PROP_EN_10GFDX_CAP: 622 if (speeds & IXGBE_LINK_SPEED_10GB_FULL) 623 *(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap; 624 else 625 err = ENOTSUP; 626 break; 627 case MAC_PROP_ADV_5000FDX_CAP: 628 if (speeds & IXGBE_LINK_SPEED_5GB_FULL) 629 *(uint8_t *)pr_val = ixgbe->param_adv_5000fdx_cap; 630 else 631 err = ENOTSUP; 632 break; 633 case MAC_PROP_EN_5000FDX_CAP: 634 if (speeds & IXGBE_LINK_SPEED_5GB_FULL) 635 *(uint8_t *)pr_val = ixgbe->param_en_5000fdx_cap; 636 else 637 err = ENOTSUP; 638 break; 639 case MAC_PROP_ADV_2500FDX_CAP: 640 if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) 641 *(uint8_t *)pr_val = ixgbe->param_adv_2500fdx_cap; 642 else 643 err = ENOTSUP; 644 break; 645 case MAC_PROP_EN_2500FDX_CAP: 646 if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) 647 *(uint8_t *)pr_val = ixgbe->param_en_2500fdx_cap; 648 else 649 err = ENOTSUP; 650 break; 651 case MAC_PROP_ADV_1000FDX_CAP: 652 if (speeds & IXGBE_LINK_SPEED_1GB_FULL) 653 *(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap; 654 else 655 err = ENOTSUP; 656 break; 657 case MAC_PROP_EN_1000FDX_CAP: 658 if (speeds & IXGBE_LINK_SPEED_1GB_FULL) 659 *(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap; 660 else 661 err = ENOTSUP; 662 break; 663 case MAC_PROP_ADV_100FDX_CAP: 664 if (speeds & IXGBE_LINK_SPEED_100_FULL) 665 *(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap; 666 else 667 err = ENOTSUP; 668 break; 669 case MAC_PROP_EN_100FDX_CAP: 670 if (speeds & IXGBE_LINK_SPEED_100_FULL) 671 *(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap; 672 else 673 err = ENOTSUP; 674 break; 675 case MAC_PROP_PRIVATE: 676 err = ixgbe_get_priv_prop(ixgbe, pr_name, 677 pr_valsize, pr_val); 678 break; 679 default: 680 err = ENOTSUP; 681 break; 682 } 683 return (err); 684 } 685 686 void 687 ixgbe_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num, 688 mac_prop_info_handle_t prh) 689 { 690 ixgbe_t *ixgbe = (ixgbe_t *)arg; 691 struct ixgbe_hw *hw = &ixgbe->hw; 692 uint_t perm; 693 uint8_t value; 694 ixgbe_link_speed speeds = 0; 695 696 /* 697 * We cannot always rely on the common code maintaining 698 * hw->phy.speeds_supported, therefore we fall back to use the 699 * recorded supported speeds which were obtained during instance init in 700 * ixgbe_init_params(). 701 */ 702 speeds = hw->phy.speeds_supported; 703 if (speeds == 0) 704 speeds = ixgbe->speeds_supported; 705 706 switch (pr_num) { 707 case MAC_PROP_DUPLEX: 708 case MAC_PROP_SPEED: 709 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 710 break; 711 712 case MAC_PROP_ADV_100FDX_CAP: 713 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 714 value = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0; 715 mac_prop_info_set_default_uint8(prh, value); 716 break; 717 718 case MAC_PROP_ADV_1000FDX_CAP: 719 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 720 value = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0; 721 mac_prop_info_set_default_uint8(prh, value); 722 break; 723 724 case MAC_PROP_ADV_2500FDX_CAP: 725 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 726 value = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0; 727 mac_prop_info_set_default_uint8(prh, value); 728 break; 729 730 case MAC_PROP_ADV_5000FDX_CAP: 731 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 732 value = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0; 733 mac_prop_info_set_default_uint8(prh, value); 734 break; 735 736 case MAC_PROP_ADV_10GFDX_CAP: 737 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 738 value = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0; 739 mac_prop_info_set_default_uint8(prh, value); 740 break; 741 742 /* 743 * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked 744 * read-only on non-baseT (SFP) PHYs. 745 */ 746 case MAC_PROP_AUTONEG: 747 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 748 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 749 mac_prop_info_set_perm(prh, perm); 750 mac_prop_info_set_default_uint8(prh, 1); 751 break; 752 753 case MAC_PROP_EN_10GFDX_CAP: 754 if (speeds & IXGBE_LINK_SPEED_10GB_FULL) { 755 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 756 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 757 mac_prop_info_set_perm(prh, perm); 758 mac_prop_info_set_default_uint8(prh, 1); 759 } 760 break; 761 762 case MAC_PROP_EN_5000FDX_CAP: 763 if (speeds & IXGBE_LINK_SPEED_5GB_FULL) { 764 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 765 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 766 mac_prop_info_set_perm(prh, perm); 767 mac_prop_info_set_default_uint8(prh, 1); 768 } 769 break; 770 771 case MAC_PROP_EN_2500FDX_CAP: 772 if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) { 773 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 774 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 775 mac_prop_info_set_perm(prh, perm); 776 mac_prop_info_set_default_uint8(prh, 1); 777 } 778 break; 779 780 case MAC_PROP_EN_1000FDX_CAP: 781 if (speeds & IXGBE_LINK_SPEED_1GB_FULL) { 782 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 783 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 784 mac_prop_info_set_perm(prh, perm); 785 mac_prop_info_set_default_uint8(prh, 1); 786 } 787 break; 788 789 case MAC_PROP_EN_100FDX_CAP: 790 if (speeds & IXGBE_LINK_SPEED_100_FULL) { 791 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 792 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 793 mac_prop_info_set_perm(prh, perm); 794 mac_prop_info_set_default_uint8(prh, 1); 795 } 796 break; 797 798 case MAC_PROP_FLOWCTRL: 799 mac_prop_info_set_default_link_flowctrl(prh, 800 LINK_FLOWCTRL_NONE); 801 break; 802 803 case MAC_PROP_MTU: 804 mac_prop_info_set_range_uint32(prh, 805 DEFAULT_MTU, ixgbe->capab->max_mtu); 806 break; 807 808 case MAC_PROP_PRIVATE: { 809 char valstr[64]; 810 int value; 811 812 bzero(valstr, sizeof (valstr)); 813 814 if (strcmp(pr_name, "_adv_pause_cap") == 0 || 815 strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 816 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 817 return; 818 } 819 820 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 821 value = DEFAULT_TX_COPY_THRESHOLD; 822 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 823 value = DEFAULT_TX_RECYCLE_THRESHOLD; 824 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 825 value = DEFAULT_TX_OVERLOAD_THRESHOLD; 826 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 827 value = DEFAULT_TX_RESCHED_THRESHOLD; 828 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 829 value = DEFAULT_RX_COPY_THRESHOLD; 830 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 831 value = DEFAULT_RX_LIMIT_PER_INTR; 832 } else if (strcmp(pr_name, "_intr_throttling") == 0) { 833 value = ixgbe->capab->def_intr_throttle; 834 } else { 835 return; 836 } 837 838 (void) snprintf(valstr, sizeof (valstr), "%x", value); 839 } 840 } 841 } 842 843 boolean_t 844 ixgbe_param_locked(mac_prop_id_t pr_num) 845 { 846 /* 847 * All en_* parameters are locked (read-only) while 848 * the device is in any sort of loopback mode ... 849 */ 850 switch (pr_num) { 851 case MAC_PROP_EN_10GFDX_CAP: 852 case MAC_PROP_EN_5000FDX_CAP: 853 case MAC_PROP_EN_2500FDX_CAP: 854 case MAC_PROP_EN_1000FDX_CAP: 855 case MAC_PROP_EN_100FDX_CAP: 856 case MAC_PROP_AUTONEG: 857 case MAC_PROP_FLOWCTRL: 858 return (B_TRUE); 859 } 860 return (B_FALSE); 861 } 862 863 /* ARGSUSED */ 864 int 865 ixgbe_set_priv_prop(ixgbe_t *ixgbe, const char *pr_name, 866 uint_t pr_valsize, const void *pr_val) 867 { 868 int err = 0; 869 long result; 870 struct ixgbe_hw *hw = &ixgbe->hw; 871 int i; 872 873 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 874 if (pr_val == NULL) { 875 err = EINVAL; 876 return (err); 877 } 878 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 879 if (result < MIN_TX_COPY_THRESHOLD || 880 result > MAX_TX_COPY_THRESHOLD) 881 err = EINVAL; 882 else { 883 ixgbe->tx_copy_thresh = (uint32_t)result; 884 } 885 return (err); 886 } 887 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 888 if (pr_val == NULL) { 889 err = EINVAL; 890 return (err); 891 } 892 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 893 if (result < MIN_TX_RECYCLE_THRESHOLD || 894 result > MAX_TX_RECYCLE_THRESHOLD) 895 err = EINVAL; 896 else { 897 ixgbe->tx_recycle_thresh = (uint32_t)result; 898 } 899 return (err); 900 } 901 if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 902 if (pr_val == NULL) { 903 err = EINVAL; 904 return (err); 905 } 906 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 907 if (result < MIN_TX_OVERLOAD_THRESHOLD || 908 result > MAX_TX_OVERLOAD_THRESHOLD) 909 err = EINVAL; 910 else { 911 ixgbe->tx_overload_thresh = (uint32_t)result; 912 } 913 return (err); 914 } 915 if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 916 if (pr_val == NULL) { 917 err = EINVAL; 918 return (err); 919 } 920 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 921 if (result < MIN_TX_RESCHED_THRESHOLD || 922 result > MAX_TX_RESCHED_THRESHOLD) 923 err = EINVAL; 924 else { 925 ixgbe->tx_resched_thresh = (uint32_t)result; 926 } 927 return (err); 928 } 929 if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 930 if (pr_val == NULL) { 931 err = EINVAL; 932 return (err); 933 } 934 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 935 if (result < MIN_RX_COPY_THRESHOLD || 936 result > MAX_RX_COPY_THRESHOLD) 937 err = EINVAL; 938 else { 939 ixgbe->rx_copy_thresh = (uint32_t)result; 940 } 941 return (err); 942 } 943 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 944 if (pr_val == NULL) { 945 err = EINVAL; 946 return (err); 947 } 948 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 949 if (result < MIN_RX_LIMIT_PER_INTR || 950 result > MAX_RX_LIMIT_PER_INTR) 951 err = EINVAL; 952 else { 953 ixgbe->rx_limit_per_intr = (uint32_t)result; 954 } 955 return (err); 956 } 957 if (strcmp(pr_name, "_intr_throttling") == 0) { 958 if (pr_val == NULL) { 959 err = EINVAL; 960 return (err); 961 } 962 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 963 964 if (result < ixgbe->capab->min_intr_throttle || 965 result > ixgbe->capab->max_intr_throttle) 966 err = EINVAL; 967 else { 968 ixgbe->intr_throttling[0] = (uint32_t)result; 969 970 /* 971 * 82599, X540 and X550 require the interrupt throttling 972 * rate is a multiple of 8. This is enforced by the 973 * register definiton. 974 */ 975 if (hw->mac.type == ixgbe_mac_82599EB || 976 hw->mac.type == ixgbe_mac_X540 || 977 hw->mac.type == ixgbe_mac_X550 || 978 hw->mac.type == ixgbe_mac_X550EM_x) { 979 ixgbe->intr_throttling[0] = 980 ixgbe->intr_throttling[0] & 0xFF8; 981 } 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_valsize, void *pr_val) 1000 { 1001 int err = ENOTSUP; 1002 int value; 1003 1004 if (strcmp(pr_name, "_adv_pause_cap") == 0) { 1005 value = ixgbe->param_adv_pause_cap; 1006 err = 0; 1007 goto done; 1008 } 1009 if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 1010 value = ixgbe->param_adv_asym_pause_cap; 1011 err = 0; 1012 goto done; 1013 } 1014 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 1015 value = ixgbe->tx_copy_thresh; 1016 err = 0; 1017 goto done; 1018 } 1019 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 1020 value = ixgbe->tx_recycle_thresh; 1021 err = 0; 1022 goto done; 1023 } 1024 if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 1025 value = ixgbe->tx_overload_thresh; 1026 err = 0; 1027 goto done; 1028 } 1029 if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 1030 value = ixgbe->tx_resched_thresh; 1031 err = 0; 1032 goto done; 1033 } 1034 if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 1035 value = ixgbe->rx_copy_thresh; 1036 err = 0; 1037 goto done; 1038 } 1039 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 1040 value = ixgbe->rx_limit_per_intr; 1041 err = 0; 1042 goto done; 1043 } 1044 if (strcmp(pr_name, "_intr_throttling") == 0) { 1045 value = ixgbe->intr_throttling[0]; 1046 err = 0; 1047 goto done; 1048 } 1049 done: 1050 if (err == 0) { 1051 (void) snprintf(pr_val, pr_valsize, "%d", value); 1052 } 1053 return (err); 1054 } 1055