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 }
|