# HG changeset patch # User chenlu chen - Sun Microsystems - Beijing China # Date 1280878736 -28800 # Node ID 22e6d3edaab5b47ef334de59ec85a55d1df1ba02 # Parent f651e899cbc96d1b07a3c68b2227b5df8bf7c464 6964175 integration of Intel ixgbe shared code 3.5.13 6947876 oplin driver detect false hang during specweb tests on X4440 6940695 Changes to relaxed ordering in new shared code can impact performance 6969304 The per-ring statistics mapping register is not set correctly in some cases diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/pkg/manifests/driver-network-ixgbe.mf --- a/usr/src/pkg/manifests/driver-network-ixgbe.mf Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/pkg/manifests/driver-network-ixgbe.mf Wed Aug 04 07:38:56 2010 +0800 @@ -52,14 +52,14 @@ alias=pciex8086,10f7 \ alias=pciex8086,10f8 \ alias=pciex8086,10f9 \ - alias=pciex8086,10fa \ alias=pciex8086,10fb \ alias=pciex8086,10fc \ alias=pciex8086,1507 \ alias=pciex8086,1508 \ alias=pciex8086,150b \ alias=pciex8086,1514 \ - alias=pciex8086,1517 + alias=pciex8086,1517 \ + alias=pciex8086,151c file path=kernel/drv/$(ARCH64)/ixgbe group=sys $(i386_ONLY)file path=kernel/drv/ixgbe group=sys file path=kernel/drv/ixgbe.conf group=sys \ diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_82598.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_82598.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_82598.c Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -22,11 +21,14 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. */ -/* IntelVersion: 1.162 sol_ixgbe_shared_339b */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* IntelVersion: 1.167 scm_061610_003709 */ #include "ixgbe_type.h" #include "ixgbe_api.h" @@ -192,6 +194,7 @@ /* Link */ mac->ops.check_link = &ixgbe_check_mac_link_82598; mac->ops.setup_link = &ixgbe_setup_mac_link_82598; + mac->ops.flap_tx_laser = NULL; mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82598; @@ -441,20 +444,28 @@ DEBUGFUNC("ixgbe_fc_enable_82598"); /* - * On 82598 backplane having FC on causes resets while doing - * KX, so turn off here. + * On 82598 having Rx FC on causes resets while doing 1G + * so if it's on turn it off once we know link_speed. For + * more details see 82598 Specification update. */ hw->mac.ops.check_link(hw, &link_speed, &link_up, false); - if (link_up && - link_speed == IXGBE_LINK_SPEED_1GB_FULL && - hw->mac.ops.get_media_type(hw) == ixgbe_media_type_backplane) { - hw->fc.disable_fc_autoneg = true; - hw->fc.requested_mode = ixgbe_fc_none; + if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) { + switch (hw->fc.requested_mode) { + case ixgbe_fc_full: + hw->fc.requested_mode = ixgbe_fc_tx_pause; + break; + case ixgbe_fc_rx_pause: + hw->fc.requested_mode = ixgbe_fc_none; + break; + default: + /* no change */ + break; + } } /* Negotiate the fc mode to use */ ret_val = ixgbe_fc_autoneg(hw); - if (ret_val) + if (ret_val == IXGBE_ERR_FLOW_CONTROL) goto out; /* Disable any previous flow control settings */ diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_82599.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_82599.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_82599.c Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -22,11 +21,14 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. */ -/* IntelVersion: 1.202 sol_ixgbe_shared_339b */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* IntelVersion: 1.217 scm_061610_003709 */ #include "ixgbe_type.h" #include "ixgbe_api.h" @@ -37,6 +39,9 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *autoneg); enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw); +void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, @@ -73,7 +78,15 @@ if (hw->phy.multispeed_fiber) { /* Set up dual speed SFP+ support */ mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; + mac->ops.disable_tx_laser = + &ixgbe_disable_tx_laser_multispeed_fiber; + mac->ops.enable_tx_laser = + &ixgbe_enable_tx_laser_multispeed_fiber; + mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber; } else { + mac->ops.disable_tx_laser = NULL; + mac->ops.enable_tx_laser = NULL; + mac->ops.flap_tx_laser = NULL; if ((ixgbe_get_media_type(hw) == ixgbe_media_type_backplane) && (hw->phy.smart_speed == ixgbe_smart_speed_auto || hw->phy.smart_speed == ixgbe_smart_speed_on)) @@ -210,6 +223,7 @@ /* MAC */ mac->ops.reset_hw = &ixgbe_reset_hw_82599; + mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_82599; mac->ops.get_media_type = &ixgbe_get_media_type_82599; mac->ops.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599; @@ -222,6 +236,7 @@ mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_generic; mac->ops.get_device_caps = &ixgbe_get_device_caps_82599; mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic; + mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic; /* RAR, Multicast, VLAN */ mac->ops.set_vmdq = &ixgbe_set_vmdq_generic; @@ -265,6 +280,14 @@ DEBUGFUNC("ixgbe_get_link_capabilities_82599"); + /* Check if 1G SFP module. */ + if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) { + *speed = IXGBE_LINK_SPEED_1GB_FULL; + *negotiation = true; + goto out; + } + /* * Determine link capabilities based on the stored value of AUTOC, * which represents EEPROM defaults. If AUTOC value has not @@ -376,7 +399,7 @@ case IXGBE_DEV_ID_82599_CX4: media_type = ixgbe_media_type_cx4; break; - case IXGBE_DEV_ID_82599_T: + case IXGBE_DEV_ID_82599_T3_LOM: media_type = ixgbe_media_type_copper; break; default: @@ -438,6 +461,74 @@ } /* + * ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser + * @hw: pointer to hardware structure + * + * The base drivers may require better control over SFP+ module + * PHY states. This includes selectively shutting down the Tx + * laser on the PHY, effectively halting physical link. + */ +void +ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +{ + u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + + /* + * Disable tx laser; allow 100us to go dark per spec + */ + esdp_reg |= IXGBE_ESDP_SDP3; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + usec_delay(100); +} + +/* + * ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser + * @hw: pointer to hardware structure + * + * The base drivers may require better control over SFP+ module + * PHY states. This includes selectively turning on the Tx + * laser on the PHY, effectively starting physical link. + */ +void +ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +{ + u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + + /* + * Enable tx laser; allow 100ms to light up + */ + esdp_reg &= ~IXGBE_ESDP_SDP3; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + msec_delay(100); +} + +/* + * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser + * @hw: pointer to hardware structure + * + * When the driver changes the link speeds that it can support, + * it sets autotry_restart to true to indicate that we need to + * initiate a new autotry session with the link partner. To do + * so, we set the speed then disable and re-enable the tx laser, to + * alert the link partner that it also needs to restart autotry on its + * end. This is consistent with true clause 37 autoneg, which also + * involves a loss of signal. + */ +void +ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +{ + DEBUGFUNC("ixgbe_flap_tx_laser_multispeed_fiber"); + + if (hw->mac.autotry_restart) { + ixgbe_disable_tx_laser_multispeed_fiber(hw); + ixgbe_enable_tx_laser_multispeed_fiber(hw); + hw->mac.autotry_restart = false; + } +} + +/* * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed @@ -469,16 +560,6 @@ speed &= link_speed; /* - * When the driver changes the link speeds that it can support, - * it sets autotry_restart to true to indicate that we need to - * initiate a new autotry session with the link partner. To do - * so, we set the speed then disable and re-enable the tx laser, to - * alert the link partner that it also needs to restart autotry on its - * end. This is consistent with true clause 37 autoneg, which also - * involves a loss of signal. - */ - - /* * Try each speed one by one, highest priority first. We do this in * software because 10gb fiber doesn't support speed autonegotiation. */ @@ -497,6 +578,7 @@ /* Set the module link speed */ esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5); IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); /* Allow module to change analog characteristics (1G->10G) */ msec_delay(40); @@ -508,19 +590,7 @@ return (status); /* Flap the tx laser if it has not already been done */ - if (hw->mac.autotry_restart) { - /* Disable tx laser; allow 100us to go dark per spec */ - esdp_reg |= IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - usec_delay(100); - - /* Enable tx laser; allow 2ms to light up per spec */ - esdp_reg &= ~IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - msec_delay(2); - - hw->mac.autotry_restart = false; - } + ixgbe_flap_tx_laser(hw); /* * Wait for the controller to acquire link. Per IEEE 802.3ap, @@ -559,6 +629,7 @@ esdp_reg &= ~IXGBE_ESDP_SDP5; esdp_reg |= IXGBE_ESDP_SDP5_DIR; IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); /* Allow module to change analog characteristics (10G->1G) */ msec_delay(40); @@ -570,19 +641,7 @@ return (status); /* Flap the tx laser if it has not already been done */ - if (hw->mac.autotry_restart) { - /* Disable tx laser; allow 100us to go dark per spec */ - esdp_reg |= IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - usec_delay(100); - - /* Enable tx laser; allow 2ms to light up per spec */ - esdp_reg &= ~IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - msec_delay(2); - - hw->mac.autotry_restart = false; - } + ixgbe_flap_tx_laser(hw); /* Wait for the link partner to also set speed */ msec_delay(100); @@ -632,7 +691,7 @@ ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { s32 status = IXGBE_SUCCESS; - ixgbe_link_speed link_speed; + ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN; s32 i, j; bool link_up = false; u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); @@ -725,6 +784,9 @@ autoneg_wait_to_complete); out: + if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL)) + DEBUGOUT("Smartspeed has downgraded the link speed " + "from the maximum advertised\n"); return (status); } @@ -881,7 +943,7 @@ ixgbe_reset_hw_82599(struct ixgbe_hw *hw) { s32 status = IXGBE_SUCCESS; - u32 ctrl, ctrl_ext; + u32 ctrl; u32 i; u32 autoc; u32 autoc2; @@ -940,11 +1002,6 @@ DEBUGOUT("Reset polling failed to complete.\n"); } - /* Clear PF Reset Done bit so PF/VF Mail Ops can work */ - ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); - ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; - IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); - /* * Double resets are required for recovery from certain error * conditions. Between resets, it is necessary to stall to allow time @@ -1225,6 +1282,9 @@ /* Send interrupt when 64 filters are left */ fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; + /* Initialize the drop queue to Rx queue 127 */ + fdirctrl |= (127 << IXGBE_FDIRCTRL_DROP_Q_SHIFT); + switch (pballoc) { case IXGBE_FDIR_PBALLOC_64K: /* 2k - 1 perfect filters */ @@ -1921,6 +1981,8 @@ * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter * @hw: pointer to hardware structure * @input: input bitstream + * @input_masks: masks for the input bitstream + * @soft_id: software index for the filters * @queue: queue index to direct traffic to * * Note that the caller to this function must lock before calling, since the @@ -1928,15 +1990,17 @@ */ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, - struct ixgbe_atr_input *input, u16 soft_id, u8 queue) + struct ixgbe_atr_input *input, struct ixgbe_atr_input_masks *input_masks, + u16 soft_id, u8 queue) { u32 fdircmd = 0; u32 fdirhash; - u32 src_ipv4, dst_ipv4; + u32 src_ipv4 = 0, dst_ipv4 = 0; u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4; u16 src_port, dst_port, vlan_id, flex_bytes; u16 bucket_hash; u8 l4type; + u8 fdirm = 0; DEBUGFUNC("ixgbe_fdir_add_perfect_filter_82599"); @@ -2004,6 +2068,77 @@ IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port | (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); + /* + * Program the relevant mask registers. If src/dst_port or src/dst_addr + * are zero, then assume a full mask for that field. Also assume that + * a VLAN of 0 is unspecified, so mask that out as well. L4type + * cannot be masked out in this implementation. + * + * This also assumes IPv4 only. IPv6 masking isn't supported at this + * point in time. + */ + if (src_ipv4 == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, 0xffffffff); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask); + + if (dst_ipv4 == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, 0xffffffff); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask); + + switch (l4type & IXGBE_ATR_L4TYPE_MASK) { + case IXGBE_ATR_L4TYPE_TCP: + if (src_port == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xffff); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, + input_masks->src_port_mask); + + if (dst_port == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | + 0xffff0000)); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | + (input_masks->dst_port_mask << 16))); + break; + case IXGBE_ATR_L4TYPE_UDP: + if (src_port == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xffff); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, + input_masks->src_port_mask); + + if (dst_port == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | + 0xffff0000)); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | + (input_masks->src_port_mask << 16))); + break; + default: + /* this already would have failed above */ + break; + } + + /* Program the last mask register, FDIRM */ + if (input_masks->vlan_id_mask || !vlan_id) + /* Mask both VLAN and VLANP - bits 0 and 1 */ + fdirm |= (IXGBE_FDIRM_VLANID | IXGBE_FDIRM_VLANP); + + if (input_masks->data_mask || !flex_bytes) + /* Flex bytes need masking, so mask the whole thing - bit 4 */ + fdirm |= IXGBE_FDIRM_FLEX; + + /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ + fdirm |= (IXGBE_FDIRM_POOL | IXGBE_FDIRM_DIPv6); + + IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm); + fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW; fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE; fdircmd |= IXGBE_FDIRCMD_LAST; @@ -2162,6 +2297,7 @@ u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; u16 ext_ability = 0; u8 comp_codes_10g = 0; + u8 comp_codes_1g = 0; DEBUGFUNC("ixgbe_get_support_physical_layer_82599"); @@ -2231,20 +2367,28 @@ goto out; switch (hw->phy.type) { - case ixgbe_phy_tw_tyco: - case ixgbe_phy_tw_unknown: + case ixgbe_phy_sfp_passive_tyco: + case ixgbe_phy_sfp_passive_unknown: physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; break; + case ixgbe_phy_sfp_ftl_active: + case ixgbe_phy_sfp_active_unknown: + physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA; + break; case ixgbe_phy_sfp_avago: case ixgbe_phy_sfp_ftl: case ixgbe_phy_sfp_intel: case ixgbe_phy_sfp_unknown: hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g); + hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g); if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; + else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T; break; default: break; diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_api.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_api.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_api.c Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -22,11 +21,14 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. */ -/* IntelVersion: 1.134 sol_ixgbe_shared_339b */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* IntelVersion: 1.140 scm_061610_003709 */ #include "ixgbe_api.h" #include "ixgbe_common.h" @@ -111,7 +113,7 @@ case IXGBE_DEV_ID_82599_SFP: case IXGBE_DEV_ID_82599_SFP_EM: case IXGBE_DEV_ID_82599_CX4: - case IXGBE_DEV_ID_82599_T: + case IXGBE_DEV_ID_82599_T3_LOM: hw->mac.type = ixgbe_mac_82599EB; break; default: @@ -291,6 +293,20 @@ } /* + * ixgbe_get_fcoe_boot_status - Get FCOE boot status from EEPROM + * @hw: pointer to hardware structure + * @bs: the fcoe boot status + * + * This function will read the FCOE boot status from the iSCSI FCOE block + */ +s32 +ixgbe_get_fcoe_boot_status(struct ixgbe_hw *hw, u16 *bs) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_fcoe_boot_status, + (hw, bs), IXGBE_NOT_IMPLEMENTED); +} + +/* * ixgbe_get_bus_info - Set PCI bus info * @hw: pointer to hardware structure * @@ -511,6 +527,47 @@ } /* + * ixgbe_disable_tx_laser - Disable Tx laser + * @hw: pointer to hardware structure + * + * If the driver needs to disable the laser on SFI optics. + */ +void +ixgbe_disable_tx_laser(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.disable_tx_laser) + hw->mac.ops.disable_tx_laser(hw); +} + +/* + * ixgbe_enable_tx_laser - Enable Tx laser + * @hw: pointer to hardware structure + * + * If the driver needs to enable the laser on SFI optics. + */ +void +ixgbe_enable_tx_laser(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.enable_tx_laser) + hw->mac.ops.enable_tx_laser(hw); +} + +/* + * ixgbe_flap_tx_laser - flap Tx laser to start autotry process + * @hw: pointer to hardware structure + * + * When the driver changes the link speeds that it can support then + * flap the tx laser to alert the link partner to start autotry + * process on its end. + */ +void +ixgbe_flap_tx_laser(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.flap_tx_laser) + hw->mac.ops.flap_tx_laser(hw); +} + +/* * ixgbe_setup_link - Set link speed * @hw: pointer to hardware structure * @speed: new link speed diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_api.h --- a/usr/src/uts/common/io/ixgbe/ixgbe_api.h Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_api.h Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -22,11 +21,14 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. */ -/* IntelVersion: 1.78 sol_ixgbe_shared_339b */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* IntelVersion: 1.82 scm_061610_003709 */ #ifndef _IXGBE_API_H #define _IXGBE_API_H @@ -61,6 +63,9 @@ ixgbe_link_speed *speed, bool *link_up); s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); +void ixgbe_disable_tx_laser(struct ixgbe_hw *hw); +void ixgbe_enable_tx_laser(struct ixgbe_hw *hw); +void ixgbe_flap_tx_laser(struct ixgbe_hw *hw); s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, @@ -113,7 +118,8 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, struct ixgbe_atr_input *input, u8 queue); s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, - struct ixgbe_atr_input *input, u16 soft_id, u8 queue); + struct ixgbe_atr_input *input, struct ixgbe_atr_input_masks *masks, + u16 soft_id, u8 queue); u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key); s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan_id); s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr); @@ -152,5 +158,6 @@ void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u16 mask); s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix, u16 *wwpn_prefix); +s32 ixgbe_get_fcoe_boot_status(struct ixgbe_hw *hw, u16 *bs); #endif /* _IXGBE_API_H */ diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_common.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_common.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_common.c Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -21,13 +20,17 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. */ -/* IntelVersion: 1.227 sol_ixgbe_shared_339b */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* IntelVersion: 1.238 scm_061610_003709 */ #include "ixgbe_common.h" +#include "ixgbe_phy.h" #include "ixgbe_api.h" static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); @@ -45,6 +48,12 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, u16 *san_mac_offset); +static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw); +static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw); +static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw); +static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); +static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, + u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan); /* @@ -278,12 +287,15 @@ (void) IXGBE_READ_REG(hw, IXGBE_BPTC); for (i = 0; i < 16; i++) { (void) IXGBE_READ_REG(hw, IXGBE_QPRC(i)); - (void) IXGBE_READ_REG(hw, IXGBE_QBRC(i)); (void) IXGBE_READ_REG(hw, IXGBE_QPTC(i)); if (hw->mac.type >= ixgbe_mac_82599EB) { + (void) IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); + (void) IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); (void) IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); (void) IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); + (void) IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); } else { + (void) IXGBE_READ_REG(hw, IXGBE_QBRC(i)); (void) IXGBE_READ_REG(hw, IXGBE_QBTC(i)); } } @@ -1639,7 +1651,6 @@ u32 vector; u32 vector_bit; u32 vector_reg; - u32 mta_reg; DEBUGFUNC("ixgbe_set_mta"); @@ -1659,9 +1670,7 @@ */ vector_reg = (vector >> 5) & 0x7F; vector_bit = vector & 0x1F; - mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg)); - mta_reg |= (1 << vector_bit); - IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg); + hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit); } /* @@ -1692,18 +1701,21 @@ hw->addr_ctrl.num_mc_addrs = mc_addr_count; hw->addr_ctrl.mta_in_use = 0; - /* Clear the MTA */ + /* Clear mta_shadow */ DEBUGOUT(" Clearing MTA\n"); - for (i = 0; i < hw->mac.mcft_size; i++) - IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); - - /* Add the new addresses */ + (void) memset(&hw->mac.mta_shadow, 0, sizeof (hw->mac.mta_shadow)); + + /* Update mta_shadow */ for (i = 0; i < mc_addr_count; i++) { DEBUGOUT(" Adding the multicast addresses:\n"); ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq)); } /* Enable mta */ + for (i = 0; i < hw->mac.mcft_size; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i, + hw->mac.mta_shadow[i]); + if (hw->addr_ctrl.mta_in_use > 0) IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); @@ -1770,7 +1782,7 @@ /* Negotiate the fc mode to use */ ret_val = ixgbe_fc_autoneg(hw); - if (ret_val) + if (ret_val == IXGBE_ERR_FLOW_CONTROL) goto out; /* Disable any previous flow control settings */ @@ -1889,14 +1901,15 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) { - s32 ret_val = IXGBE_SUCCESS; + s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; ixgbe_link_speed speed; - u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; - u32 links2, anlp1_reg, autoc_reg, links; bool link_up; DEBUGFUNC("ixgbe_fc_autoneg"); + if (hw->fc.disable_fc_autoneg) + goto out; + /* * AN should have completed when the cable was plugged in. * Look for reasons to bail out. Bail out if: @@ -1907,156 +1920,206 @@ * So use link_up_wait_to_complete=false. */ hw->mac.ops.check_link(hw, &speed, &link_up, false); - - if (hw->fc.disable_fc_autoneg || (!link_up)) { - hw->fc.fc_was_autonegged = false; - hw->fc.current_mode = hw->fc.requested_mode; + if (!link_up) { + ret_val = IXGBE_ERR_FLOW_CONTROL; goto out; } - /* - * On backplane, bail out if - * - backplane autoneg was not completed, or if - * - we are 82599 and link partner is not AN enabled - */ - if (hw->phy.media_type == ixgbe_media_type_backplane) { - links = IXGBE_READ_REG(hw, IXGBE_LINKS); - if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { - hw->fc.fc_was_autonegged = false; - hw->fc.current_mode = hw->fc.requested_mode; - goto out; - } - - if (hw->mac.type == ixgbe_mac_82599EB) { - links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); - if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { - hw->fc.fc_was_autonegged = false; - hw->fc.current_mode = hw->fc.requested_mode; - goto out; - } - } + switch (hw->phy.media_type) { + /* Autoneg flow control on fiber adapters */ + case ixgbe_media_type_fiber: + if (speed == IXGBE_LINK_SPEED_1GB_FULL) + ret_val = ixgbe_fc_autoneg_fiber(hw); + break; + + /* Autoneg flow control on backplane adapters */ + case ixgbe_media_type_backplane: + ret_val = ixgbe_fc_autoneg_backplane(hw); + break; + + /* Autoneg flow control on copper adapters */ + case ixgbe_media_type_copper: + if (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS) + ret_val = ixgbe_fc_autoneg_copper(hw); + break; + + default: + break; } +out: + if (ret_val == IXGBE_SUCCESS) { + hw->fc.fc_was_autonegged = true; + } else { + hw->fc.fc_was_autonegged = false; + hw->fc.current_mode = hw->fc.requested_mode; + } + return (ret_val); +} + +/* + * ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber + * @hw: pointer to hardware structure + * @speed: + * @link_up + * + * Enable flow control according on 1 gig fiber. + */ +static s32 +ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw) +{ + u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; + s32 ret_val; + /* * On multispeed fiber at 1g, bail out if * - link is up but AN did not complete, or if * - link is up and AN completed but timed out */ - if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) { - linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); - if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || - ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { + + linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); + if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || + ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { + ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; + } + + pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); + + ret_val = ixgbe_negotiate_fc(hw, pcs_anadv_reg, + pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE, + IXGBE_PCS1GANA_ASM_PAUSE, + IXGBE_PCS1GANA_SYM_PAUSE, + IXGBE_PCS1GANA_ASM_PAUSE); + +out: + return (ret_val); +} + +/* + * ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + */ +static s32 +ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw) +{ + u32 links2, anlp1_reg, autoc_reg, links; + s32 ret_val; + + /* + * On backplane, bail out if + * - backplane autoneg was not completed, or if + * - we are 82599 and link partner is not AN enabled + */ + links = IXGBE_READ_REG(hw, IXGBE_LINKS); + if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { + hw->fc.fc_was_autonegged = false; + hw->fc.current_mode = hw->fc.requested_mode; + ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; + } + + if (hw->mac.type == ixgbe_mac_82599EB) { + links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); + if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { hw->fc.fc_was_autonegged = false; hw->fc.current_mode = hw->fc.requested_mode; + ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; goto out; } } - /* - * Bail out on - * - copper or CX4 adapters - * - fiber adapters running at 10gig - */ - if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->phy.media_type == ixgbe_media_type_cx4) || - ((hw->phy.media_type == ixgbe_media_type_fiber) && - (speed == IXGBE_LINK_SPEED_10GB_FULL))) { - hw->fc.fc_was_autonegged = false; - hw->fc.current_mode = hw->fc.requested_mode; - goto out; - } - - /* - * Read the AN advertisement and LP ability registers and resolve + * Read the 10g AN autoc and LP ability registers and resolve * local flow control settings accordingly */ - if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && - (hw->phy.media_type != ixgbe_media_type_backplane)) { - pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); - pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); - if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) { - /* - * Now we need to check if the user selected Rx ONLY - * of pause frames. In this case, we had to advertise - * FULL flow control because we could not advertise RX - * ONLY. Hence, we must now check to see if we need to - * turn OFF the TRANSMISSION of PAUSE frames. - */ - if (hw->fc.requested_mode == ixgbe_fc_full) { - hw->fc.current_mode = ixgbe_fc_full; - DEBUGOUT("Flow Control = FULL.\n"); - } else { - hw->fc.current_mode = ixgbe_fc_rx_pause; - DEBUGOUT("Flow Control=RX PAUSE frames only\n"); - } - } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_tx_pause; - DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); - } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && - !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_rx_pause; - DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); - } else { - hw->fc.current_mode = ixgbe_fc_none; - DEBUGOUT("Flow Control = NONE.\n"); - } - } - - if (hw->phy.media_type == ixgbe_media_type_backplane) { - /* - * Read the 10g AN autoc and LP ability registers and resolve - * local flow control settings accordingly - */ - autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); - anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); - - if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && - (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE)) { - /* - * Now we need to check if the user selected Rx ONLY - * of pause frames. In this case, we had to advertise - * FULL flow control because we could not advertise RX - * ONLY. Hence, we must now check to see if we need to - * turn OFF the TRANSMISSION of PAUSE frames. - */ - if (hw->fc.requested_mode == ixgbe_fc_full) { - hw->fc.current_mode = ixgbe_fc_full; - DEBUGOUT("Flow Control = FULL.\n"); - } else { - hw->fc.current_mode = ixgbe_fc_rx_pause; - DEBUGOUT("Flow Control=RX PAUSE frames only\n"); - } - } else if (!(autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && - (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) && - (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) && - (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_tx_pause; - DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); - } else if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && - (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) && - !(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) && - (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_rx_pause; - DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); - } else { - hw->fc.current_mode = ixgbe_fc_none; - DEBUGOUT("Flow Control = NONE.\n"); - } - } - /* Record that current_mode is the result of a successful autoneg */ - hw->fc.fc_was_autonegged = true; + autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); + + ret_val = ixgbe_negotiate_fc(hw, autoc_reg, + anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE, + IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE); out: return (ret_val); } /* + * ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + */ +static s32 +ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw) +{ + u16 technology_ability_reg = 0; + u16 lp_technology_ability_reg = 0; + + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &technology_ability_reg); + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_LP, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &lp_technology_ability_reg); + + return (ixgbe_negotiate_fc(hw, (u32)technology_ability_reg, + (u32)lp_technology_ability_reg, + IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE, + IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE)); +} + +/* + * ixgbe_negotiate_fc - Negotiate flow control + * @hw: pointer to hardware structure + * @adv_reg: flow control advertised settings + * @lp_reg: link partner's flow control settings + * @adv_sym: symmetric pause bit in advertisement + * @adv_asm: asymmetric pause bit in advertisement + * @lp_sym: symmetric pause bit in link partner advertisement + * @lp_asm: asymmetric pause bit in link partner advertisement + * + * Find the intersection between advertised settings and link partner's + * advertised settings + */ +static s32 +ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, + u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) +{ + if ((!(adv_reg)) || (!(lp_reg))) + return (IXGBE_ERR_FC_NOT_NEGOTIATED); + + if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { + /* + * Now we need to check if the user selected Rx ONLY + * of pause frames. In this case, we had to advertise + * FULL flow control because we could not advertise RX + * ONLY. Hence, we must now check to see if we need to + * turn OFF the TRANSMISSION of PAUSE frames. + */ + if (hw->fc.requested_mode == ixgbe_fc_full) { + hw->fc.current_mode = ixgbe_fc_full; + DEBUGOUT("Flow Control = FULL.\n"); + } else { + hw->fc.current_mode = ixgbe_fc_rx_pause; + DEBUGOUT("Flow Control=RX PAUSE frames only\n"); + } + } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) && + (lp_reg & lp_sym) && (lp_reg & lp_asm)) { + hw->fc.current_mode = ixgbe_fc_tx_pause; + DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); + } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) && + !(lp_reg & lp_sym) && (lp_reg & lp_asm)) { + hw->fc.current_mode = ixgbe_fc_rx_pause; + DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); + } else { + hw->fc.current_mode = ixgbe_fc_none; + DEBUGOUT("Flow Control = NONE.\n"); + } + return (IXGBE_SUCCESS); +} + +/* * ixgbe_setup_fc - Set up flow control * @hw: pointer to hardware structure * @@ -2066,7 +2129,8 @@ ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) { s32 ret_val = IXGBE_SUCCESS; - u32 reg; + u32 reg = 0, reg_bp = 0; + u16 reg_cu = 0; DEBUGFUNC("ixgbe_setup_fc"); @@ -2106,11 +2170,25 @@ hw->fc.requested_mode = ixgbe_fc_full; /* - * Set up the 1G flow control advertisement registers so the HW will be - * able to do fc autoneg once the cable is plugged in. If we end up - * using 10g instead, this is harmless. + * Set up the 1G and 10G flow control advertisement registers so the + * HW will be able to do fc autoneg once the cable is plugged in. If + * we link at 10G, the 1G advertisement is harmless and vice versa. */ - reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: + case ixgbe_media_type_backplane: + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC); + break; + + case ixgbe_media_type_copper: + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®_cu); + break; + + default: + ; + } /* * The possible values of fc.requested_mode are: @@ -2126,6 +2204,11 @@ case ixgbe_fc_none: /* Flow control completely disabled by software override. */ reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + if (hw->phy.media_type == ixgbe_media_type_backplane) + reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE | + IXGBE_AUTOC_ASM_PAUSE); + else if (hw->phy.media_type == ixgbe_media_type_copper) + reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); break; case ixgbe_fc_rx_pause: /* @@ -2137,6 +2220,11 @@ * disable the adapter's ability to send PAUSE frames. */ reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + if (hw->phy.media_type == ixgbe_media_type_backplane) + reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | + IXGBE_AUTOC_ASM_PAUSE); + else if (hw->phy.media_type == ixgbe_media_type_copper) + reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); break; case ixgbe_fc_tx_pause: /* @@ -2145,10 +2233,22 @@ */ reg |= (IXGBE_PCS1GANA_ASM_PAUSE); reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); + if (hw->phy.media_type == ixgbe_media_type_backplane) { + reg_bp |= (IXGBE_AUTOC_ASM_PAUSE); + reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE); + } else if (hw->phy.media_type == ixgbe_media_type_copper) { + reg_cu |= (IXGBE_TAF_ASM_PAUSE); + reg_cu &= ~(IXGBE_TAF_SYM_PAUSE); + } break; case ixgbe_fc_full: /* Flow control (both Rx and Tx) is enabled by SW override. */ reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + if (hw->phy.media_type == ixgbe_media_type_backplane) + reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | + IXGBE_AUTOC_ASM_PAUSE); + else if (hw->phy.media_type == ixgbe_media_type_copper) + reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); break; default: DEBUGOUT("Flow control param set incorrectly\n"); @@ -2167,61 +2267,18 @@ DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg); /* - * Set up the 10G flow control advertisement registers so the HW - * can do fc autoneg once the cable is plugged in. If we end up - * using 1g instead, this is harmless. - */ - reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); - - /* - * The possible values of fc.requested_mode are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames, - * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but - * we do not support receiving pause frames). - * 3: Both Rx and Tx flow control (symmetric) are enabled. - * other: Invalid. - */ - switch (hw->fc.requested_mode) { - case ixgbe_fc_none: - /* Flow control completely disabled by software override. */ - reg &= ~(IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); - break; - case ixgbe_fc_rx_pause: - /* - * Rx Flow control is enabled and Tx Flow control is - * disabled by software override. Since there really - * isn't a way to advertise that we are capable of RX - * Pause ONLY, we will advertise that we support both - * symmetric and asymmetric Rx PAUSE. Later, we will - * disable the adapter's ability to send PAUSE frames. - */ - reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); - break; - case ixgbe_fc_tx_pause: - /* - * Tx Flow control is enabled, and Rx Flow control is - * disabled by software override. - */ - reg |= (IXGBE_AUTOC_ASM_PAUSE); - reg &= ~(IXGBE_AUTOC_SYM_PAUSE); - break; - case ixgbe_fc_full: - /* Flow control (both Rx and Tx) is enabled by SW override. */ - reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); - break; - default: - DEBUGOUT("Flow control param set incorrectly\n"); - ret_val = IXGBE_ERR_CONFIG; - goto out; - } - /* * AUTOC restart handles negotiation of 1G and 10G. There is * no need to set the PCS1GCTL register. */ - reg |= IXGBE_AUTOC_AN_RESTART; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg); + if (hw->phy.media_type == ixgbe_media_type_backplane) { + reg_bp |= IXGBE_AUTOC_AN_RESTART; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); + } else if ((hw->phy.media_type == ixgbe_media_type_copper) && + (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)) { + hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu); + } + DEBUGOUT1("Set up FC; IXGBE_AUTOC = 0x%08X\n", reg); out: @@ -3006,12 +3063,21 @@ ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete) { - u32 links_reg; + u32 links_reg, links_orig; u32 i; DEBUGFUNC("ixgbe_check_mac_link_generic"); + /* clear the old state */ + links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + + if (links_orig != links_reg) { + DEBUGOUT2("LINKS changed from %08X to %08X\n", + links_orig, links_reg); + } + if (link_up_wait_to_complete) { for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { if (links_reg & IXGBE_LINKS_UP) { @@ -3036,8 +3102,11 @@ else if ((links_reg & IXGBE_LINKS_SPEED_82599) == IXGBE_LINKS_SPEED_1G_82599) *speed = IXGBE_LINK_SPEED_1GB_FULL; + else if ((links_reg & IXGBE_LINKS_SPEED_82599) == + IXGBE_LINKS_SPEED_100_82599) + *speed = IXGBE_LINK_SPEED_100_FULL; else - *speed = IXGBE_LINK_SPEED_100_FULL; + *speed = IXGBE_LINK_SPEED_UNKNOWN; /* if link is down, zero out the current_mode */ if (*link_up == false) { @@ -3095,3 +3164,75 @@ wwn_prefix_out: return (IXGBE_SUCCESS); } + +/* + * ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM + * @hw: pointer to hardware structure + * @bs: the fcoe boot status + * + * This function will read the FCOE boot status from the iSCSI FCOE block + */ +s32 +ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs) +{ + u16 offset, caps, flags; + s32 status; + + DEBUGFUNC("ixgbe_get_fcoe_boot_status_generic"); + + /* clear output first */ + *bs = ixgbe_fcoe_bootstatus_unavailable; + + /* check if FCOE IBA block is present */ + offset = IXGBE_FCOE_IBA_CAPS_BLK_PTR; + status = hw->eeprom.ops.read(hw, offset, &caps); + if (status != IXGBE_SUCCESS) + goto out; + + if (!(caps & IXGBE_FCOE_IBA_CAPS_FCOE)) + goto out; + + /* check if iSCSI FCOE block is populated */ + status = hw->eeprom.ops.read(hw, IXGBE_ISCSI_FCOE_BLK_PTR, &offset); + if (status != IXGBE_SUCCESS) + goto out; + + if ((offset == 0) || (offset == 0xFFFF)) + goto out; + + /* read fcoe flags in iSCSI FCOE block */ + offset = offset + IXGBE_ISCSI_FCOE_FLAGS_OFFSET; + status = hw->eeprom.ops.read(hw, offset, &flags); + if (status != IXGBE_SUCCESS) + goto out; + + if (flags & IXGBE_ISCSI_FCOE_FLAGS_ENABLE) + *bs = ixgbe_fcoe_bootstatus_enabled; + else + *bs = ixgbe_fcoe_bootstatus_disabled; + +out: + return (status); +} + +/* + * ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow + * control + * @hw: pointer to hardware structure + * + * There are several phys that do not support autoneg flow control. This + * function check the device id to see if the associated phy supports + * autoneg flow control. + */ +static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) +{ + + DEBUGFUNC("ixgbe_device_supports_autoneg_fc"); + + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_T3_LOM: + return (IXGBE_SUCCESS); + default: + return (IXGBE_ERR_FC_NOT_SUPPORTED); + } +} diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_common.h --- a/usr/src/uts/common/io/ixgbe/ixgbe_common.h Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_common.h Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -22,11 +21,14 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. */ -/* IntelVersion: 1.94 sol_ixgbe_shared_339b */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* IntelVersion: 1.95 scm_061610_003709 */ #ifndef _IXGBE_COMMON_H #define _IXGBE_COMMON_H @@ -107,5 +109,6 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, u16 *wwpn_prefix); +s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs); #endif /* _IXGBE_COMMON_H */ diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_gld.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_gld.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_gld.c Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2009 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -21,8 +20,11 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. + */ + +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include "ixgbe_sw.h" @@ -517,10 +519,14 @@ switch (pr_num) { case MAC_PROP_DUPLEX: case MAC_PROP_SPEED: + mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); + break; + case MAC_PROP_ADV_100FDX_CAP: case MAC_PROP_ADV_1000FDX_CAP: case MAC_PROP_ADV_10GFDX_CAP: mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); + mac_prop_info_set_default_uint8(prh, 1); break; case MAC_PROP_AUTONEG: @@ -529,9 +535,8 @@ case MAC_PROP_EN_100FDX_CAP: perm = (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) ? MAC_PROP_PERM_RW : MAC_PROP_PERM_READ; - if (perm == MAC_PROP_PERM_RW) - mac_prop_info_set_default_uint8(prh, 1); mac_prop_info_set_perm(prh, perm); + mac_prop_info_set_default_uint8(prh, 1); break; case MAC_PROP_FLOWCTRL: diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_main.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_main.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_main.c Wed Aug 04 07:38:56 2010 +0800 @@ -30,7 +30,7 @@ #include "ixgbe_sw.h" static char ixgbe_ident[] = "Intel 10Gb Ethernet"; -static char ixgbe_version[] = "ixgbe 1.1.6"; +static char ixgbe_version[] = "ixgbe 1.1.7"; /* * Local function protoypes @@ -71,6 +71,7 @@ static int ixgbe_get_prop(ixgbe_t *, char *, int, int, int); static void ixgbe_driver_link_check(ixgbe_t *); static void ixgbe_sfp_check(void *); +static void ixgbe_overtemp_check(void *); static void ixgbe_link_timer(void *); static void ixgbe_local_timer(void *); static void ixgbe_arm_watchdog_timer(ixgbe_t *); @@ -253,6 +254,7 @@ 16, /* maximum number of ring vectors */ 2, /* maximum number of other vectors */ IXGBE_EICR_LSC, /* "other" interrupt types handled */ + 0, /* "other" interrupt types enable mask */ (IXGBE_FLAG_DCA_CAPABLE /* capability flags */ | IXGBE_FLAG_RSS_CAPABLE | IXGBE_FLAG_VMDQ_CAPABLE) @@ -275,11 +277,18 @@ 64, /* maximum total msix vectors */ 16, /* maximum number of ring vectors */ 2, /* maximum number of other vectors */ - IXGBE_EICR_LSC, /* "other" interrupt types handled */ - (IXGBE_FLAG_DCA_CAPABLE /* capability flags */ + (IXGBE_EICR_LSC + | IXGBE_EICR_GPI_SDP1 + | IXGBE_EICR_GPI_SDP2), /* "other" interrupt types handled */ + + (IXGBE_SDP1_GPIEN + | IXGBE_SDP2_GPIEN), /* "other" interrupt types enable mask */ + + (IXGBE_FLAG_DCA_CAPABLE | IXGBE_FLAG_RSS_CAPABLE | IXGBE_FLAG_VMDQ_CAPABLE - | IXGBE_FLAG_RSC_CAPABLE) + | IXGBE_FLAG_RSC_CAPABLE + | IXGBE_FLAG_SFP_PLUG_CAPABLE) /* capability flags */ }; /* @@ -471,15 +480,26 @@ /* * Create a taskq for sfp-change */ - (void) sprintf(taskqname, "ixgbe%d_taskq", instance); + (void) sprintf(taskqname, "ixgbe%d_sfp_taskq", instance); if ((ixgbe->sfp_taskq = ddi_taskq_create(devinfo, taskqname, 1, TASKQ_DEFAULTPRI, 0)) == NULL) { - ixgbe_error(ixgbe, "taskq_create failed"); + ixgbe_error(ixgbe, "sfp_taskq create failed"); goto attach_fail; } ixgbe->attach_progress |= ATTACH_PROGRESS_SFP_TASKQ; /* + * Create a taskq for over-temp + */ + (void) sprintf(taskqname, "ixgbe%d_overtemp_taskq", instance); + if ((ixgbe->overtemp_taskq = ddi_taskq_create(devinfo, taskqname, + 1, TASKQ_DEFAULTPRI, 0)) == NULL) { + ixgbe_error(ixgbe, "overtemp_taskq create failed"); + goto attach_fail; + } + ixgbe->attach_progress |= ATTACH_PROGRESS_OVERTEMP_TASKQ; + + /* * Initialize driver parameters */ if (ixgbe_init_driver_settings(ixgbe) != IXGBE_SUCCESS) { @@ -680,6 +700,13 @@ } /* + * Remove taskq for over-temp + */ + if (ixgbe->attach_progress & ATTACH_PROGRESS_OVERTEMP_TASKQ) { + ddi_taskq_destroy(ixgbe->overtemp_taskq); + } + + /* * Remove interrupts */ if (ixgbe->attach_progress & ATTACH_PROGRESS_ALLOC_INTR) { @@ -825,18 +852,21 @@ if (ixgbe_get_media_type(hw) == ixgbe_media_type_copper) { ixgbe->capab->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE; ixgbe->capab->other_intr |= IXGBE_EICR_GPI_SDP1; + ixgbe->capab->other_gpie |= IXGBE_SDP1_GPIEN; } - ixgbe->capab->other_intr |= IXGBE_EICR_LSC; - break; + case ixgbe_mac_82599EB: IXGBE_DEBUGLOG_0(ixgbe, "identify 82599 adapter\n"); ixgbe->capab = &ixgbe_82599eb_cap; - ixgbe->capab->other_intr = (IXGBE_EICR_GPI_SDP1 | - IXGBE_EICR_GPI_SDP2 | IXGBE_EICR_LSC); - + if (hw->device_id == IXGBE_DEV_ID_82599_T3_LOM) { + ixgbe->capab->flags |= IXGBE_FLAG_TEMP_SENSOR_CAPABLE; + ixgbe->capab->other_intr |= IXGBE_EICR_GPI_SDP0; + ixgbe->capab->other_gpie |= IXGBE_SDP0_GPIEN; + } break; + default: IXGBE_DEBUGLOG_1(ixgbe, "adapter not supported in ixgbe_identify_hardware(): %d\n", @@ -1255,7 +1285,8 @@ * Re-enable relaxed ordering for performance. It is disabled * by default in the hardware init. */ - ixgbe_enable_relaxed_ordering(hw); + if (ixgbe->relax_order_enable == B_TRUE) + ixgbe_enable_relaxed_ordering(hw); /* * Setup adapter interrupt vectors @@ -1563,10 +1594,11 @@ /* * ixgbe_start() will be called when resetting, however if reset - * happens, we need to clear the ERROR and STALL flags before - * enabling the interrupts. - */ - atomic_and_32(&ixgbe->ixgbe_state, ~(IXGBE_ERROR | IXGBE_STALL)); + * happens, we need to clear the ERROR, STALL and OVERTEMP flags + * before enabling the interrupts. + */ + atomic_and_32(&ixgbe->ixgbe_state, ~(IXGBE_ERROR + | IXGBE_STALL| IXGBE_OVERTEMP)); /* * Enable adapter interrupts @@ -2347,22 +2379,38 @@ for (i = 0; i < ixgbe->num_tx_rings; i++) { ring_mapping |= (i & 0xF) << (8 * (i & 0x3)); if ((i & 0x3) == 0x3) { - if (hw->mac.type >= ixgbe_mac_82599EB) { - IXGBE_WRITE_REG(hw, IXGBE_TQSM(i >> 2), - ring_mapping); - } else { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i >> 2), ring_mapping); + break; + + case ixgbe_mac_82599EB: + IXGBE_WRITE_REG(hw, IXGBE_TQSM(i >> 2), + ring_mapping); + break; + + default: + break; } + ring_mapping = 0; } } - if ((i & 0x3) != 0x3) - if (hw->mac.type >= ixgbe_mac_82599EB) { + if (i & 0x3) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i >> 2), ring_mapping); + break; + + case ixgbe_mac_82599EB: IXGBE_WRITE_REG(hw, IXGBE_TQSM(i >> 2), ring_mapping); - } else { - IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i >> 2), ring_mapping); + break; + + default: + break; } + } /* * Enable CRC appending and TX padding (for short tx frames) @@ -2500,7 +2548,6 @@ */ IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), IXGBE_VFRE_ENABLE_ALL); IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), IXGBE_VFRE_ENABLE_ALL); - break; default: @@ -2847,7 +2894,6 @@ ixgbe->num_rx_rings = ixgbe->num_rx_groups * min(2, ring_per_group); } - break; default: @@ -2996,6 +3042,8 @@ 0, 1, DEFAULT_LRO_ENABLE); ixgbe->tx_head_wb_enable = ixgbe_get_prop(ixgbe, PROP_TX_HEAD_WB_ENABLE, 0, 1, DEFAULT_TX_HEAD_WB_ENABLE); + ixgbe->relax_order_enable = ixgbe_get_prop(ixgbe, + PROP_RELAX_ORDER_ENABLE, 0, 1, DEFAULT_RELAX_ORDER_ENABLE); /* Head Write Back not recommended for 82599 */ if (hw->mac.type >= ixgbe_mac_82599EB) { @@ -3220,12 +3268,6 @@ } /* - * this is only reached after a link-status-change interrupt - * so always get new phy state - */ - ixgbe_get_hw_state(ixgbe); - - /* * If we are in an interrupt context, need to re-enable the * interrupt, which was automasked */ @@ -3258,6 +3300,7 @@ (void) ixgbe_setup_link(hw, IXGBE_LINK_SPEED_82599_AUTONEG, B_TRUE, B_TRUE); ixgbe_driver_link_check(ixgbe); + ixgbe_get_hw_state(ixgbe); } else if (eicr & IXGBE_EICR_GPI_SDP2) { /* clear the interrupt */ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2); @@ -3269,7 +3312,69 @@ (void) ixgbe_setup_link(hw, IXGBE_LINK_SPEED_82599_AUTONEG, B_TRUE, B_TRUE); ixgbe_driver_link_check(ixgbe); - } + ixgbe_get_hw_state(ixgbe); + } + mutex_exit(&ixgbe->gen_lock); + + /* + * We need to fully re-check the link later. + */ + ixgbe->link_check_complete = B_FALSE; + ixgbe->link_check_hrtime = gethrtime() + + (IXGBE_LINK_UP_TIME * 100000000ULL); +} + +/* + * ixgbe_overtemp_check - overtemp module processing done in taskq + * + * This routine will only be called on adapters with temperature sensor. + * The indication of over-temperature can be either SDP0 interrupt or the link + * status change interrupt. + */ +static void +ixgbe_overtemp_check(void *arg) +{ + ixgbe_t *ixgbe = (ixgbe_t *)arg; + struct ixgbe_hw *hw = &ixgbe->hw; + uint32_t eicr = ixgbe->eicr; + ixgbe_link_speed speed; + boolean_t link_up; + + mutex_enter(&ixgbe->gen_lock); + + /* make sure we know current state of link */ + (void) ixgbe_check_link(hw, &speed, &link_up, false); + + /* check over-temp condition */ + if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) || + (eicr & IXGBE_EICR_LSC)) { + if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP) { + atomic_or_32(&ixgbe->ixgbe_state, IXGBE_OVERTEMP); + + /* + * Disable the adapter interrupts + */ + ixgbe_disable_adapter_interrupts(ixgbe); + + /* + * Disable Rx/Tx units + */ + (void) ixgbe_stop_adapter(hw); + + ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_LOST); + ixgbe_error(ixgbe, + "Problem: Network adapter has been stopped " + "because it has overheated"); + ixgbe_error(ixgbe, + "Action: Restart the computer. " + "If the problem persists, power off the system " + "and replace the adapter"); + } + } + + /* write to clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); + mutex_exit(&ixgbe->gen_lock); } @@ -3296,12 +3401,14 @@ { ixgbe_t *ixgbe = (ixgbe_t *)arg; + if (ixgbe->ixgbe_state & IXGBE_OVERTEMP) + goto out; + if (ixgbe->ixgbe_state & IXGBE_ERROR) { ixgbe->reset_count++; if (ixgbe_reset(ixgbe) == IXGBE_SUCCESS) ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_RESTORED); - ixgbe_restart_watchdog_timer(ixgbe); - return; + goto out; } if (ixgbe_stall_check(ixgbe)) { @@ -3313,6 +3420,7 @@ ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_RESTORED); } +out: ixgbe_restart_watchdog_timer(ixgbe); } @@ -3632,15 +3740,26 @@ gpie |= IXGBE_GPIE_EIAME; } } - /* Enable specific interrupts for 82599 */ - if (hw->mac.type == ixgbe_mac_82599EB) { - gpie |= IXGBE_SDP2_GPIEN; /* pluggable optics intr */ - gpie |= IXGBE_SDP1_GPIEN; /* LSC interrupt */ - } - /* Enable RSC Dealy 8us for 82599 */ - if (ixgbe->lro_enable) { - gpie |= (1 << IXGBE_GPIE_RSC_DELAY_SHIFT); - } + + /* Enable specific "other" interrupt types */ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + gpie |= ixgbe->capab->other_gpie; + break; + + case ixgbe_mac_82599EB: + gpie |= ixgbe->capab->other_gpie; + + /* Enable RSC Delay 8us when LRO enabled */ + if (ixgbe->lro_enable) { + gpie |= (1 << IXGBE_GPIE_RSC_DELAY_SHIFT); + } + break; + + default: + break; + } + /* write to interrupt control registers */ IXGBE_WRITE_REG(hw, IXGBE_EIMS, ixgbe->eims); IXGBE_WRITE_REG(hw, IXGBE_EIAC, eiac); @@ -3794,7 +3913,8 @@ /* * Disable Atlas Tx lanes to keep packets in loopback and not on wire */ - if (hw->mac.type == ixgbe_mac_82598EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: (void) ixgbe_read_analog_reg8(&ixgbe->hw, IXGBE_ATLAS_PDN_LPBK, &atlas); atlas |= IXGBE_ATLAS_PDN_TX_REG_EN; @@ -3818,7 +3938,9 @@ atlas |= IXGBE_ATLAS_PDN_TX_AN_QL_ALL; (void) ixgbe_write_analog_reg8(&ixgbe->hw, IXGBE_ATLAS_PDN_AN, atlas); - } else if (hw->mac.type == ixgbe_mac_82599EB) { + break; + + case ixgbe_mac_82599EB: reg = IXGBE_READ_REG(&ixgbe->hw, IXGBE_AUTOC); reg |= (IXGBE_AUTOC_FLU | IXGBE_AUTOC_10G_KX4); @@ -3826,6 +3948,10 @@ (void) ixgbe_setup_link(&ixgbe->hw, IXGBE_LINK_SPEED_10GB_FULL, B_FALSE, B_TRUE); + break; + + default: + break; } } @@ -3881,8 +4007,6 @@ static void ixgbe_intr_other_work(ixgbe_t *ixgbe, uint32_t eicr) { - struct ixgbe_hw *hw = &ixgbe->hw; - ASSERT(mutex_owned(&ixgbe->gen_lock)); /* @@ -3890,6 +4014,7 @@ */ if (eicr & IXGBE_EICR_LSC) { ixgbe_driver_link_check(ixgbe); + ixgbe_get_hw_state(ixgbe); } /* @@ -3897,32 +4022,55 @@ */ if ((ixgbe->capab->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) && (eicr & IXGBE_EICR_GPI_SDP1)) { - if (hw->mac.type < ixgbe_mac_82599EB) { - ixgbe_log(ixgbe, - "Fan has stopped, replace the adapter\n"); - - /* re-enable the interrupt, which was automasked */ - ixgbe->eims |= IXGBE_EICR_GPI_SDP1; - } - } - - /* - * Do SFP check for 82599 - */ - if (hw->mac.type == ixgbe_mac_82599EB) { + atomic_or_32(&ixgbe->ixgbe_state, IXGBE_OVERTEMP); + + /* + * Disable the adapter interrupts + */ + ixgbe_disable_adapter_interrupts(ixgbe); + + /* + * Disable Rx/Tx units + */ + (void) ixgbe_stop_adapter(&ixgbe->hw); + + ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_LOST); + ixgbe_error(ixgbe, + "Problem: Network adapter has been stopped " + "because the fan has stopped.\n"); + ixgbe_error(ixgbe, + "Action: Replace the adapter.\n"); + + /* re-enable the interrupt, which was automasked */ + ixgbe->eims |= IXGBE_EICR_GPI_SDP1; + } + + /* + * Do SFP check for adapters with hot-plug capability + */ + if ((ixgbe->capab->flags & IXGBE_FLAG_SFP_PLUG_CAPABLE) && + ((eicr & IXGBE_EICR_GPI_SDP1) || (eicr & IXGBE_EICR_GPI_SDP2))) { + ixgbe->eicr = eicr; if ((ddi_taskq_dispatch(ixgbe->sfp_taskq, ixgbe_sfp_check, (void *)ixgbe, DDI_NOSLEEP)) != DDI_SUCCESS) { ixgbe_log(ixgbe, "No memory available to dispatch " "taskq for SFP check"); } - - /* - * We need to fully re-check the link later. - */ - ixgbe->link_check_complete = B_FALSE; - ixgbe->link_check_hrtime = gethrtime() + - (IXGBE_LINK_UP_TIME * 100000000ULL); + } + + /* + * Do over-temperature check for adapters with temp sensor + */ + if ((ixgbe->capab->flags & IXGBE_FLAG_TEMP_SENSOR_CAPABLE) && + ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { + ixgbe->eicr = eicr; + if ((ddi_taskq_dispatch(ixgbe->overtemp_taskq, + ixgbe_overtemp_check, (void *)ixgbe, + DDI_NOSLEEP)) != DDI_SUCCESS) { + ixgbe_log(ixgbe, "No memory available to dispatch " + "taskq for overtemp check"); + } } } @@ -4005,12 +4153,18 @@ /* any interrupt type other than tx/rx */ if (eicr & ixgbe->capab->other_intr) { - if (hw->mac.type < ixgbe_mac_82599EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR); - } - if (hw->mac.type == ixgbe_mac_82599EB) { + break; + + case ixgbe_mac_82599EB: ixgbe->eimc = IXGBE_82599_OTHER_INTR; IXGBE_WRITE_REG(hw, IXGBE_EIMC, ixgbe->eimc); + break; + + default: + break; } ixgbe_intr_other_work(ixgbe, eicr); ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR); @@ -4092,12 +4246,18 @@ /* any interrupt type other than tx/rx */ if (eicr & ixgbe->capab->other_intr) { mutex_enter(&ixgbe->gen_lock); - if (hw->mac.type < ixgbe_mac_82599EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR); - } - if (hw->mac.type == ixgbe_mac_82599EB) { + break; + + case ixgbe_mac_82599EB: ixgbe->eimc = IXGBE_82599_OTHER_INTR; IXGBE_WRITE_REG(hw, IXGBE_EIMC, ixgbe->eimc); + break; + + default: + break; } ixgbe_intr_other_work(ixgbe, eicr); ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR); @@ -4160,24 +4320,25 @@ } /* - * Need check cause bits and only other causes will - * be processed + * Check "other" cause bits: any interrupt type other than tx/rx */ - /* any interrupt type other than tx/rx */ if (eicr & ixgbe->capab->other_intr) { - if (hw->mac.type < ixgbe_mac_82599EB) { - mutex_enter(&ixgbe->gen_lock); + mutex_enter(&ixgbe->gen_lock); + switch (hw->mac.type) { + case ixgbe_mac_82598EB: ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR); ixgbe_intr_other_work(ixgbe, eicr); - mutex_exit(&ixgbe->gen_lock); - } else { - if (hw->mac.type == ixgbe_mac_82599EB) { - mutex_enter(&ixgbe->gen_lock); - ixgbe->eims |= IXGBE_EICR_RTX_QUEUE; - ixgbe_intr_other_work(ixgbe, eicr); - mutex_exit(&ixgbe->gen_lock); - } + break; + + case ixgbe_mac_82599EB: + ixgbe->eims |= IXGBE_EICR_RTX_QUEUE; + ixgbe_intr_other_work(ixgbe, eicr); + break; + + default: + break; } + mutex_exit(&ixgbe->gen_lock); } /* re-enable the interrupts which were automasked */ @@ -4373,9 +4534,8 @@ */ ring_per_group = ixgbe->num_rx_rings / ixgbe->num_rx_groups; ASSERT((ixgbe->num_rx_rings % ixgbe->num_rx_groups) == 0); - if (min(actual, ixgbe->num_rx_rings) < ring_per_group) { - ixgbe->num_rx_rings = ixgbe->num_rx_groups * - min(actual, ixgbe->num_rx_rings); + if (actual < ring_per_group) { + ixgbe->num_rx_rings = ixgbe->num_rx_groups * actual; ixgbe_setup_vmdq_rss_conf(ixgbe); } @@ -4569,6 +4729,7 @@ ivar |= (msix_vector << (8 * (intr_alloc_entry & 0x3))); IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar); break; + case ixgbe_mac_82599EB: if (cause == -1) { /* other causes */ @@ -4590,6 +4751,7 @@ ivar); } break; + default: break; } @@ -4620,6 +4782,7 @@ (intr_alloc_entry & 0x3))); IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar); break; + case ixgbe_mac_82599EB: if (cause == -1) { /* other causes */ @@ -4637,6 +4800,7 @@ ivar); } break; + default: break; } @@ -4667,6 +4831,7 @@ (intr_alloc_entry & 0x3))); IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar); break; + case ixgbe_mac_82599EB: if (cause == -1) { /* other causes */ @@ -4684,6 +4849,7 @@ ivar); } break; + default: break; } @@ -4704,19 +4870,26 @@ ixgbe->classify_mode == IXGBE_CLASSIFY_NONE) { return (sw_rx_index); } else if (ixgbe->classify_mode == IXGBE_CLASSIFY_VMDQ) { - if (hw->mac.type == ixgbe_mac_82598EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: return (sw_rx_index); - } else if (hw->mac.type == ixgbe_mac_82599EB) { + + case ixgbe_mac_82599EB: return (sw_rx_index * 2); + + default: + break; } } else if (ixgbe->classify_mode == IXGBE_CLASSIFY_VMDQ_RSS) { rx_ring_per_group = ixgbe->num_rx_rings / ixgbe->num_rx_groups; - if (hw->mac.type == ixgbe_mac_82598EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: hw_rx_index = (sw_rx_index / rx_ring_per_group) * 16 + (sw_rx_index % rx_ring_per_group); return (hw_rx_index); - } else if (hw->mac.type == ixgbe_mac_82599EB) { + + case ixgbe_mac_82599EB: if (ixgbe->num_rx_groups > 32) { hw_rx_index = (sw_rx_index / rx_ring_per_group) * 2 + @@ -4727,6 +4900,9 @@ (sw_rx_index % rx_ring_per_group); } return (hw_rx_index); + + default: + break; } } @@ -4815,14 +4991,14 @@ case ixgbe_mac_82598EB: for (v_idx = 0; v_idx < 25; v_idx++) IXGBE_WRITE_REG(hw, IXGBE_IVAR(v_idx), 0); - break; + case ixgbe_mac_82599EB: for (v_idx = 0; v_idx < 64; v_idx++) IXGBE_WRITE_REG(hw, IXGBE_IVAR(v_idx), 0); IXGBE_WRITE_REG(hw, IXGBE_IVAR_MISC, 0); - break; + default: break; } @@ -4997,6 +5173,7 @@ boolean_t link_up = B_FALSE; uint32_t pcs1g_anlp = 0; uint32_t pcs1g_ana = 0; + boolean_t autoneg = B_FALSE; ASSERT(mutex_owned(&ixgbe->gen_lock)); ixgbe->param_lp_1000fdx_cap = 0; @@ -5004,9 +5181,10 @@ /* check for link, don't wait */ (void) ixgbe_check_link(hw, &speed, &link_up, false); + pcs1g_ana = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + if (link_up) { pcs1g_anlp = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); - pcs1g_ana = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); ixgbe->param_lp_1000fdx_cap = (pcs1g_anlp & IXGBE_PCS1GANLP_LPFD) ? 1 : 0; @@ -5014,9 +5192,12 @@ (pcs1g_anlp & IXGBE_PCS1GANLP_LPFD) ? 1 : 0; } - ixgbe->param_adv_1000fdx_cap = - (pcs1g_ana & IXGBE_PCS1GANA_FDC) ? 1 : 0; - ixgbe->param_adv_100fdx_cap = (pcs1g_ana & IXGBE_PCS1GANA_FDC) ? 1 : 0; + (void) ixgbe_get_link_capabilities(hw, &speed, &autoneg); + + ixgbe->param_adv_1000fdx_cap = ((pcs1g_ana & IXGBE_PCS1GANA_FDC) && + (speed & IXGBE_LINK_SPEED_1GB_FULL)) ? 1 : 0; + ixgbe->param_adv_100fdx_cap = ((pcs1g_ana & IXGBE_PCS1GANA_FDC) && + (speed & IXGBE_LINK_SPEED_100_FULL)) ? 1 : 0; } /* diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_osdep.h --- a/usr/src/uts/common/io/ixgbe/ixgbe_osdep.h Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_osdep.h Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2009 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -21,8 +20,11 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. + */ + +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _IXGBE_OSDEP_H @@ -81,10 +83,16 @@ ddi_put32((OS_DEP(a))->reg_handle, \ (uint32_t *)((uintptr_t)(a)->hw_addr + reg), (value)) +#define IXGBE_WRITE_REG_ARRAY(a, reg, index, value) \ + IXGBE_WRITE_REG(a, ((reg) + ((index) << 2)), (value)) + #define IXGBE_READ_REG(a, reg) \ ddi_get32((OS_DEP(a))->reg_handle, \ (uint32_t *)((uintptr_t)(a)->hw_addr + reg)) +#define IXGBE_READ_REG_ARRAY(a, reg, index) \ + IXGBE_READ_REG(a, ((reg) + ((index) << 2))) + #define IXGBE_WRITE_REG64(hw, reg, value) \ do { \ IXGBE_WRITE_REG(hw, reg, (u32) value); \ diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_phy.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_phy.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_phy.c Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -22,11 +21,14 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. */ -/* IntelVersion: 1.99 sol_ixgbe_shared_339b */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* IntelVersion: 1.109 scm_061610_003709 */ #include "ixgbe_api.h" #include "ixgbe_common.h" @@ -74,6 +76,7 @@ phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear; phy->ops.identify_sfp = &ixgbe_identify_sfp_module_generic; phy->sfp_type = ixgbe_sfp_type_unknown; + phy->ops.check_overtemp = &ixgbe_tn_check_overtemp; return (IXGBE_SUCCESS); } @@ -237,6 +240,12 @@ if (status != IXGBE_SUCCESS || hw->phy.type == ixgbe_phy_none) goto out; + if (!hw->phy.reset_if_overtemp && + (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw))) { + /* Don't reset PHY if it's shut down due to overtemp. */ + goto out; + } + /* * Perform soft PHY reset to the PHY_XS. * This will cause a soft reset to the PHY @@ -245,13 +254,19 @@ IXGBE_MDIO_PHY_XS_DEV_TYPE, IXGBE_MDIO_PHY_XS_RESET); - /* Poll for reset bit to self-clear indicating reset is complete */ - for (i = 0; i < 500; i++) { - msec_delay(1); + /* + * Poll for reset bit to self-clear indicating reset is complete. + * Some PHYs could take up to 3 seconds to complete and need about + * 1.7 usec delay after the reset is complete. + */ + for (i = 0; i < 30; i++) { + msec_delay(100); hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl); - if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) + if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) { + usec_delay(2); break; + } } if (ctrl & IXGBE_MDIO_PHY_XS_RESET) { @@ -933,6 +948,7 @@ u8 comp_codes_10g = 0; u8 oui_bytes[3] = {0, 0, 0}; u8 cable_tech = 0; + u8 cable_spec = 0; u16 enforce_sfp = 0; DEBUGFUNC("ixgbe_identify_sfp_module_generic"); @@ -980,6 +996,10 @@ * 4 SFP_DA_CORE1 - 82599-specific * 5 SFP_SR/LR_CORE0 - 82599-specific * 6 SFP_SR/LR_CORE1 - 82599-specific + * 7 SFP_act_lmt_DA_CORE0 - 82599-specific + * 8 SFP_act_lmt_DA_CORE1 - 82599-specific + * 9 SFP_1g_cu_CORE0 - 82599-specific + * 10 SFP_1g_cu_CORE1 - 82599-specific */ if (hw->mac.type == ixgbe_mac_82598EB) { if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) @@ -991,29 +1011,46 @@ else hw->phy.sfp_type = ixgbe_sfp_type_unknown; } else if (hw->mac.type == ixgbe_mac_82599EB) { - if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) + if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) { if (hw->bus.lan_id == 0) hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core0; else hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core1; - else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) + } else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) { + hw->phy.ops.read_i2c_eeprom( + hw, IXGBE_SFF_CABLE_SPEC_COMP, &cable_spec); + if (cable_spec & + IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_da_act_lmt_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_da_act_lmt_core1; + } else + hw->phy.sfp_type = + ixgbe_sfp_type_unknown; + } else if (comp_codes_10g & + (IXGBE_SFF_10GBASESR_CAPABLE | + IXGBE_SFF_10GBASELR_CAPABLE)) { if (hw->bus.lan_id == 0) hw->phy.sfp_type = ixgbe_sfp_type_srlr_core0; else hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1; - else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) + } else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) { if (hw->bus.lan_id == 0) hw->phy.sfp_type = - ixgbe_sfp_type_srlr_core0; + ixgbe_sfp_type_1g_cu_core0; else hw->phy.sfp_type = - ixgbe_sfp_type_srlr_core1; - else + ixgbe_sfp_type_1g_cu_core1; + } else { hw->phy.sfp_type = ixgbe_sfp_type_unknown; + } } if (hw->phy.sfp_type != stored_sfp_type) @@ -1046,10 +1083,14 @@ switch (vendor_oui) { case IXGBE_SFF_VENDOR_OUI_TYCO: if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) - hw->phy.type = ixgbe_phy_tw_tyco; + hw->phy.type = + ixgbe_phy_sfp_passive_tyco; break; case IXGBE_SFF_VENDOR_OUI_FTL: - hw->phy.type = ixgbe_phy_sfp_ftl; + if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) + hw->phy.type = ixgbe_phy_sfp_ftl_active; + else + hw->phy.type = ixgbe_phy_sfp_ftl; break; case IXGBE_SFF_VENDOR_OUI_AVAGO: hw->phy.type = ixgbe_phy_sfp_avago; @@ -1059,21 +1100,28 @@ break; default: if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) - hw->phy.type = ixgbe_phy_tw_unknown; + hw->phy.type = + ixgbe_phy_sfp_passive_unknown; + else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) + hw->phy.type = + ixgbe_phy_sfp_active_unknown; else hw->phy.type = ixgbe_phy_sfp_unknown; break; } } - /* All passive DA cables are supported */ - if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) { + /* Allow any DA cable vendor */ + if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE | + IXGBE_SFF_DA_ACTIVE_CABLE)) { status = IXGBE_SUCCESS; goto out; } - /* 1G SFP modules are not supported */ - if (comp_codes_10g == 0) { + /* Verify supporteed 1G SFP modules */ + if (comp_codes_10g == 0 && + !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0)) { hw->phy.type = ixgbe_phy_sfp_unsupported; status = IXGBE_ERR_SFP_NOT_SUPPORTED; goto out; @@ -1086,7 +1134,9 @@ } (void) ixgbe_get_device_caps(hw, &enforce_sfp); - if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) { + if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) && + !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) || + (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1))) { /* Make sure we're a supported PHY type */ if (hw->phy.type == ixgbe_phy_sfp_intel) { status = IXGBE_SUCCESS; @@ -1118,6 +1168,7 @@ u16 *list_offset, u16 *data_offset) { u16 sfp_id; + u16 sfp_type = hw->phy.sfp_type; DEBUGFUNC("ixgbe_get_sfp_init_sequence_offsets"); @@ -1131,6 +1182,17 @@ (hw->phy.sfp_type == ixgbe_sfp_type_da_cu)) return (IXGBE_ERR_SFP_NOT_SUPPORTED); + /* + * Limiting active cables and 1G Phys must be initialized as + * SR modules + */ + if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || + sfp_type == ixgbe_sfp_type_1g_cu_core0) + sfp_type = ixgbe_sfp_type_srlr_core0; + else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || + sfp_type == ixgbe_sfp_type_1g_cu_core1) + sfp_type = ixgbe_sfp_type_srlr_core1; + /* Read offset to PHY init contents */ hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset); @@ -1147,7 +1209,7 @@ hw->eeprom.ops.read(hw, *list_offset, &sfp_id); while (sfp_id != IXGBE_PHY_INIT_END_NL) { - if (sfp_id == hw->phy.sfp_type) { + if (sfp_id == sfp_type) { (*list_offset)++; hw->eeprom.ops.read(hw, *list_offset, data_offset); if ((!*data_offset) || (*data_offset == 0xFFFF)) { @@ -1745,3 +1807,32 @@ /* Put the i2c bus back to default state */ ixgbe_i2c_stop(hw); } + +/* + * ixgbe_tn_check_overtemp - Checks if an overtemp occured. + * @hw: pointer to hardware structure + * + * Checks if the LASI temp alarm status was triggered due to overtemp + */ +s32 +ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u16 phy_data = 0; + + DEBUGFUNC("ixgbe_tn_check_overtemp"); + + if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM) + goto out; + + /* Check that the LASI temp alarm status was triggered */ + hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data); + + if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM)) + goto out; + + status = IXGBE_ERR_OVERTEMP; +out: + return (status); +} diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_phy.h --- a/usr/src/uts/common/io/ixgbe/ixgbe_phy.h Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_phy.h Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -22,11 +21,14 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. */ -/* IntelVersion: 1.37 sol_ixgbe_shared_339b */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* IntelVersion: 1.43 scm_061610_003709 */ #ifndef _IXGBE_PHY_H #define _IXGBE_PHY_H @@ -44,11 +46,15 @@ #define IXGBE_SFF_1GBE_COMP_CODES 0x6 #define IXGBE_SFF_10GBE_COMP_CODES 0x3 #define IXGBE_SFF_CABLE_TECHNOLOGY 0x8 +#define IXGBE_SFF_CABLE_SPEC_COMP 0x3C /* Bitmasks */ #define IXGBE_SFF_DA_PASSIVE_CABLE 0x4 +#define IXGBE_SFF_DA_ACTIVE_CABLE 0x8 +#define IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING 0x4 #define IXGBE_SFF_1GBASESX_CAPABLE 0x1 #define IXGBE_SFF_1GBASELX_CAPABLE 0x2 +#define IXGBE_SFF_1GBASET_CAPABLE 0x8 #define IXGBE_SFF_10GBASESR_CAPABLE 0x10 #define IXGBE_SFF_10GBASELR_CAPABLE 0x20 #define IXGBE_I2C_EEPROM_READ_MASK 0x100 @@ -58,6 +64,10 @@ #define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2 #define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3 +/* Flow control defines */ +#define IXGBE_TAF_SYM_PAUSE 0x400 +#define IXGBE_TAF_ASM_PAUSE 0x800 + /* Bit-shift macros */ #define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24 #define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16 @@ -81,6 +91,9 @@ #define IXGBE_I2C_T_SU_STO 4 #define IXGBE_I2C_T_BUF 5 +#define IXGBE_TN_LASI_STATUS_REG 0x9005 +#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008 + s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw); bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr); enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); @@ -110,6 +123,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *list_offset, u16 *data_offset); +s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data); s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_rx.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_rx.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_rx.c Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2009 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -21,8 +20,11 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. + */ + +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include "ixgbe_sw.h" @@ -560,6 +562,7 @@ if ((ixgbe->ixgbe_state & IXGBE_SUSPENDED) || (ixgbe->ixgbe_state & IXGBE_ERROR) || + (ixgbe->ixgbe_state & IXGBE_OVERTEMP) || !(ixgbe->ixgbe_state & IXGBE_STARTED)) return (NULL); diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_stat.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_stat.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_stat.c Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2009 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -21,8 +20,11 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. + */ + +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include "ixgbe_sw.h" @@ -103,14 +105,22 @@ ixgbe_ks->qbrc[i].value.ui64 += IXGBE_READ_REG(hw, IXGBE_QBRC(i)); ixgbe_ks->tor.value.ui64 += ixgbe_ks->qbrc[i].value.ui64; - if (hw->mac.type >= ixgbe_mac_82599EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ixgbe_ks->qbtc[i].value.ui64 += + IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + break; + + case ixgbe_mac_82599EB: ixgbe_ks->qbtc[i].value.ui64 += IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); - ixgbe_ks->qbtc[i].value.ui64 += ((uint64_t) - (IXGBE_READ_REG(hw, IXGBE_QBTC_H(i))) << 32); - } else { ixgbe_ks->qbtc[i].value.ui64 += - IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + ((uint64_t)((IXGBE_READ_REG(hw, + IXGBE_QBTC_H(i))) & 0xF) << 32); + break; + + default: + break; } ixgbe_ks->tot.value.ui64 += ixgbe_ks->qbtc[i].value.ui64; } @@ -148,20 +158,34 @@ ixgbe_ks->mrfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MRFC); ixgbe_ks->rlec.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RLEC); ixgbe_ks->lxontxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXONTXC); - if (hw->mac.type == ixgbe_mac_82598EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXONRXC); - } else { + break; + + case ixgbe_mac_82599EB: ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + break; + + default: + break; } ixgbe_ks->lxofftxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); - if (hw->mac.type == ixgbe_mac_82598EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); - } else { + break; + + case ixgbe_mac_82599EB: ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + break; + + default: + break; } ixgbe_ks->ruc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RUC); ixgbe_ks->rfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RFC); @@ -525,14 +549,22 @@ case MAC_STAT_OBYTES: ixgbe_ks->tot.value.ui64 = 0; for (i = 0; i < 16; i++) { - if (hw->mac.type >= ixgbe_mac_82599EB) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ixgbe_ks->qbtc[i].value.ui64 += + IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + break; + + case ixgbe_mac_82599EB: ixgbe_ks->qbtc[i].value.ui64 += IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); - ixgbe_ks->qbtc[i].value.ui64 += ((uint64_t) - IXGBE_READ_REG(hw, IXGBE_QBTC_H(i))) << 32; - } else { ixgbe_ks->qbtc[i].value.ui64 += - IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + ((uint64_t)((IXGBE_READ_REG(hw, + IXGBE_QBTC_H(i))) & 0xF) << 32); + break; + + default: + break; } ixgbe_ks->tot.value.ui64 += ixgbe_ks->qbtc[i].value.ui64; diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_sw.h --- a/usr/src/uts/common/io/ixgbe/ixgbe_sw.h Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_sw.h Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2009 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -21,8 +20,11 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. + */ + +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _IXGBE_SW_H @@ -80,6 +82,7 @@ #define IXGBE_STARTED 0x02 #define IXGBE_SUSPENDED 0x04 #define IXGBE_STALL 0x08 +#define IXGBE_OVERTEMP 0x20 #define IXGBE_INTR_ADJUST 0x40 #define IXGBE_ERROR 0x80 @@ -110,7 +113,6 @@ #define MAX_TX_QUEUE_NUM 128 #define MAX_RX_QUEUE_NUM 128 #define MAX_INTR_VECTOR 64 -#define MAX_RX_GROUP_NUM 64 /* * Maximum values for user configurable parameters @@ -163,6 +165,7 @@ #define DEFAULT_LRO_ENABLE B_FALSE #define DEFAULT_MR_ENABLE B_TRUE #define DEFAULT_TX_HEAD_WB_ENABLE B_TRUE +#define DEFAULT_RELAX_ORDER_ENABLE B_TRUE #define IXGBE_LSO_MAXLEN 65535 @@ -203,6 +206,7 @@ #define ATTACH_PROGRESS_FM_INIT 0x2000 /* FMA initialized */ #define ATTACH_PROGRESS_SFP_TASKQ 0x4000 /* SFP taskq created */ #define ATTACH_PROGRESS_LINK_TIMER 0x8000 /* link check timer */ +#define ATTACH_PROGRESS_OVERTEMP_TASKQ 0x10000 /* Over-temp taskq created */ #define PROP_DEFAULT_MTU "default_mtu" #define PROP_FLOW_CONTROL "flow_control" @@ -218,6 +222,7 @@ #define PROP_LSO_ENABLE "lso_enable" #define PROP_LRO_ENABLE "lro_enable" #define PROP_MR_ENABLE "mr_enable" +#define PROP_RELAX_ORDER_ENABLE "relax_order_enable" #define PROP_TX_HEAD_WB_ENABLE "tx_head_wb_enable" #define PROP_TX_COPY_THRESHOLD "tx_copy_threshold" #define PROP_TX_RECYCLE_THRESHOLD "tx_recycle_threshold" @@ -249,6 +254,8 @@ #define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 7) #define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 8) #define IXGBE_FLAG_RSC_CAPABLE (u32)(1 << 9) +#define IXGBE_FLAG_SFP_PLUG_CAPABLE (u32)(1 << 10) +#define IXGBE_FLAG_TEMP_SENSOR_CAPABLE (u32)(1 << 11) /* * Classification mode @@ -281,6 +288,7 @@ uint32_t max_ring_vect; /* maximum number of ring vectors */ uint32_t max_other_vect; /* maximum number of other vectors */ uint32_t other_intr; /* "other" interrupt types handled */ + uint32_t other_gpie; /* "other" interrupt types enabling */ uint32_t flags; /* capability flags */ } adapter_info_t; @@ -617,6 +625,7 @@ adapter_info_t *capab; /* adapter hardware capabilities */ ddi_taskq_t *sfp_taskq; /* sfp-change taskq */ + ddi_taskq_t *overtemp_taskq; /* overtemp taskq */ uint32_t eims; /* interrupt mask setting */ uint32_t eimc; /* interrupt mask clear */ uint32_t eicr; /* interrupt cause reg */ @@ -667,6 +676,7 @@ boolean_t tx_hcksum_enable; /* Tx h/w cksum offload */ boolean_t lso_enable; /* Large Segment Offload */ boolean_t mr_enable; /* Multiple Tx and Rx Ring */ + boolean_t relax_order_enable; /* Relax Order */ uint32_t classify_mode; /* Classification mode */ uint32_t tx_copy_thresh; /* Tx copy threshold */ uint32_t tx_recycle_thresh; /* Tx recycle threshold */ diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_tx.c --- a/usr/src/uts/common/io/ixgbe/ixgbe_tx.c Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_tx.c Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -21,8 +20,11 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. + */ + +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include "ixgbe_sw.h" @@ -101,6 +103,7 @@ if ((ixgbe->ixgbe_state & IXGBE_SUSPENDED) || (ixgbe->ixgbe_state & IXGBE_ERROR) || + (ixgbe->ixgbe_state & IXGBE_OVERTEMP) || !(ixgbe->ixgbe_state & IXGBE_STARTED)) { return (mp); } @@ -476,8 +479,10 @@ * Before fill the tx descriptor ring with the data, we need to * ensure there are adequate free descriptors for transmit * (including one context descriptor). + * Do not use up all the tx descriptors. + * Otherwise tx recycle will fail and cause false hang. */ - if (tx_ring->tbd_free < (desc_total + 1)) { + if (tx_ring->tbd_free <= (desc_total + 1)) { tx_ring->tx_recycle(tx_ring); } @@ -490,7 +495,7 @@ * ensure the correctness when multiple threads access it in * parallel. */ - if (tx_ring->tbd_free < (desc_total + 1)) { + if (tx_ring->tbd_free <= (desc_total + 1)) { IXGBE_DEBUG_STAT(tx_ring->stat_fail_no_tbd); mutex_exit(&tx_ring->tx_lock); goto tx_failure; @@ -1080,6 +1085,15 @@ first_tbd->read.cmd_type_len |= IXGBE_ADVTXD_DCMD_IFCS; switch (hw->mac.type) { + case ixgbe_mac_82598EB: + if (ctx != NULL && ctx->lso_flag) { + first_tbd->read.cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; + first_tbd->read.olinfo_status |= + (mbsize - ctx->mac_hdr_len - ctx->ip_hdr_len + - ctx->l4_hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT; + } + break; + case ixgbe_mac_82599EB: if (ctx != NULL && ctx->lso_flag) { first_tbd->read.cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; @@ -1091,14 +1105,7 @@ (mbsize << IXGBE_ADVTXD_PAYLEN_SHIFT); } break; - case ixgbe_mac_82598EB: - if (ctx != NULL && ctx->lso_flag) { - first_tbd->read.cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; - first_tbd->read.olinfo_status |= - (mbsize - ctx->mac_hdr_len - ctx->ip_hdr_len - - ctx->l4_hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT; - } - break; + default: break; } diff -r f651e899cbc9 -r 22e6d3edaab5 usr/src/uts/common/io/ixgbe/ixgbe_type.h --- a/usr/src/uts/common/io/ixgbe/ixgbe_type.h Tue Aug 03 15:54:52 2010 -0700 +++ b/usr/src/uts/common/io/ixgbe/ixgbe_type.h Wed Aug 04 07:38:56 2010 +0800 @@ -1,7 +1,6 @@ /* * CDDL HEADER START * - * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. @@ -22,11 +21,14 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. */ -/* IntelVersion: 1.375.4.1 sol_ixgbe_shared_339b */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* IntelVersion: 1.397 scm_061610_003709 */ #ifndef _IXGBE_TYPE_H #define _IXGBE_TYPE_H @@ -53,11 +55,12 @@ #define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514 #define IXGBE_DEV_ID_82599_KR 0x1517 #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 +#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C #define IXGBE_DEV_ID_82599_CX4 0x10F9 #define IXGBE_DEV_ID_82599_SFP 0x10FB #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC -#define IXGBE_DEV_ID_82599_T 0x10FA +#define IXGBE_DEV_ID_82599_T3_LOM 0x151C /* General Registers */ #define IXGBE_CTRL 0x00000 @@ -87,7 +90,7 @@ /* General Receive Control */ #define IXGBE_GRC_MNG 0x00000001 /* Manageability Enable */ -#define IXGBE_GRC_APME 0x00000002 /* Advanced Power Management Enable */ +#define IXGBE_GRC_APME 0x00000002 /* APM enabled in EEPROM */ #define IXGBE_VPDDIAG0 0x10204 #define IXGBE_VPDDIAG1 0x10208 @@ -226,6 +229,7 @@ #define IXGBE_MTQC 0x08120 #define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */ #define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */ +#define IXGBE_VMVIR(_i) (0x08000 + ((_i) * 4)) /* 64 of these (0-63) */ #define IXGBE_VT_CTL 0x051B0 #define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4)) #define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4)) @@ -331,6 +335,7 @@ /* Wake Up Control */ #define IXGBE_WUC_PME_EN 0x00000002 /* PME Enable */ #define IXGBE_WUC_PME_STATUS 0x00000004 /* PME Status */ +#define IXGBE_WUC_WKEN 0x00000010 /* Enable PE_WAKE_N pin assertion */ /* Wake Up Filter Control */ #define IXGBE_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ @@ -631,6 +636,8 @@ #define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBRC_L(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBRC_H(_i) (0x01038 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */ #define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */ @@ -1003,6 +1010,8 @@ #define IXGBE_MDIO_AUTO_NEG_CONTROL 0x0 /* AUTO_NEG Control Reg */ #define IXGBE_MDIO_AUTO_NEG_STATUS 0x1 /* AUTO_NEG Status Reg */ +#define IXGBE_MDIO_AUTO_NEG_ADVT 0x10 /* AUTO_NEG Advt Reg */ +#define IXGBE_MDIO_AUTO_NEG_LP 0x13 /* AUTO_NEG LP Status Reg */ #define IXGBE_MDIO_PHY_XS_CONTROL 0x0 /* PHY_XS Control Reg */ #define IXGBE_MDIO_PHY_XS_RESET 0x8000 /* PHY_XS Reset */ #define IXGBE_MDIO_PHY_ID_HIGH 0x2 /* PHY ID High Reg */ @@ -1365,10 +1374,12 @@ * EAPOL 802.1x (0x888e): Filter 0 * FCoE (0x8906): Filter 2 * 1588 (0x88f7): Filter 3 + * FIP (0x8914): Filter 4 */ #define IXGBE_ETQF_FILTER_EAPOL 0 #define IXGBE_ETQF_FILTER_FCOE 2 #define IXGBE_ETQF_FILTER_1588 3 +#define IXGBE_ETQF_FILTER_FIP 4 /* VLAN Control Bit Masks */ #define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */ @@ -1381,6 +1392,10 @@ #define IXGBE_VLVF_VIEN 0x80000000 /* filter is valid */ #define IXGBE_VLVF_ENTRIES 64 #define IXGBE_VLVF_VLANID_MASK 0x00000FFF +/* Per VF Port VLAN insertion rules */ +#define IXGBE_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */ +#define IXGBE_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */ + #define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */ @@ -1648,6 +1663,11 @@ #define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2 #define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4 #define IXGBE_FW_PATCH_VERSION_4 0x7 +#define IXGBE_FCOE_IBA_CAPS_BLK_PTR 0x33 /* iSCSI/FCOE block */ +#define IXGBE_FCOE_IBA_CAPS_FCOE 0x20 /* FCOE flags */ +#define IXGBE_ISCSI_FCOE_BLK_PTR 0x17 /* iSCSI/FCOE block */ +#define IXGBE_ISCSI_FCOE_FLAGS_OFFSET 0x0 /* FCOE flags */ +#define IXGBE_ISCSI_FCOE_FLAGS_ENABLE 0x1 /* FCOE flags enable bit */ #define IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR 0x27 /* Alt. SAN MAC block */ #define IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET 0x0 /* Alt. SAN MAC capability */ #define IXGBE_ALT_SAN_MAC_ADDR_PORT0_OFFSET 0x1 /* Alt. SAN MAC 0 offset */ @@ -1794,6 +1814,7 @@ #define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */ #define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */ #define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */ +#define IXGBE_MTQC_4TC_4TQ 0x8 /* 4 TC if RT_ENA and VT_ENA */ #define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */ /* Receive Descriptor bit definitions */ @@ -1954,10 +1975,63 @@ #define IXGBE_MBVFICR(_i) (0x00710 + (_i * 4)) #define IXGBE_VFLRE(_i) (((_i & 1) ? 0x001C0 : 0x00600)) #define IXGBE_VFLREC(_i) (0x00700 + (_i * 4)) +/* Translated register #defines */ +#define IXGBE_PVFCTRL(P) (0x00300 + (4 * P)) +#define IXGBE_PVFSTATUS(P) (0x00008 + (0 * P)) +#define IXGBE_PVFLINKS(P) (0x042A4 + (0 * P)) +#define IXGBE_PVFRTIMER(P) (0x00048 + (0 * P)) +#define IXGBE_PVFMAILBOX(P) (0x04C00 + (4 * P)) +#define IXGBE_PVFRXMEMWRAP(P) (0x03190 + (0 * P)) +#define IXGBE_PVTEICR(P) (0x00B00 + (4 * P)) +#define IXGBE_PVTEICS(P) (0x00C00 + (4 * P)) +#define IXGBE_PVTEIMS(P) (0x00D00 + (4 * P)) +#define IXGBE_PVTEIMC(P) (0x00E00 + (4 * P)) +#define IXGBE_PVTEIAC(P) (0x00F00 + (4 * P)) +#define IXGBE_PVTEIAM(P) (0x04D00 + (4 * P)) +#define IXGBE_PVTEITR(P) (((P) < 24) ? (0x00820 + ((P) * 4)) : \ + (0x012300 + (((P) - 24) * 4))) +#define IXGBE_PVTIVAR(P) (0x12500 + (4 * P)) +#define IXGBE_PVTIVAR_MISC(P) (0x04E00 + (4 * P)) +#define IXGBE_PVTRSCINT(P) (0x12000 + (4 * P)) +#define IXGBE_VFPBACL(P) (0x110C8 + (4 * P)) +#define IXGBE_PVFRDBAL(P) ((P < 64) ? (0x01000 + (0x40 * P)) \ + : (0x0D000 + (0x40 * (P - 64)))) +#define IXGBE_PVFRDBAH(P) ((P < 64) ? (0x01004 + (0x40 * P)) \ + : (0x0D004 + (0x40 * (P - 64)))) +#define IXGBE_PVFRDLEN(P) ((P < 64) ? (0x01008 + (0x40 * P)) \ + : (0x0D008 + (0x40 * (P - 64)))) +#define IXGBE_PVFRDH(P) ((P < 64) ? (0x01010 + (0x40 * P)) \ + : (0x0D010 + (0x40 * (P - 64)))) +#define IXGBE_PVFRDT(P) ((P < 64) ? (0x01018 + (0x40 * P)) \ + : (0x0D018 + (0x40 * (P - 64)))) +#define IXGBE_PVFRXDCTL(P) ((P < 64) ? (0x01028 + (0x40 * P)) \ + : (0x0D028 + (0x40 * (P - 64)))) +#define IXGBE_PVFSRRCTL(P) ((P < 64) ? (0x01014 + (0x40 * P)) \ + : (0x0D014 + (0x40 * (P - 64)))) +#define IXGBE_PVFPSRTYPE(P) (0x0EA00 + (4 * P)) +#define IXGBE_PVFTDBAL(P) (0x06000 + (0x40 * P)) +#define IXGBE_PVFTDBAH(P) (0x06004 + (0x40 * P)) +#define IXGBE_PVFTTDLEN(P) (0x06008 + (0x40 * P)) +#define IXGBE_PVFTDH(P) (0x06010 + (0x40 * P)) +#define IXGBE_PVFTDT(P) (0x06018 + (0x40 * P)) +#define IXGBE_PVFTXDCTL(P) (0x06028 + (0x40 * P)) +#define IXGBE_PVFTDWBAL(P) (0x06038 + (0x40 * P)) +#define IXGBE_PVFTDWBAH(P) (0x0603C + (0x40 * P)) +#define IXGBE_PVFDCA_RXCTRL(P) ((P < 64) ? (0x0100C + (0x40 * P)) \ + : (0x0D00C + (0x40 * (P - 64)))) +#define IXGBE_PVFDCA_TXCTRL(P) (0x0600C + (0x40 * P)) +#define IXGBE_PVFGPRC(x) (0x0101C + (0x40 * x)) +#define IXGBE_PVFGPTC(x) (0x08300 + (0x04 * x)) +#define IXGBE_PVFGORC_LSB(x) (0x01020 + (0x40 * x)) +#define IXGBE_PVFGORC_MSB(x) (0x0D020 + (0x40 * x)) +#define IXGBE_PVFGOTC_LSB(x) (0x08400 + (0x08 * x)) +#define IXGBE_PVFGOTC_MSB(x) (0x08404 + (0x08 * x)) +#define IXGBE_PVFMPRC(x) (0x0D01C + (0x40 * x)) #ifndef __le16 /* Little Endian defines */ #define __le16 u16 + #define __le32 u32 #define __le64 u64 #endif @@ -1997,10 +2071,9 @@ #define IXGBE_FDIRM_VLANID 0x00000001 #define IXGBE_FDIRM_VLANP 0x00000002 #define IXGBE_FDIRM_POOL 0x00000004 -#define IXGBE_FDIRM_L3P 0x00000008 -#define IXGBE_FDIRM_L4P 0x00000010 -#define IXGBE_FDIRM_FLEX 0x00000020 -#define IXGBE_FDIRM_DIPv6 0x00000040 +#define IXGBE_FDIRM_L4P 0x00000008 +#define IXGBE_FDIRM_FLEX 0x00000010 +#define IXGBE_FDIRM_DIPv6 0x00000020 #define IXGBE_FDIRFREE_FREE_MASK 0xFFFF #define IXGBE_FDIRFREE_FREE_SHIFT 0 @@ -2216,6 +2289,7 @@ #define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400 #define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800 #define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000 +#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000 /* Software ATR hash keys */ #define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D @@ -2257,6 +2331,26 @@ u8 byte_stream[42]; }; +struct ixgbe_atr_input_masks { + u32 src_ip_mask; + u32 dst_ip_mask; + u16 src_port_mask; + u16 dst_port_mask; + u16 vlan_id_mask; + u16 data_mask; +}; + +/* + * Unavailable: The FCoE Boot Option ROM is not present in the flash. + * Disabled: Present; boot order is not set for any targets on the port. + * Enabled: Present; boot order is set for at least one target on the port. + */ +enum ixgbe_fcoe_boot_status { + ixgbe_fcoe_bootstatus_disabled = 0, + ixgbe_fcoe_bootstatus_enabled = 1, + ixgbe_fcoe_bootstatus_unavailable = 0xFFFF +}; + enum ixgbe_eeprom_type { ixgbe_eeprom_uninitialized = 0, ixgbe_eeprom_spi, @@ -2280,10 +2374,12 @@ ixgbe_phy_qt, ixgbe_phy_xaui, ixgbe_phy_nl, - ixgbe_phy_tw_tyco, - ixgbe_phy_tw_unknown, + ixgbe_phy_sfp_passive_tyco, + ixgbe_phy_sfp_passive_unknown, + ixgbe_phy_sfp_active_unknown, ixgbe_phy_sfp_avago, ixgbe_phy_sfp_ftl, + ixgbe_phy_sfp_ftl_active, ixgbe_phy_sfp_unknown, ixgbe_phy_sfp_intel, ixgbe_phy_sfp_unsupported, /* Enforce bit set with unsupported module */ @@ -2311,6 +2407,10 @@ ixgbe_sfp_type_da_cu_core1 = 4, ixgbe_sfp_type_srlr_core0 = 5, ixgbe_sfp_type_srlr_core1 = 6, + ixgbe_sfp_type_da_act_lmt_core0 = 7, + ixgbe_sfp_type_da_act_lmt_core1 = 8, + ixgbe_sfp_type_1g_cu_core0 = 9, + ixgbe_sfp_type_1g_cu_core1 = 10, ixgbe_sfp_type_not_present = 0xFFFE, ixgbe_sfp_type_unknown = 0xFFFF }; @@ -2353,25 +2453,25 @@ /* PCI bus speeds */ enum ixgbe_bus_speed { ixgbe_bus_speed_unknown = 0, - ixgbe_bus_speed_33, - ixgbe_bus_speed_66, - ixgbe_bus_speed_100, - ixgbe_bus_speed_120, - ixgbe_bus_speed_133, - ixgbe_bus_speed_2500, - ixgbe_bus_speed_5000, + ixgbe_bus_speed_33 = 33, + ixgbe_bus_speed_66 = 66, + ixgbe_bus_speed_100 = 100, + ixgbe_bus_speed_120 = 120, + ixgbe_bus_speed_133 = 133, + ixgbe_bus_speed_2500 = 2500, + ixgbe_bus_speed_5000 = 5000, ixgbe_bus_speed_reserved }; /* PCI bus widths */ enum ixgbe_bus_width { ixgbe_bus_width_unknown = 0, - ixgbe_bus_width_pcie_x1, - ixgbe_bus_width_pcie_x2, + ixgbe_bus_width_pcie_x1 = 1, + ixgbe_bus_width_pcie_x2 = 2, ixgbe_bus_width_pcie_x4 = 4, ixgbe_bus_width_pcie_x8 = 8, - ixgbe_bus_width_32, - ixgbe_bus_width_64, + ixgbe_bus_width_32 = 32, + ixgbe_bus_width_64 = 64, ixgbe_bus_width_reserved }; @@ -2457,8 +2557,6 @@ u64 mptc; u64 bptc; u64 xec; - u64 rqsmr[16]; - u64 tqsmr[8]; u64 qprc[16]; u64 qptc[16]; u64 qbrc[16]; @@ -2510,6 +2608,7 @@ s32 (*set_san_mac_addr)(struct ixgbe_hw *, u8 *); s32 (*get_device_caps)(struct ixgbe_hw *, u16 *); s32 (*get_wwn_prefix)(struct ixgbe_hw *, u16 *, u16 *); + s32 (*get_fcoe_boot_status)(struct ixgbe_hw *, u16 *); s32 (*stop_adapter)(struct ixgbe_hw *); s32 (*get_bus_info)(struct ixgbe_hw *); void (*set_lan_id)(struct ixgbe_hw *); @@ -2521,6 +2620,9 @@ void (*release_swfw_sync)(struct ixgbe_hw *, u16); /* Link */ + void (*disable_tx_laser)(struct ixgbe_hw *); + void (*enable_tx_laser)(struct ixgbe_hw *); + void (*flap_tx_laser)(struct ixgbe_hw *); s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool); s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, @@ -2570,6 +2672,7 @@ s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8, u8 *); s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); void (*i2c_bus_clear)(struct ixgbe_hw *); + s32 (*check_overtemp)(struct ixgbe_hw *); }; struct ixgbe_eeprom_info { @@ -2591,6 +2694,8 @@ u16 wwnn_prefix; /* prefix for World Wide Port Name (WWPN) */ u16 wwpn_prefix; +#define IXGBE_MAX_MTA 128 + u32 mta_shadow[IXGBE_MAX_MTA]; s32 mc_filter_type; u32 mcft_size; u32 vft_size; @@ -2621,6 +2726,7 @@ enum ixgbe_smart_speed smart_speed; bool smart_speed_active; bool multispeed_fiber; + bool reset_if_overtemp; }; struct ixgbe_hw { @@ -2670,11 +2776,17 @@ #define IXGBE_ERR_FDIR_REINIT_FAILED -23 #define IXGBE_ERR_EEPROM_VERSION -24 #define IXGBE_ERR_NO_SPACE -25 -#define IXGBE_ERR_INVALID_INTERRUPT -26 +#define IXGBE_ERR_OVERTEMP -26 +#define IXGBE_ERR_FC_NOT_NEGOTIATED -27 +#define IXGBE_ERR_FC_NOT_SUPPORTED -28 +#define IXGBE_ERR_FLOW_CONTROL -29 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #ifndef UNREFERENCED_PARAMETER #define UNREFERENCED_PARAMETER(_p) (_p); +#define UNREFERENCED_2PARAMETER(_p, _q) (_p); (_q); +#define UNREFERENCED_3PARAMETER(_p, _q, _r) (_p); (_q); (_r); +#define UNREFERENCED_4PARAMETER(_p, _q, _r, _s) (_p); (_q); (_r); (_s); #endif #endif /* _IXGBE_TYPE_H */