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 err = ENOTSUP; /* read-only prop. Can't set this. */ 504 break; 505 case MAC_PROP_MTU: 506 cur_mtu = ixgbe->default_mtu; 507 bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 508 if (new_mtu == cur_mtu) { 509 err = 0; 510 break; 511 } 512 513 if (new_mtu < DEFAULT_MTU || new_mtu > ixgbe->capab->max_mtu) { 514 err = EINVAL; 515 break; 516 } 517 518 if (ixgbe->ixgbe_state & IXGBE_STARTED) { 519 err = EBUSY; 520 break; 521 } 522 523 err = mac_maxsdu_update(ixgbe->mac_hdl, new_mtu); 524 if (err == 0) { 525 ixgbe->default_mtu = new_mtu; 526 ixgbe->max_frame_size = ixgbe->default_mtu + 527 sizeof (struct ether_vlan_header) + ETHERFCSL; 528 529 /* 530 * Set rx buffer size 531 */ 532 rx_size = ixgbe->max_frame_size + IPHDR_ALIGN_ROOM; 533 ixgbe->rx_buf_size = ((rx_size >> 10) + ((rx_size & 534 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 535 536 /* 537 * Set tx buffer size 538 */ 539 tx_size = ixgbe->max_frame_size; 540 ixgbe->tx_buf_size = ((tx_size >> 10) + ((tx_size & 541 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 542 } 543 break; 544 case MAC_PROP_PRIVATE: 545 err = ixgbe_set_priv_prop(ixgbe, pr_name, pr_valsize, pr_val); 546 break; 547 default: 548 err = ENOTSUP; 549 break; 550 } 551 mutex_exit(&ixgbe->gen_lock); 552 return (err); 553 } 554 555 int 556 ixgbe_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 557 uint_t pr_valsize, void *pr_val) 558 { 559 ixgbe_t *ixgbe = (ixgbe_t *)arg; 560 struct ixgbe_hw *hw = &ixgbe->hw; 561 int err = 0; 562 uint32_t flow_control; 563 uint64_t tmp = 0; 564 ixgbe_link_speed speeds = 0; 565 566 /* 567 * We cannot always rely on the common code maintaining 568 * hw->phy.speeds_supported, therefore we fall back to use the recorded 569 * supported speeds which were obtained during instance init in 570 * ixgbe_init_params(). 571 */ 572 speeds = hw->phy.speeds_supported; 573 if (speeds == 0) 574 speeds = ixgbe->speeds_supported; 575 576 switch (pr_num) { 577 case MAC_PROP_DUPLEX: 578 ASSERT(pr_valsize >= sizeof (link_duplex_t)); 579 bcopy(&ixgbe->link_duplex, pr_val, 580 sizeof (link_duplex_t)); 581 break; 582 case MAC_PROP_SPEED: 583 ASSERT(pr_valsize >= sizeof (uint64_t)); 584 tmp = ixgbe->link_speed * 1000000ull; 585 bcopy(&tmp, pr_val, sizeof (tmp)); 586 break; 587 case MAC_PROP_AUTONEG: 588 *(uint8_t *)pr_val = ixgbe->param_adv_autoneg_cap; 589 break; 590 case MAC_PROP_FLOWCTRL: 591 ASSERT(pr_valsize >= sizeof (uint32_t)); 592 593 switch (hw->fc.requested_mode) { 594 case ixgbe_fc_none: 595 flow_control = LINK_FLOWCTRL_NONE; 596 break; 597 case ixgbe_fc_rx_pause: 598 flow_control = LINK_FLOWCTRL_RX; 599 break; 600 case ixgbe_fc_tx_pause: 601 flow_control = LINK_FLOWCTRL_TX; 602 break; 603 case ixgbe_fc_full: 604 flow_control = LINK_FLOWCTRL_BI; 605 break; 606 } 607 bcopy(&flow_control, pr_val, sizeof (flow_control)); 608 break; 609 case MAC_PROP_ADV_10GFDX_CAP: 610 if (speeds & IXGBE_LINK_SPEED_10GB_FULL) 611 *(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap; 612 else 613 err = ENOTSUP; 614 break; 615 case MAC_PROP_EN_10GFDX_CAP: 616 if (speeds & IXGBE_LINK_SPEED_10GB_FULL) 617 *(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap; 618 else 619 err = ENOTSUP; 620 break; 621 case MAC_PROP_ADV_5000FDX_CAP: 622 if (speeds & IXGBE_LINK_SPEED_5GB_FULL) 623 *(uint8_t *)pr_val = ixgbe->param_adv_5000fdx_cap; 624 else 625 err = ENOTSUP; 626 break; 627 case MAC_PROP_EN_5000FDX_CAP: 628 if (speeds & IXGBE_LINK_SPEED_5GB_FULL) 629 *(uint8_t *)pr_val = ixgbe->param_en_5000fdx_cap; 630 else 631 err = ENOTSUP; 632 break; 633 case MAC_PROP_ADV_2500FDX_CAP: 634 if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) 635 *(uint8_t *)pr_val = ixgbe->param_adv_2500fdx_cap; 636 else 637 err = ENOTSUP; 638 break; 639 case MAC_PROP_EN_2500FDX_CAP: 640 if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) 641 *(uint8_t *)pr_val = ixgbe->param_en_2500fdx_cap; 642 else 643 err = ENOTSUP; 644 break; 645 case MAC_PROP_ADV_1000FDX_CAP: 646 if (speeds & IXGBE_LINK_SPEED_1GB_FULL) 647 *(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap; 648 else 649 err = ENOTSUP; 650 break; 651 case MAC_PROP_EN_1000FDX_CAP: 652 if (speeds & IXGBE_LINK_SPEED_1GB_FULL) 653 *(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap; 654 else 655 err = ENOTSUP; 656 break; 657 case MAC_PROP_ADV_100FDX_CAP: 658 if (speeds & IXGBE_LINK_SPEED_100_FULL) 659 *(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap; 660 else 661 err = ENOTSUP; 662 break; 663 case MAC_PROP_EN_100FDX_CAP: 664 if (speeds & IXGBE_LINK_SPEED_100_FULL) 665 *(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap; 666 else 667 err = ENOTSUP; 668 break; 669 case MAC_PROP_PRIVATE: 670 err = ixgbe_get_priv_prop(ixgbe, pr_name, 671 pr_valsize, pr_val); 672 break; 673 default: 674 err = ENOTSUP; 675 break; 676 } 677 return (err); 678 } 679 680 void 681 ixgbe_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num, 682 mac_prop_info_handle_t prh) 683 { 684 ixgbe_t *ixgbe = (ixgbe_t *)arg; 685 struct ixgbe_hw *hw = &ixgbe->hw; 686 uint_t perm; 687 uint8_t value; 688 ixgbe_link_speed speeds = 0; 689 690 /* 691 * We cannot always rely on the common code maintaining 692 * hw->phy.speeds_supported, therefore we fall back to use the 693 * recorded supported speeds which were obtained during instance init in 694 * ixgbe_init_params(). 695 */ 696 speeds = hw->phy.speeds_supported; 697 if (speeds == 0) 698 speeds = ixgbe->speeds_supported; 699 700 switch (pr_num) { 701 case MAC_PROP_DUPLEX: 702 case MAC_PROP_SPEED: 703 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 704 break; 705 706 case MAC_PROP_ADV_100FDX_CAP: 707 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 708 value = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0; 709 mac_prop_info_set_default_uint8(prh, value); 710 break; 711 712 case MAC_PROP_ADV_1000FDX_CAP: 713 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 714 value = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0; 715 mac_prop_info_set_default_uint8(prh, value); 716 break; 717 718 case MAC_PROP_ADV_2500FDX_CAP: 719 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 720 value = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0; 721 mac_prop_info_set_default_uint8(prh, value); 722 break; 723 724 case MAC_PROP_ADV_5000FDX_CAP: 725 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 726 value = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0; 727 mac_prop_info_set_default_uint8(prh, value); 728 break; 729 730 case MAC_PROP_ADV_10GFDX_CAP: 731 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 732 value = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0; 733 mac_prop_info_set_default_uint8(prh, value); 734 break; 735 736 /* 737 * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked 738 * read-only on non-baseT (SFP) PHYs. 739 */ 740 case MAC_PROP_AUTONEG: 741 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 742 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 743 mac_prop_info_set_perm(prh, perm); 744 mac_prop_info_set_default_uint8(prh, 1); 745 break; 746 747 case MAC_PROP_EN_10GFDX_CAP: 748 if (speeds & IXGBE_LINK_SPEED_10GB_FULL) { 749 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 750 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 751 mac_prop_info_set_perm(prh, perm); 752 mac_prop_info_set_default_uint8(prh, 1); 753 } 754 break; 755 756 case MAC_PROP_EN_5000FDX_CAP: 757 if (speeds & IXGBE_LINK_SPEED_5GB_FULL) { 758 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 759 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 760 mac_prop_info_set_perm(prh, perm); 761 mac_prop_info_set_default_uint8(prh, 1); 762 } 763 break; 764 765 case MAC_PROP_EN_2500FDX_CAP: 766 if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) { 767 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 768 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 769 mac_prop_info_set_perm(prh, perm); 770 mac_prop_info_set_default_uint8(prh, 1); 771 } 772 break; 773 774 case MAC_PROP_EN_1000FDX_CAP: 775 if (speeds & IXGBE_LINK_SPEED_1GB_FULL) { 776 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 777 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 778 mac_prop_info_set_perm(prh, perm); 779 mac_prop_info_set_default_uint8(prh, 1); 780 } 781 break; 782 783 case MAC_PROP_EN_100FDX_CAP: 784 if (speeds & IXGBE_LINK_SPEED_100_FULL) { 785 perm = (hw->phy.media_type == ixgbe_media_type_copper) ? 786 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; 787 mac_prop_info_set_perm(prh, perm); 788 mac_prop_info_set_default_uint8(prh, 1); 789 } 790 break; 791 792 case MAC_PROP_FLOWCTRL: 793 mac_prop_info_set_default_link_flowctrl(prh, 794 LINK_FLOWCTRL_NONE); 795 break; 796 797 case MAC_PROP_MTU: 798 mac_prop_info_set_range_uint32(prh, 799 DEFAULT_MTU, ixgbe->capab->max_mtu); 800 break; 801 802 case MAC_PROP_PRIVATE: { 803 char valstr[64]; 804 int value; 805 806 bzero(valstr, sizeof (valstr)); 807 808 if (strcmp(pr_name, "_adv_pause_cap") == 0 || 809 strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 810 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 811 return; 812 } 813 814 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 815 value = DEFAULT_TX_COPY_THRESHOLD; 816 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 817 value = DEFAULT_TX_RECYCLE_THRESHOLD; 818 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 819 value = DEFAULT_TX_OVERLOAD_THRESHOLD; 820 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 821 value = DEFAULT_TX_RESCHED_THRESHOLD; 822 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 823 value = DEFAULT_RX_COPY_THRESHOLD; 824 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 825 value = DEFAULT_RX_LIMIT_PER_INTR; 826 } else if (strcmp(pr_name, "_intr_throttling") == 0) { 827 value = ixgbe->capab->def_intr_throttle; 828 } else { 829 return; 830 } 831 832 (void) snprintf(valstr, sizeof (valstr), "%x", value); 833 } 834 } 835 } 836 837 boolean_t 838 ixgbe_param_locked(mac_prop_id_t pr_num) 839 { 840 /* 841 * All en_* parameters are locked (read-only) while 842 * the device is in any sort of loopback mode ... 843 */ 844 switch (pr_num) { 845 case MAC_PROP_EN_10GFDX_CAP: 846 case MAC_PROP_EN_5000FDX_CAP: 847 case MAC_PROP_EN_2500FDX_CAP: 848 case MAC_PROP_EN_1000FDX_CAP: 849 case MAC_PROP_EN_100FDX_CAP: 850 case MAC_PROP_AUTONEG: 851 case MAC_PROP_FLOWCTRL: 852 return (B_TRUE); 853 } 854 return (B_FALSE); 855 } 856 857 /* ARGSUSED */ 858 int 859 ixgbe_set_priv_prop(ixgbe_t *ixgbe, const char *pr_name, 860 uint_t pr_valsize, const void *pr_val) 861 { 862 int err = 0; 863 long result; 864 struct ixgbe_hw *hw = &ixgbe->hw; 865 int i; 866 867 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 868 if (pr_val == NULL) { 869 err = EINVAL; 870 return (err); 871 } 872 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 873 if (result < MIN_TX_COPY_THRESHOLD || 874 result > MAX_TX_COPY_THRESHOLD) 875 err = EINVAL; 876 else { 877 ixgbe->tx_copy_thresh = (uint32_t)result; 878 } 879 return (err); 880 } 881 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 882 if (pr_val == NULL) { 883 err = EINVAL; 884 return (err); 885 } 886 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 887 if (result < MIN_TX_RECYCLE_THRESHOLD || 888 result > MAX_TX_RECYCLE_THRESHOLD) 889 err = EINVAL; 890 else { 891 ixgbe->tx_recycle_thresh = (uint32_t)result; 892 } 893 return (err); 894 } 895 if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 896 if (pr_val == NULL) { 897 err = EINVAL; 898 return (err); 899 } 900 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 901 if (result < MIN_TX_OVERLOAD_THRESHOLD || 902 result > MAX_TX_OVERLOAD_THRESHOLD) 903 err = EINVAL; 904 else { 905 ixgbe->tx_overload_thresh = (uint32_t)result; 906 } 907 return (err); 908 } 909 if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 910 if (pr_val == NULL) { 911 err = EINVAL; 912 return (err); 913 } 914 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 915 if (result < MIN_TX_RESCHED_THRESHOLD || 916 result > MAX_TX_RESCHED_THRESHOLD) 917 err = EINVAL; 918 else { 919 ixgbe->tx_resched_thresh = (uint32_t)result; 920 } 921 return (err); 922 } 923 if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 924 if (pr_val == NULL) { 925 err = EINVAL; 926 return (err); 927 } 928 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 929 if (result < MIN_RX_COPY_THRESHOLD || 930 result > MAX_RX_COPY_THRESHOLD) 931 err = EINVAL; 932 else { 933 ixgbe->rx_copy_thresh = (uint32_t)result; 934 } 935 return (err); 936 } 937 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 938 if (pr_val == NULL) { 939 err = EINVAL; 940 return (err); 941 } 942 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 943 if (result < MIN_RX_LIMIT_PER_INTR || 944 result > MAX_RX_LIMIT_PER_INTR) 945 err = EINVAL; 946 else { 947 ixgbe->rx_limit_per_intr = (uint32_t)result; 948 } 949 return (err); 950 } 951 if (strcmp(pr_name, "_intr_throttling") == 0) { 952 if (pr_val == NULL) { 953 err = EINVAL; 954 return (err); 955 } 956 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 957 958 if (result < ixgbe->capab->min_intr_throttle || 959 result > ixgbe->capab->max_intr_throttle) 960 err = EINVAL; 961 else { 962 ixgbe->intr_throttling[0] = (uint32_t)result; 963 964 /* 965 * 82599, X540 and X550 require the interrupt throttling 966 * rate is a multiple of 8. This is enforced by the 967 * register definiton. 968 */ 969 if (hw->mac.type == ixgbe_mac_82599EB || 970 hw->mac.type == ixgbe_mac_X540 || 971 hw->mac.type == ixgbe_mac_X550 || 972 hw->mac.type == ixgbe_mac_X550EM_x) { 973 ixgbe->intr_throttling[0] = 974 ixgbe->intr_throttling[0] & 0xFF8; 975 } 976 977 for (i = 0; i < MAX_INTR_VECTOR; i++) 978 ixgbe->intr_throttling[i] = 979 ixgbe->intr_throttling[0]; 980 981 /* Set interrupt throttling rate */ 982 for (i = 0; i < ixgbe->intr_cnt; i++) 983 IXGBE_WRITE_REG(hw, IXGBE_EITR(i), 984 ixgbe->intr_throttling[i]); 985 } 986 return (err); 987 } 988 return (ENOTSUP); 989 } 990 991 int 992 ixgbe_get_priv_prop(ixgbe_t *ixgbe, const char *pr_name, 993 uint_t pr_valsize, void *pr_val) 994 { 995 int err = ENOTSUP; 996 int value; 997 998 if (strcmp(pr_name, "_adv_pause_cap") == 0) { 999 value = ixgbe->param_adv_pause_cap; 1000 err = 0; 1001 goto done; 1002 } 1003 if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 1004 value = ixgbe->param_adv_asym_pause_cap; 1005 err = 0; 1006 goto done; 1007 } 1008 if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 1009 value = ixgbe->tx_copy_thresh; 1010 err = 0; 1011 goto done; 1012 } 1013 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 1014 value = ixgbe->tx_recycle_thresh; 1015 err = 0; 1016 goto done; 1017 } 1018 if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 1019 value = ixgbe->tx_overload_thresh; 1020 err = 0; 1021 goto done; 1022 } 1023 if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 1024 value = ixgbe->tx_resched_thresh; 1025 err = 0; 1026 goto done; 1027 } 1028 if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 1029 value = ixgbe->rx_copy_thresh; 1030 err = 0; 1031 goto done; 1032 } 1033 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 1034 value = ixgbe->rx_limit_per_intr; 1035 err = 0; 1036 goto done; 1037 } 1038 if (strcmp(pr_name, "_intr_throttling") == 0) { 1039 value = ixgbe->intr_throttling[0]; 1040 err = 0; 1041 goto done; 1042 } 1043 done: 1044 if (err == 0) { 1045 (void) snprintf(pr_val, pr_valsize, "%d", value); 1046 } 1047 return (err); 1048 } 1049