Print this page
9095 ixgbe MAC_CAPAB_LED support
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Sebastian Wiedenroth <sebastian.wiedenroth@skylime.net>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
NEX-2081 ixgbe triggers warning when receiving too many interrupt vectors from DDI
SUP-479 10 Gigabit CX4 Dual Port Server Adapter EXPX9502CX4 unresponsive to external pings after upgrade from 3.1.2 to 3.1.3.5

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/ixgbe/ixgbe_main.c
          +++ new/usr/src/uts/common/io/ixgbe/ixgbe_main.c
↓ open down ↓ 18 lines elided ↑ open up ↑
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
  24   24   */
  25   25  
  26   26  /*
  27   27   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  28   28   * Copyright (c) 2017, Joyent, Inc.
  29      - * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
       29 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  30   30   * Copyright (c) 2013 Saso Kiselkov. All rights reserved.
  31   31   * Copyright (c) 2013 OSN Online Service Nuernberg GmbH. All rights reserved.
  32   32   * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
  33   33   */
  34   34  
  35   35  #include "ixgbe_sw.h"
  36   36  
  37   37  static char ixgbe_ident[] = "Intel 10Gb Ethernet";
  38   38  
  39   39  /*
↓ open down ↓ 446 lines elided ↑ open up ↑
 486  486          }
 487  487          ixgbe->attach_progress |= ATTACH_PROGRESS_REGS_MAP;
 488  488  
 489  489          /*
 490  490           * Initialize driver parameters
 491  491           */
 492  492          ixgbe_init_properties(ixgbe);
 493  493          ixgbe->attach_progress |= ATTACH_PROGRESS_PROPS;
 494  494  
 495  495          /*
 496      -         * Register interrupt callback
 497      -         */
 498      -        if (ixgbe_intr_cb_register(ixgbe) != IXGBE_SUCCESS) {
 499      -                ixgbe_error(ixgbe, "Failed to register interrupt callback");
 500      -                goto attach_fail;
 501      -        }
 502      -
 503      -        /*
 504  496           * Allocate interrupts
 505  497           */
 506  498          if (ixgbe_alloc_intrs(ixgbe) != IXGBE_SUCCESS) {
 507  499                  ixgbe_error(ixgbe, "Failed to allocate interrupts");
 508  500                  goto attach_fail;
 509  501          }
 510  502          ixgbe->attach_progress |= ATTACH_PROGRESS_ALLOC_INTR;
 511  503  
 512  504          /*
 513  505           * Allocate rx/tx rings based on the ring numbers.
↓ open down ↓ 129 lines elided ↑ open up ↑
 643  635           */
 644  636          if (ixgbe_enable_intrs(ixgbe) != IXGBE_SUCCESS) {
 645  637                  ixgbe_error(ixgbe, "Failed to enable DDI interrupts");
 646  638                  goto attach_fail;
 647  639          }
 648  640          ixgbe->attach_progress |= ATTACH_PROGRESS_ENABLE_INTR;
 649  641  
 650  642          ixgbe_log(ixgbe, "%s", ixgbe_ident);
 651  643          atomic_or_32(&ixgbe->ixgbe_state, IXGBE_INITIALIZED);
 652  644  
      645 +        /*
      646 +         * Register interrupt callback
      647 +         */
      648 +        if (ixgbe->intr_type == DDI_INTR_TYPE_MSIX)
      649 +                if (ixgbe_intr_cb_register(ixgbe) != IXGBE_SUCCESS) {
      650 +                        ixgbe_error(ixgbe,
      651 +                            "Failed to register interrupt callback");
      652 +                }
      653 +
 653  654          return (DDI_SUCCESS);
 654  655  
 655  656  attach_fail:
 656  657          ixgbe_unconfigure(devinfo, ixgbe);
 657  658          return (DDI_FAILURE);
 658  659  }
 659  660  
 660  661  /*
 661  662   * ixgbe_detach - Driver detach.
 662  663   *
↓ open down ↓ 108 lines elided ↑ open up ↑
 771  772           */
 772  773          (void) ixgbe_reset_phy(hw);
 773  774  
 774  775          return (DDI_SUCCESS);
 775  776  }
 776  777  
 777  778  static void
 778  779  ixgbe_unconfigure(dev_info_t *devinfo, ixgbe_t *ixgbe)
 779  780  {
 780  781          /*
      782 +         * Unregister interrupt callback handler
      783 +         */
      784 +        if (ixgbe->cb_hdl != NULL)
      785 +                (void) ddi_cb_unregister(ixgbe->cb_hdl);
      786 +
      787 +        /*
 781  788           * Disable interrupt
 782  789           */
 783  790          if (ixgbe->attach_progress & ATTACH_PROGRESS_ENABLE_INTR) {
 784  791                  (void) ixgbe_disable_intrs(ixgbe);
 785  792          }
 786  793  
 787  794          /*
 788  795           * remove the link check timer
 789  796           */
 790  797          if (ixgbe->attach_progress & ATTACH_PROGRESS_LINK_TIMER) {
↓ open down ↓ 443 lines elided ↑ open up ↑
1234 1241                  mutex_destroy(&tx_ring->tx_lock);
1235 1242                  mutex_destroy(&tx_ring->recycle_lock);
1236 1243                  mutex_destroy(&tx_ring->tcb_head_lock);
1237 1244                  mutex_destroy(&tx_ring->tcb_tail_lock);
1238 1245          }
1239 1246  
1240 1247          mutex_destroy(&ixgbe->gen_lock);
1241 1248          mutex_destroy(&ixgbe->watchdog_lock);
1242 1249  }
1243 1250  
     1251 +/*
     1252 + * We need to try and determine which LED index in hardware corresponds to the
     1253 + * link/activity LED. This is the one that'll be overwritten when we perform
     1254 + * GLDv3 LED activity.
     1255 + */
     1256 +static void
     1257 +ixgbe_led_init(ixgbe_t *ixgbe)
     1258 +{
     1259 +        uint32_t reg, i;
     1260 +        struct ixgbe_hw *hw = &ixgbe->hw;
     1261 +
     1262 +        reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
     1263 +        for (i = 0; i < 4; i++) {
     1264 +                if (((reg >> IXGBE_LED_MODE_SHIFT(i)) &
     1265 +                    IXGBE_LED_MODE_MASK_BASE) == IXGBE_LED_LINK_ACTIVE) {
     1266 +                        ixgbe->ixgbe_led_index = i;
     1267 +                        return;
     1268 +                }
     1269 +        }
     1270 +
     1271 +        /*
     1272 +         * If we couldn't determine this, we use the default for various MACs
     1273 +         * based on information Intel has inserted into other drivers over the
     1274 +         * years.  Note, when we have support for the X553 which should add the
     1275 +         * ixgbe_x550_em_a mac type, that should be at index 0.
     1276 +         */
     1277 +        switch (hw->mac.type) {
     1278 +        case ixgbe_mac_X550EM_x:
     1279 +                ixgbe->ixgbe_led_index = 1;
     1280 +                break;
     1281 +        default:
     1282 +                ixgbe->ixgbe_led_index = 2;
     1283 +                break;
     1284 +        }
     1285 +}
     1286 +
1244 1287  static int
1245 1288  ixgbe_resume(dev_info_t *devinfo)
1246 1289  {
1247 1290          ixgbe_t *ixgbe;
1248 1291          int i;
1249 1292  
1250 1293          ixgbe = (ixgbe_t *)ddi_get_driver_private(devinfo);
1251 1294          if (ixgbe == NULL)
1252 1295                  return (DDI_FAILURE);
1253 1296  
↓ open down ↓ 134 lines elided ↑ open up ↑
1388 1431                              "the vendor to update the NVM.");
1389 1432                          ixgbe_fm_ereport(ixgbe, DDI_FM_DEVICE_INVAL_STATE);
1390 1433                          goto init_fail;
1391 1434                  }
1392 1435          }
1393 1436  
1394 1437          /*
1395 1438           * Setup default flow control thresholds - enable/disable
1396 1439           * & flow control type is controlled by ixgbe.conf
1397 1440           */
1398      -        hw->fc.high_water[0] = DEFAULT_FCRTH;
1399      -        hw->fc.low_water[0] = DEFAULT_FCRTL;
     1441 +        {
     1442 +                uint32_t rxpb, frame, size, hitmp, lotmp;
     1443 +
     1444 +                frame = ixgbe->max_frame_size;
     1445 +
     1446 +                /* Calculate High and Low Water */
     1447 +                if (hw->mac.type == ixgbe_mac_X540) {
     1448 +                        hitmp = IXGBE_DV_X540(frame, frame);
     1449 +                        lotmp = IXGBE_LOW_DV_X540(frame);
     1450 +                } else {
     1451 +                                hitmp = IXGBE_DV(frame, frame);
     1452 +                                lotmp = IXGBE_LOW_DV(frame);
     1453 +                }
     1454 +                size = IXGBE_BT2KB(hitmp);
     1455 +                rxpb = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) >> 10;
     1456 +                hw->fc.high_water[0] = rxpb - size;
     1457 +                hw->fc.low_water[0] = IXGBE_BT2KB(lotmp);
     1458 +        }
     1459 +
1400 1460          hw->fc.pause_time = DEFAULT_FCPAUSE;
1401 1461          hw->fc.send_xon = B_TRUE;
1402 1462  
1403 1463          /*
1404 1464           * Initialize flow control
1405 1465           */
1406 1466          (void) ixgbe_start_hw(hw);
1407 1467  
1408 1468          /*
1409 1469           * Initialize link settings
↓ open down ↓ 11 lines elided ↑ open up ↑
1421 1481          /*
1422 1482           * Read identifying information and place in devinfo.
1423 1483           */
1424 1484          pbanum[0] = '\0';
1425 1485          (void) ixgbe_read_pba_string(hw, pbanum, sizeof (pbanum));
1426 1486          if (*pbanum != '\0') {
1427 1487                  (void) ddi_prop_update_string(DDI_DEV_T_NONE, ixgbe->dip,
1428 1488                      "printed-board-assembly", (char *)pbanum);
1429 1489          }
1430 1490  
     1491 +        /*
     1492 +         * Determine LED index.
     1493 +         */
     1494 +        ixgbe_led_init(ixgbe);
     1495 +
1431 1496          if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
1432 1497                  goto init_fail;
1433 1498          }
1434 1499  
1435 1500          mutex_exit(&ixgbe->gen_lock);
1436 1501          return (IXGBE_SUCCESS);
1437 1502  
1438 1503  init_fail:
1439 1504          /*
1440 1505           * Reset PHY
↓ open down ↓ 544 lines elided ↑ open up ↑
1985 2050          return (DDI_FAILURE);
1986 2051  }
1987 2052  
1988 2053  /*
1989 2054   * ixgbe_intr_adjust - Adjust interrupt to respond to IRM request.
1990 2055   */
1991 2056  static int
1992 2057  ixgbe_intr_adjust(ixgbe_t *ixgbe, ddi_cb_action_t cbaction, int count)
1993 2058  {
1994 2059          int i, rc, actual;
     2060 +        uint32_t started;
1995 2061  
1996      -        if (count == 0)
1997      -                return (DDI_SUCCESS);
1998      -
1999      -        if ((cbaction == DDI_CB_INTR_ADD &&
2000      -            ixgbe->intr_cnt + count > ixgbe->intr_cnt_max) ||
2001      -            (cbaction == DDI_CB_INTR_REMOVE &&
2002      -            ixgbe->intr_cnt - count < ixgbe->intr_cnt_min))
     2062 +        if (!(ixgbe->ixgbe_state & IXGBE_INITIALIZED)) {
2003 2063                  return (DDI_FAILURE);
     2064 +        }
2004 2065  
2005      -        if (!(ixgbe->ixgbe_state & IXGBE_STARTED)) {
     2066 +        if (cbaction == DDI_CB_INTR_REMOVE &&
     2067 +            ixgbe->intr_cnt - count < ixgbe->intr_cnt_min)
2006 2068                  return (DDI_FAILURE);
2007      -        }
2008 2069  
     2070 +        if (cbaction == DDI_CB_INTR_ADD &&
     2071 +            ixgbe->intr_cnt + count > ixgbe->intr_cnt_max)
     2072 +                count = ixgbe->intr_cnt_max - ixgbe->intr_cnt;
     2073 +
     2074 +        if (count == 0)
     2075 +                return (DDI_SUCCESS);
     2076 +
2009 2077          for (i = 0; i < ixgbe->num_rx_rings; i++)
2010 2078                  mac_ring_intr_set(ixgbe->rx_rings[i].ring_handle, NULL);
2011 2079          for (i = 0; i < ixgbe->num_tx_rings; i++)
2012 2080                  mac_ring_intr_set(ixgbe->tx_rings[i].ring_handle, NULL);
2013 2081  
2014 2082          mutex_enter(&ixgbe->gen_lock);
     2083 +        started = ixgbe->ixgbe_state & IXGBE_STARTED;
2015 2084          ixgbe->ixgbe_state &= ~IXGBE_STARTED;
2016 2085          ixgbe->ixgbe_state |= IXGBE_INTR_ADJUST;
2017 2086          ixgbe->ixgbe_state |= IXGBE_SUSPENDED;
2018 2087          mac_link_update(ixgbe->mac_hdl, LINK_STATE_UNKNOWN);
2019 2088  
2020      -        ixgbe_stop(ixgbe, B_FALSE);
     2089 +        if (started)
     2090 +                ixgbe_stop(ixgbe, B_FALSE);
2021 2091          /*
2022 2092           * Disable interrupts
2023 2093           */
2024 2094          if (ixgbe->attach_progress & ATTACH_PROGRESS_ENABLE_INTR) {
2025 2095                  rc = ixgbe_disable_intrs(ixgbe);
2026 2096                  ASSERT(rc == IXGBE_SUCCESS);
2027 2097          }
2028 2098          ixgbe->attach_progress &= ~ATTACH_PROGRESS_ENABLE_INTR;
2029 2099  
2030 2100          /*
↓ open down ↓ 74 lines elided ↑ open up ↑
2105 2175  
2106 2176          /*
2107 2177           * Now that mutex locks are initialized, and the chip is also
2108 2178           * initialized, enable interrupts.
2109 2179           */
2110 2180          if (ixgbe_enable_intrs(ixgbe) != IXGBE_SUCCESS) {
2111 2181                  ixgbe_error(ixgbe, "IRM CB: Failed to enable DDI interrupts");
2112 2182                  goto intr_adjust_fail;
2113 2183          }
2114 2184          ixgbe->attach_progress |= ATTACH_PROGRESS_ENABLE_INTR;
2115      -        if (ixgbe_start(ixgbe, B_FALSE) != IXGBE_SUCCESS) {
2116      -                ixgbe_error(ixgbe, "IRM CB: Failed to start");
2117      -                goto intr_adjust_fail;
2118      -        }
     2185 +        if (started)
     2186 +                if (ixgbe_start(ixgbe, B_FALSE) != IXGBE_SUCCESS) {
     2187 +                        ixgbe_error(ixgbe, "IRM CB: Failed to start");
     2188 +                        goto intr_adjust_fail;
     2189 +                }
2119 2190          ixgbe->ixgbe_state &= ~IXGBE_INTR_ADJUST;
2120 2191          ixgbe->ixgbe_state &= ~IXGBE_SUSPENDED;
2121      -        ixgbe->ixgbe_state |= IXGBE_STARTED;
     2192 +        ixgbe->ixgbe_state |= started;
2122 2193          mutex_exit(&ixgbe->gen_lock);
2123 2194  
2124 2195          for (i = 0; i < ixgbe->num_rx_rings; i++) {
2125 2196                  mac_ring_intr_set(ixgbe->rx_rings[i].ring_handle,
2126 2197                      ixgbe->htable[ixgbe->rx_rings[i].intr_vector]);
2127 2198          }
2128 2199          for (i = 0; i < ixgbe->num_tx_rings; i++) {
2129 2200                  mac_ring_intr_set(ixgbe->tx_rings[i].ring_handle,
2130 2201                      ixgbe->htable[ixgbe->tx_rings[i].intr_vector]);
2131 2202          }
↓ open down ↓ 1538 lines elided ↑ open up ↑
3670 3741          ixgbe_link_speed speed = IXGBE_LINK_SPEED_UNKNOWN;
3671 3742          boolean_t link_up = B_FALSE;
3672 3743          boolean_t link_changed = B_FALSE;
3673 3744  
3674 3745          ASSERT(mutex_owned(&ixgbe->gen_lock));
3675 3746  
3676 3747          (void) ixgbe_check_link(hw, &speed, &link_up, B_FALSE);
3677 3748          if (link_up) {
3678 3749                  ixgbe->link_check_complete = B_TRUE;
3679 3750  
3680      -                /* Link is up, enable flow control settings */
3681      -                (void) ixgbe_fc_enable(hw);
3682      -
3683 3751                  /*
3684 3752                   * The Link is up, check whether it was marked as down earlier
3685 3753                   */
3686 3754                  if (ixgbe->link_state != LINK_STATE_UP) {
     3755 +
     3756 +                        /* Link is up, enable flow control settings */
     3757 +                        (void) ixgbe_fc_enable(hw);
     3758 +
3687 3759                          switch (speed) {
3688 3760                          case IXGBE_LINK_SPEED_10GB_FULL:
3689 3761                                  ixgbe->link_speed = SPEED_10GB;
3690 3762                                  break;
3691 3763                          case IXGBE_LINK_SPEED_5GB_FULL:
3692 3764                                  ixgbe->link_speed = SPEED_5GB;
3693 3765                                  break;
3694 3766                          case IXGBE_LINK_SPEED_2_5GB_FULL:
3695 3767                                  ixgbe->link_speed = SPEED_2_5GB;
3696 3768                                  break;
↓ open down ↓ 2627 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX