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 (c) 2017, Joyent, Inc.
  29  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  30  * Copyright (c) 2013 Saso Kiselkov. All rights reserved.
  31  * Copyright (c) 2013 OSN Online Service Nuernberg GmbH. All rights reserved.
  32  * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
  33  */
  34 
  35 #include "ixgbe_sw.h"
  36 
  37 static char ixgbe_ident[] = "Intel 10Gb Ethernet";
  38 
  39 /*
  40  * Local function protoypes
  41  */
  42 static int ixgbe_register_mac(ixgbe_t *);
  43 static int ixgbe_identify_hardware(ixgbe_t *);
  44 static int ixgbe_regs_map(ixgbe_t *);
  45 static void ixgbe_init_properties(ixgbe_t *);
  46 static int ixgbe_init_driver_settings(ixgbe_t *);
  47 static void ixgbe_init_locks(ixgbe_t *);
  48 static void ixgbe_destroy_locks(ixgbe_t *);
  49 static int ixgbe_init(ixgbe_t *);
 
 
 476                 ixgbe_error(ixgbe, "Failed to identify hardware");
 477                 goto attach_fail;
 478         }
 479 
 480         /*
 481          * Map device registers
 482          */
 483         if (ixgbe_regs_map(ixgbe) != IXGBE_SUCCESS) {
 484                 ixgbe_error(ixgbe, "Failed to map device registers");
 485                 goto attach_fail;
 486         }
 487         ixgbe->attach_progress |= ATTACH_PROGRESS_REGS_MAP;
 488 
 489         /*
 490          * Initialize driver parameters
 491          */
 492         ixgbe_init_properties(ixgbe);
 493         ixgbe->attach_progress |= ATTACH_PROGRESS_PROPS;
 494 
 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          * Allocate interrupts
 505          */
 506         if (ixgbe_alloc_intrs(ixgbe) != IXGBE_SUCCESS) {
 507                 ixgbe_error(ixgbe, "Failed to allocate interrupts");
 508                 goto attach_fail;
 509         }
 510         ixgbe->attach_progress |= ATTACH_PROGRESS_ALLOC_INTR;
 511 
 512         /*
 513          * Allocate rx/tx rings based on the ring numbers.
 514          * The actual numbers of rx/tx rings are decided by the number of
 515          * allocated interrupt vectors, so we should allocate the rings after
 516          * interrupts are allocated.
 517          */
 518         if (ixgbe_alloc_rings(ixgbe) != IXGBE_SUCCESS) {
 519                 ixgbe_error(ixgbe, "Failed to allocate rx and tx rings");
 520                 goto attach_fail;
 521         }
 522         ixgbe->attach_progress |= ATTACH_PROGRESS_ALLOC_RINGS;
 523 
 
 633             IXGBE_CYCLIC_PERIOD, DDI_IPL_0);
 634         if (ixgbe->periodic_id == 0) {
 635                 ixgbe_error(ixgbe, "Failed to add the link check timer");
 636                 goto attach_fail;
 637         }
 638         ixgbe->attach_progress |= ATTACH_PROGRESS_LINK_TIMER;
 639 
 640         /*
 641          * Now that mutex locks are initialized, and the chip is also
 642          * initialized, enable interrupts.
 643          */
 644         if (ixgbe_enable_intrs(ixgbe) != IXGBE_SUCCESS) {
 645                 ixgbe_error(ixgbe, "Failed to enable DDI interrupts");
 646                 goto attach_fail;
 647         }
 648         ixgbe->attach_progress |= ATTACH_PROGRESS_ENABLE_INTR;
 649 
 650         ixgbe_log(ixgbe, "%s", ixgbe_ident);
 651         atomic_or_32(&ixgbe->ixgbe_state, IXGBE_INITIALIZED);
 652 
 653         return (DDI_SUCCESS);
 654 
 655 attach_fail:
 656         ixgbe_unconfigure(devinfo, ixgbe);
 657         return (DDI_FAILURE);
 658 }
 659 
 660 /*
 661  * ixgbe_detach - Driver detach.
 662  *
 663  * The detach() function is the complement of the attach routine.
 664  * If cmd is set to DDI_DETACH, detach() is used to remove  the
 665  * state  associated  with  a  given  instance of a device node
 666  * prior to the removal of that instance from the system.
 667  *
 668  * The detach() function will be called once for each  instance
 669  * of the device for which there has been a successful attach()
 670  * once there are no longer  any  opens  on  the  device.
 671  *
 672  * Interrupts routine are disabled, All memory allocated by this
 
 761          */
 762         ixgbe_release_driver_control(hw);
 763 
 764         /*
 765          * Reset the chipset
 766          */
 767         (void) ixgbe_reset_hw(hw);
 768 
 769         /*
 770          * Reset PHY
 771          */
 772         (void) ixgbe_reset_phy(hw);
 773 
 774         return (DDI_SUCCESS);
 775 }
 776 
 777 static void
 778 ixgbe_unconfigure(dev_info_t *devinfo, ixgbe_t *ixgbe)
 779 {
 780         /*
 781          * Disable interrupt
 782          */
 783         if (ixgbe->attach_progress & ATTACH_PROGRESS_ENABLE_INTR) {
 784                 (void) ixgbe_disable_intrs(ixgbe);
 785         }
 786 
 787         /*
 788          * remove the link check timer
 789          */
 790         if (ixgbe->attach_progress & ATTACH_PROGRESS_LINK_TIMER) {
 791                 if (ixgbe->periodic_id != NULL) {
 792                         ddi_periodic_delete(ixgbe->periodic_id);
 793                         ixgbe->periodic_id = NULL;
 794                 }
 795         }
 796 
 797         /*
 798          * Unregister MAC
 799          */
 800         if (ixgbe->attach_progress & ATTACH_PROGRESS_MAC) {
 
1224         ixgbe_tx_ring_t *tx_ring;
1225         int i;
1226 
1227         for (i = 0; i < ixgbe->num_rx_rings; i++) {
1228                 rx_ring = &ixgbe->rx_rings[i];
1229                 mutex_destroy(&rx_ring->rx_lock);
1230         }
1231 
1232         for (i = 0; i < ixgbe->num_tx_rings; i++) {
1233                 tx_ring = &ixgbe->tx_rings[i];
1234                 mutex_destroy(&tx_ring->tx_lock);
1235                 mutex_destroy(&tx_ring->recycle_lock);
1236                 mutex_destroy(&tx_ring->tcb_head_lock);
1237                 mutex_destroy(&tx_ring->tcb_tail_lock);
1238         }
1239 
1240         mutex_destroy(&ixgbe->gen_lock);
1241         mutex_destroy(&ixgbe->watchdog_lock);
1242 }
1243 
1244 static int
1245 ixgbe_resume(dev_info_t *devinfo)
1246 {
1247         ixgbe_t *ixgbe;
1248         int i;
1249 
1250         ixgbe = (ixgbe_t *)ddi_get_driver_private(devinfo);
1251         if (ixgbe == NULL)
1252                 return (DDI_FAILURE);
1253 
1254         mutex_enter(&ixgbe->gen_lock);
1255 
1256         if (ixgbe->ixgbe_state & IXGBE_STARTED) {
1257                 if (ixgbe_start(ixgbe, B_FALSE) != IXGBE_SUCCESS) {
1258                         mutex_exit(&ixgbe->gen_lock);
1259                         return (DDI_FAILURE);
1260                 }
1261 
1262                 /*
1263                  * Enable and start the watchdog timer
 
1378          */
1379         if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
1380                 /*
1381                  * Some PCI-E parts fail the first check due to
1382                  * the link being in sleep state.  Call it again,
1383                  * if it fails a second time it's a real issue.
1384                  */
1385                 if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
1386                         ixgbe_error(ixgbe,
1387                             "Invalid NVM checksum. Please contact "
1388                             "the vendor to update the NVM.");
1389                         ixgbe_fm_ereport(ixgbe, DDI_FM_DEVICE_INVAL_STATE);
1390                         goto init_fail;
1391                 }
1392         }
1393 
1394         /*
1395          * Setup default flow control thresholds - enable/disable
1396          * & flow control type is controlled by ixgbe.conf
1397          */
1398         hw->fc.high_water[0] = DEFAULT_FCRTH;
1399         hw->fc.low_water[0] = DEFAULT_FCRTL;
1400         hw->fc.pause_time = DEFAULT_FCPAUSE;
1401         hw->fc.send_xon = B_TRUE;
1402 
1403         /*
1404          * Initialize flow control
1405          */
1406         (void) ixgbe_start_hw(hw);
1407 
1408         /*
1409          * Initialize link settings
1410          */
1411         (void) ixgbe_driver_setup_link(ixgbe, B_FALSE);
1412 
1413         /*
1414          * Initialize the chipset hardware
1415          */
1416         if (ixgbe_chip_start(ixgbe) != IXGBE_SUCCESS) {
1417                 ixgbe_fm_ereport(ixgbe, DDI_FM_DEVICE_INVAL_STATE);
1418                 goto init_fail;
1419         }
1420 
1421         /*
1422          * Read identifying information and place in devinfo.
1423          */
1424         pbanum[0] = '\0';
1425         (void) ixgbe_read_pba_string(hw, pbanum, sizeof (pbanum));
1426         if (*pbanum != '\0') {
1427                 (void) ddi_prop_update_string(DDI_DEV_T_NONE, ixgbe->dip,
1428                     "printed-board-assembly", (char *)pbanum);
1429         }
1430 
1431         if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
1432                 goto init_fail;
1433         }
1434 
1435         mutex_exit(&ixgbe->gen_lock);
1436         return (IXGBE_SUCCESS);
1437 
1438 init_fail:
1439         /*
1440          * Reset PHY
1441          */
1442         (void) ixgbe_reset_phy(hw);
1443 
1444         mutex_exit(&ixgbe->gen_lock);
1445         ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_LOST);
1446         return (IXGBE_FAILURE);
1447 }
1448 
1449 /*
1450  * ixgbe_chip_start - Initialize and start the chipset hardware.
 
1975                         goto cb_fail;
1976                 }
1977                 break;
1978         default:
1979                 IXGBE_DEBUGLOG_1(ixgbe, "DDI CB: action 0x%x NOT supported",
1980                     cbaction);
1981                 return (DDI_ENOTSUP);
1982         }
1983         return (DDI_SUCCESS);
1984 cb_fail:
1985         return (DDI_FAILURE);
1986 }
1987 
1988 /*
1989  * ixgbe_intr_adjust - Adjust interrupt to respond to IRM request.
1990  */
1991 static int
1992 ixgbe_intr_adjust(ixgbe_t *ixgbe, ddi_cb_action_t cbaction, int count)
1993 {
1994         int i, rc, actual;
1995 
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))
2003                 return (DDI_FAILURE);
2004 
2005         if (!(ixgbe->ixgbe_state & IXGBE_STARTED)) {
2006                 return (DDI_FAILURE);
2007         }
2008 
2009         for (i = 0; i < ixgbe->num_rx_rings; i++)
2010                 mac_ring_intr_set(ixgbe->rx_rings[i].ring_handle, NULL);
2011         for (i = 0; i < ixgbe->num_tx_rings; i++)
2012                 mac_ring_intr_set(ixgbe->tx_rings[i].ring_handle, NULL);
2013 
2014         mutex_enter(&ixgbe->gen_lock);
2015         ixgbe->ixgbe_state &= ~IXGBE_STARTED;
2016         ixgbe->ixgbe_state |= IXGBE_INTR_ADJUST;
2017         ixgbe->ixgbe_state |= IXGBE_SUSPENDED;
2018         mac_link_update(ixgbe->mac_hdl, LINK_STATE_UNKNOWN);
2019 
2020         ixgbe_stop(ixgbe, B_FALSE);
2021         /*
2022          * Disable interrupts
2023          */
2024         if (ixgbe->attach_progress & ATTACH_PROGRESS_ENABLE_INTR) {
2025                 rc = ixgbe_disable_intrs(ixgbe);
2026                 ASSERT(rc == IXGBE_SUCCESS);
2027         }
2028         ixgbe->attach_progress &= ~ATTACH_PROGRESS_ENABLE_INTR;
2029 
2030         /*
2031          * Remove interrupt handlers
2032          */
2033         if (ixgbe->attach_progress & ATTACH_PROGRESS_ADD_INTR) {
2034                 ixgbe_rem_intr_handlers(ixgbe);
2035         }
2036         ixgbe->attach_progress &= ~ATTACH_PROGRESS_ADD_INTR;
2037 
2038         /*
2039          * Clear vect_map
 
2095         }
2096 
2097         /*
2098          * Add interrupt handlers
2099          */
2100         if (ixgbe_add_intr_handlers(ixgbe) != IXGBE_SUCCESS) {
2101                 ixgbe_error(ixgbe, "IRM CB: Failed to add interrupt handlers");
2102                 goto intr_adjust_fail;
2103         }
2104         ixgbe->attach_progress |= ATTACH_PROGRESS_ADD_INTR;
2105 
2106         /*
2107          * Now that mutex locks are initialized, and the chip is also
2108          * initialized, enable interrupts.
2109          */
2110         if (ixgbe_enable_intrs(ixgbe) != IXGBE_SUCCESS) {
2111                 ixgbe_error(ixgbe, "IRM CB: Failed to enable DDI interrupts");
2112                 goto intr_adjust_fail;
2113         }
2114         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         }
2119         ixgbe->ixgbe_state &= ~IXGBE_INTR_ADJUST;
2120         ixgbe->ixgbe_state &= ~IXGBE_SUSPENDED;
2121         ixgbe->ixgbe_state |= IXGBE_STARTED;
2122         mutex_exit(&ixgbe->gen_lock);
2123 
2124         for (i = 0; i < ixgbe->num_rx_rings; i++) {
2125                 mac_ring_intr_set(ixgbe->rx_rings[i].ring_handle,
2126                     ixgbe->htable[ixgbe->rx_rings[i].intr_vector]);
2127         }
2128         for (i = 0; i < ixgbe->num_tx_rings; i++) {
2129                 mac_ring_intr_set(ixgbe->tx_rings[i].ring_handle,
2130                     ixgbe->htable[ixgbe->tx_rings[i].intr_vector]);
2131         }
2132 
2133         /* Wakeup all Tx rings */
2134         for (i = 0; i < ixgbe->num_tx_rings; i++) {
2135                 mac_tx_ring_update(ixgbe->mac_hdl,
2136                     ixgbe->tx_rings[i].ring_handle);
2137         }
2138 
2139         IXGBE_DEBUGLOG_3(ixgbe,
2140             "IRM CB: interrupts new value: 0x%x(0x%x:0x%x).",
2141             ixgbe->intr_cnt, ixgbe->intr_cnt_min, ixgbe->intr_cnt_max);
 
3660 
3661 /*
3662  * ixgbe_driver_link_check - Link status processing.
3663  *
3664  * This function can be called in both kernel context and interrupt context
3665  */
3666 static void
3667 ixgbe_driver_link_check(ixgbe_t *ixgbe)
3668 {
3669         struct ixgbe_hw *hw = &ixgbe->hw;
3670         ixgbe_link_speed speed = IXGBE_LINK_SPEED_UNKNOWN;
3671         boolean_t link_up = B_FALSE;
3672         boolean_t link_changed = B_FALSE;
3673 
3674         ASSERT(mutex_owned(&ixgbe->gen_lock));
3675 
3676         (void) ixgbe_check_link(hw, &speed, &link_up, B_FALSE);
3677         if (link_up) {
3678                 ixgbe->link_check_complete = B_TRUE;
3679 
3680                 /* Link is up, enable flow control settings */
3681                 (void) ixgbe_fc_enable(hw);
3682 
3683                 /*
3684                  * The Link is up, check whether it was marked as down earlier
3685                  */
3686                 if (ixgbe->link_state != LINK_STATE_UP) {
3687                         switch (speed) {
3688                         case IXGBE_LINK_SPEED_10GB_FULL:
3689                                 ixgbe->link_speed = SPEED_10GB;
3690                                 break;
3691                         case IXGBE_LINK_SPEED_5GB_FULL:
3692                                 ixgbe->link_speed = SPEED_5GB;
3693                                 break;
3694                         case IXGBE_LINK_SPEED_2_5GB_FULL:
3695                                 ixgbe->link_speed = SPEED_2_5GB;
3696                                 break;
3697                         case IXGBE_LINK_SPEED_1GB_FULL:
3698                                 ixgbe->link_speed = SPEED_1GB;
3699                                 break;
3700                         case IXGBE_LINK_SPEED_100_FULL:
3701                                 ixgbe->link_speed = SPEED_100;
3702                         }
3703                         ixgbe->link_duplex = LINK_DUPLEX_FULL;
3704                         ixgbe->link_state = LINK_STATE_UP;
3705                         link_changed = B_TRUE;
3706                 }
 
 | 
 
 
   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 (c) 2017, Joyent, Inc.
  29  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  30  * Copyright (c) 2013 Saso Kiselkov. All rights reserved.
  31  * Copyright (c) 2013 OSN Online Service Nuernberg GmbH. All rights reserved.
  32  * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
  33  */
  34 
  35 #include "ixgbe_sw.h"
  36 
  37 static char ixgbe_ident[] = "Intel 10Gb Ethernet";
  38 
  39 /*
  40  * Local function protoypes
  41  */
  42 static int ixgbe_register_mac(ixgbe_t *);
  43 static int ixgbe_identify_hardware(ixgbe_t *);
  44 static int ixgbe_regs_map(ixgbe_t *);
  45 static void ixgbe_init_properties(ixgbe_t *);
  46 static int ixgbe_init_driver_settings(ixgbe_t *);
  47 static void ixgbe_init_locks(ixgbe_t *);
  48 static void ixgbe_destroy_locks(ixgbe_t *);
  49 static int ixgbe_init(ixgbe_t *);
 
 
 476                 ixgbe_error(ixgbe, "Failed to identify hardware");
 477                 goto attach_fail;
 478         }
 479 
 480         /*
 481          * Map device registers
 482          */
 483         if (ixgbe_regs_map(ixgbe) != IXGBE_SUCCESS) {
 484                 ixgbe_error(ixgbe, "Failed to map device registers");
 485                 goto attach_fail;
 486         }
 487         ixgbe->attach_progress |= ATTACH_PROGRESS_REGS_MAP;
 488 
 489         /*
 490          * Initialize driver parameters
 491          */
 492         ixgbe_init_properties(ixgbe);
 493         ixgbe->attach_progress |= ATTACH_PROGRESS_PROPS;
 494 
 495         /*
 496          * Allocate interrupts
 497          */
 498         if (ixgbe_alloc_intrs(ixgbe) != IXGBE_SUCCESS) {
 499                 ixgbe_error(ixgbe, "Failed to allocate interrupts");
 500                 goto attach_fail;
 501         }
 502         ixgbe->attach_progress |= ATTACH_PROGRESS_ALLOC_INTR;
 503 
 504         /*
 505          * Allocate rx/tx rings based on the ring numbers.
 506          * The actual numbers of rx/tx rings are decided by the number of
 507          * allocated interrupt vectors, so we should allocate the rings after
 508          * interrupts are allocated.
 509          */
 510         if (ixgbe_alloc_rings(ixgbe) != IXGBE_SUCCESS) {
 511                 ixgbe_error(ixgbe, "Failed to allocate rx and tx rings");
 512                 goto attach_fail;
 513         }
 514         ixgbe->attach_progress |= ATTACH_PROGRESS_ALLOC_RINGS;
 515 
 
 625             IXGBE_CYCLIC_PERIOD, DDI_IPL_0);
 626         if (ixgbe->periodic_id == 0) {
 627                 ixgbe_error(ixgbe, "Failed to add the link check timer");
 628                 goto attach_fail;
 629         }
 630         ixgbe->attach_progress |= ATTACH_PROGRESS_LINK_TIMER;
 631 
 632         /*
 633          * Now that mutex locks are initialized, and the chip is also
 634          * initialized, enable interrupts.
 635          */
 636         if (ixgbe_enable_intrs(ixgbe) != IXGBE_SUCCESS) {
 637                 ixgbe_error(ixgbe, "Failed to enable DDI interrupts");
 638                 goto attach_fail;
 639         }
 640         ixgbe->attach_progress |= ATTACH_PROGRESS_ENABLE_INTR;
 641 
 642         ixgbe_log(ixgbe, "%s", ixgbe_ident);
 643         atomic_or_32(&ixgbe->ixgbe_state, IXGBE_INITIALIZED);
 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 
 654         return (DDI_SUCCESS);
 655 
 656 attach_fail:
 657         ixgbe_unconfigure(devinfo, ixgbe);
 658         return (DDI_FAILURE);
 659 }
 660 
 661 /*
 662  * ixgbe_detach - Driver detach.
 663  *
 664  * The detach() function is the complement of the attach routine.
 665  * If cmd is set to DDI_DETACH, detach() is used to remove  the
 666  * state  associated  with  a  given  instance of a device node
 667  * prior to the removal of that instance from the system.
 668  *
 669  * The detach() function will be called once for each  instance
 670  * of the device for which there has been a successful attach()
 671  * once there are no longer  any  opens  on  the  device.
 672  *
 673  * Interrupts routine are disabled, All memory allocated by this
 
 762          */
 763         ixgbe_release_driver_control(hw);
 764 
 765         /*
 766          * Reset the chipset
 767          */
 768         (void) ixgbe_reset_hw(hw);
 769 
 770         /*
 771          * Reset PHY
 772          */
 773         (void) ixgbe_reset_phy(hw);
 774 
 775         return (DDI_SUCCESS);
 776 }
 777 
 778 static void
 779 ixgbe_unconfigure(dev_info_t *devinfo, ixgbe_t *ixgbe)
 780 {
 781         /*
 782          * Unregister interrupt callback handler
 783          */
 784         if (ixgbe->cb_hdl != NULL)
 785                 (void) ddi_cb_unregister(ixgbe->cb_hdl);
 786 
 787         /*
 788          * Disable interrupt
 789          */
 790         if (ixgbe->attach_progress & ATTACH_PROGRESS_ENABLE_INTR) {
 791                 (void) ixgbe_disable_intrs(ixgbe);
 792         }
 793 
 794         /*
 795          * remove the link check timer
 796          */
 797         if (ixgbe->attach_progress & ATTACH_PROGRESS_LINK_TIMER) {
 798                 if (ixgbe->periodic_id != NULL) {
 799                         ddi_periodic_delete(ixgbe->periodic_id);
 800                         ixgbe->periodic_id = NULL;
 801                 }
 802         }
 803 
 804         /*
 805          * Unregister MAC
 806          */
 807         if (ixgbe->attach_progress & ATTACH_PROGRESS_MAC) {
 
1231         ixgbe_tx_ring_t *tx_ring;
1232         int i;
1233 
1234         for (i = 0; i < ixgbe->num_rx_rings; i++) {
1235                 rx_ring = &ixgbe->rx_rings[i];
1236                 mutex_destroy(&rx_ring->rx_lock);
1237         }
1238 
1239         for (i = 0; i < ixgbe->num_tx_rings; i++) {
1240                 tx_ring = &ixgbe->tx_rings[i];
1241                 mutex_destroy(&tx_ring->tx_lock);
1242                 mutex_destroy(&tx_ring->recycle_lock);
1243                 mutex_destroy(&tx_ring->tcb_head_lock);
1244                 mutex_destroy(&tx_ring->tcb_tail_lock);
1245         }
1246 
1247         mutex_destroy(&ixgbe->gen_lock);
1248         mutex_destroy(&ixgbe->watchdog_lock);
1249 }
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 
1287 static int
1288 ixgbe_resume(dev_info_t *devinfo)
1289 {
1290         ixgbe_t *ixgbe;
1291         int i;
1292 
1293         ixgbe = (ixgbe_t *)ddi_get_driver_private(devinfo);
1294         if (ixgbe == NULL)
1295                 return (DDI_FAILURE);
1296 
1297         mutex_enter(&ixgbe->gen_lock);
1298 
1299         if (ixgbe->ixgbe_state & IXGBE_STARTED) {
1300                 if (ixgbe_start(ixgbe, B_FALSE) != IXGBE_SUCCESS) {
1301                         mutex_exit(&ixgbe->gen_lock);
1302                         return (DDI_FAILURE);
1303                 }
1304 
1305                 /*
1306                  * Enable and start the watchdog timer
 
1421          */
1422         if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
1423                 /*
1424                  * Some PCI-E parts fail the first check due to
1425                  * the link being in sleep state.  Call it again,
1426                  * if it fails a second time it's a real issue.
1427                  */
1428                 if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
1429                         ixgbe_error(ixgbe,
1430                             "Invalid NVM checksum. Please contact "
1431                             "the vendor to update the NVM.");
1432                         ixgbe_fm_ereport(ixgbe, DDI_FM_DEVICE_INVAL_STATE);
1433                         goto init_fail;
1434                 }
1435         }
1436 
1437         /*
1438          * Setup default flow control thresholds - enable/disable
1439          * & flow control type is controlled by ixgbe.conf
1440          */
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 
1460         hw->fc.pause_time = DEFAULT_FCPAUSE;
1461         hw->fc.send_xon = B_TRUE;
1462 
1463         /*
1464          * Initialize flow control
1465          */
1466         (void) ixgbe_start_hw(hw);
1467 
1468         /*
1469          * Initialize link settings
1470          */
1471         (void) ixgbe_driver_setup_link(ixgbe, B_FALSE);
1472 
1473         /*
1474          * Initialize the chipset hardware
1475          */
1476         if (ixgbe_chip_start(ixgbe) != IXGBE_SUCCESS) {
1477                 ixgbe_fm_ereport(ixgbe, DDI_FM_DEVICE_INVAL_STATE);
1478                 goto init_fail;
1479         }
1480 
1481         /*
1482          * Read identifying information and place in devinfo.
1483          */
1484         pbanum[0] = '\0';
1485         (void) ixgbe_read_pba_string(hw, pbanum, sizeof (pbanum));
1486         if (*pbanum != '\0') {
1487                 (void) ddi_prop_update_string(DDI_DEV_T_NONE, ixgbe->dip,
1488                     "printed-board-assembly", (char *)pbanum);
1489         }
1490 
1491         /*
1492          * Determine LED index.
1493          */
1494         ixgbe_led_init(ixgbe);
1495 
1496         if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
1497                 goto init_fail;
1498         }
1499 
1500         mutex_exit(&ixgbe->gen_lock);
1501         return (IXGBE_SUCCESS);
1502 
1503 init_fail:
1504         /*
1505          * Reset PHY
1506          */
1507         (void) ixgbe_reset_phy(hw);
1508 
1509         mutex_exit(&ixgbe->gen_lock);
1510         ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_LOST);
1511         return (IXGBE_FAILURE);
1512 }
1513 
1514 /*
1515  * ixgbe_chip_start - Initialize and start the chipset hardware.
 
2040                         goto cb_fail;
2041                 }
2042                 break;
2043         default:
2044                 IXGBE_DEBUGLOG_1(ixgbe, "DDI CB: action 0x%x NOT supported",
2045                     cbaction);
2046                 return (DDI_ENOTSUP);
2047         }
2048         return (DDI_SUCCESS);
2049 cb_fail:
2050         return (DDI_FAILURE);
2051 }
2052 
2053 /*
2054  * ixgbe_intr_adjust - Adjust interrupt to respond to IRM request.
2055  */
2056 static int
2057 ixgbe_intr_adjust(ixgbe_t *ixgbe, ddi_cb_action_t cbaction, int count)
2058 {
2059         int i, rc, actual;
2060         uint32_t started;
2061 
2062         if (!(ixgbe->ixgbe_state & IXGBE_INITIALIZED)) {
2063                 return (DDI_FAILURE);
2064         }
2065 
2066         if (cbaction == DDI_CB_INTR_REMOVE &&
2067             ixgbe->intr_cnt - count < ixgbe->intr_cnt_min)
2068                 return (DDI_FAILURE);
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 
2077         for (i = 0; i < ixgbe->num_rx_rings; i++)
2078                 mac_ring_intr_set(ixgbe->rx_rings[i].ring_handle, NULL);
2079         for (i = 0; i < ixgbe->num_tx_rings; i++)
2080                 mac_ring_intr_set(ixgbe->tx_rings[i].ring_handle, NULL);
2081 
2082         mutex_enter(&ixgbe->gen_lock);
2083         started = ixgbe->ixgbe_state & IXGBE_STARTED;
2084         ixgbe->ixgbe_state &= ~IXGBE_STARTED;
2085         ixgbe->ixgbe_state |= IXGBE_INTR_ADJUST;
2086         ixgbe->ixgbe_state |= IXGBE_SUSPENDED;
2087         mac_link_update(ixgbe->mac_hdl, LINK_STATE_UNKNOWN);
2088 
2089         if (started)
2090                 ixgbe_stop(ixgbe, B_FALSE);
2091         /*
2092          * Disable interrupts
2093          */
2094         if (ixgbe->attach_progress & ATTACH_PROGRESS_ENABLE_INTR) {
2095                 rc = ixgbe_disable_intrs(ixgbe);
2096                 ASSERT(rc == IXGBE_SUCCESS);
2097         }
2098         ixgbe->attach_progress &= ~ATTACH_PROGRESS_ENABLE_INTR;
2099 
2100         /*
2101          * Remove interrupt handlers
2102          */
2103         if (ixgbe->attach_progress & ATTACH_PROGRESS_ADD_INTR) {
2104                 ixgbe_rem_intr_handlers(ixgbe);
2105         }
2106         ixgbe->attach_progress &= ~ATTACH_PROGRESS_ADD_INTR;
2107 
2108         /*
2109          * Clear vect_map
 
2165         }
2166 
2167         /*
2168          * Add interrupt handlers
2169          */
2170         if (ixgbe_add_intr_handlers(ixgbe) != IXGBE_SUCCESS) {
2171                 ixgbe_error(ixgbe, "IRM CB: Failed to add interrupt handlers");
2172                 goto intr_adjust_fail;
2173         }
2174         ixgbe->attach_progress |= ATTACH_PROGRESS_ADD_INTR;
2175 
2176         /*
2177          * Now that mutex locks are initialized, and the chip is also
2178          * initialized, enable interrupts.
2179          */
2180         if (ixgbe_enable_intrs(ixgbe) != IXGBE_SUCCESS) {
2181                 ixgbe_error(ixgbe, "IRM CB: Failed to enable DDI interrupts");
2182                 goto intr_adjust_fail;
2183         }
2184         ixgbe->attach_progress |= ATTACH_PROGRESS_ENABLE_INTR;
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                 }
2190         ixgbe->ixgbe_state &= ~IXGBE_INTR_ADJUST;
2191         ixgbe->ixgbe_state &= ~IXGBE_SUSPENDED;
2192         ixgbe->ixgbe_state |= started;
2193         mutex_exit(&ixgbe->gen_lock);
2194 
2195         for (i = 0; i < ixgbe->num_rx_rings; i++) {
2196                 mac_ring_intr_set(ixgbe->rx_rings[i].ring_handle,
2197                     ixgbe->htable[ixgbe->rx_rings[i].intr_vector]);
2198         }
2199         for (i = 0; i < ixgbe->num_tx_rings; i++) {
2200                 mac_ring_intr_set(ixgbe->tx_rings[i].ring_handle,
2201                     ixgbe->htable[ixgbe->tx_rings[i].intr_vector]);
2202         }
2203 
2204         /* Wakeup all Tx rings */
2205         for (i = 0; i < ixgbe->num_tx_rings; i++) {
2206                 mac_tx_ring_update(ixgbe->mac_hdl,
2207                     ixgbe->tx_rings[i].ring_handle);
2208         }
2209 
2210         IXGBE_DEBUGLOG_3(ixgbe,
2211             "IRM CB: interrupts new value: 0x%x(0x%x:0x%x).",
2212             ixgbe->intr_cnt, ixgbe->intr_cnt_min, ixgbe->intr_cnt_max);
 
3731 
3732 /*
3733  * ixgbe_driver_link_check - Link status processing.
3734  *
3735  * This function can be called in both kernel context and interrupt context
3736  */
3737 static void
3738 ixgbe_driver_link_check(ixgbe_t *ixgbe)
3739 {
3740         struct ixgbe_hw *hw = &ixgbe->hw;
3741         ixgbe_link_speed speed = IXGBE_LINK_SPEED_UNKNOWN;
3742         boolean_t link_up = B_FALSE;
3743         boolean_t link_changed = B_FALSE;
3744 
3745         ASSERT(mutex_owned(&ixgbe->gen_lock));
3746 
3747         (void) ixgbe_check_link(hw, &speed, &link_up, B_FALSE);
3748         if (link_up) {
3749                 ixgbe->link_check_complete = B_TRUE;
3750 
3751                 /*
3752                  * The Link is up, check whether it was marked as down earlier
3753                  */
3754                 if (ixgbe->link_state != LINK_STATE_UP) {
3755 
3756                         /* Link is up, enable flow control settings */
3757                         (void) ixgbe_fc_enable(hw);
3758 
3759                         switch (speed) {
3760                         case IXGBE_LINK_SPEED_10GB_FULL:
3761                                 ixgbe->link_speed = SPEED_10GB;
3762                                 break;
3763                         case IXGBE_LINK_SPEED_5GB_FULL:
3764                                 ixgbe->link_speed = SPEED_5GB;
3765                                 break;
3766                         case IXGBE_LINK_SPEED_2_5GB_FULL:
3767                                 ixgbe->link_speed = SPEED_2_5GB;
3768                                 break;
3769                         case IXGBE_LINK_SPEED_1GB_FULL:
3770                                 ixgbe->link_speed = SPEED_1GB;
3771                                 break;
3772                         case IXGBE_LINK_SPEED_100_FULL:
3773                                 ixgbe->link_speed = SPEED_100;
3774                         }
3775                         ixgbe->link_duplex = LINK_DUPLEX_FULL;
3776                         ixgbe->link_state = LINK_STATE_UP;
3777                         link_changed = B_TRUE;
3778                 }
 
 |