summaryrefslogtreecommitdiff
path: root/sys/dev/pci/ixgbe_phy.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2011-06-10 12:46:36 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2011-06-10 12:46:36 +0000
commitede3ae71faaa64d8a260366efbfa6669a1a8898a (patch)
tree19da36ebabdeb9dfc35c109712cf84715463ca39 /sys/dev/pci/ixgbe_phy.c
parent1067402c5d83af16fa9c9f95adef20db70eff0e3 (diff)
Monster update of ix(4). This brings ix(4) close to what is currently
in FreeBSD. This seems to fix a lot of problems on 82599 based cards including the VLAN problems and the corrupted receives. Putting this in now to work on it in tree since a few additional things need to be merged. Tested by myself, deraadt@ and jsg@ on both 98er and 99er cards. OK jsg@, deraadt@
Diffstat (limited to 'sys/dev/pci/ixgbe_phy.c')
-rw-r--r--sys/dev/pci/ixgbe_phy.c247
1 files changed, 185 insertions, 62 deletions
diff --git a/sys/dev/pci/ixgbe_phy.c b/sys/dev/pci/ixgbe_phy.c
index c859aef86f1..7bfcd7ff9b7 100644
--- a/sys/dev/pci/ixgbe_phy.c
+++ b/sys/dev/pci/ixgbe_phy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ixgbe_phy.c,v 1.5 2010/09/21 00:29:29 claudio Exp $ */
+/* $OpenBSD: ixgbe_phy.c,v 1.6 2011/06/10 12:46:35 claudio Exp $ */
/******************************************************************************
@@ -75,7 +75,7 @@ int32_t ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
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;
}
@@ -105,9 +105,8 @@ int32_t ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
IXGBE_MDIO_PMA_PMD_DEV_TYPE,
&ext_ability);
if (ext_ability &
- IXGBE_MDIO_PHY_10GBASET_ABILITY ||
- ext_ability &
- IXGBE_MDIO_PHY_1000BASET_ABILITY)
+ (IXGBE_MDIO_PHY_10GBASET_ABILITY |
+ IXGBE_MDIO_PHY_1000BASET_ABILITY))
hw->phy.type =
ixgbe_phy_cu_unknown;
else
@@ -119,6 +118,7 @@ int32_t ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
break;
}
}
+ /* clear value if nothing found */
if (status != IXGBE_SUCCESS)
hw->phy.addr = 0;
} else {
@@ -221,6 +221,11 @@ int32_t ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
if (status != IXGBE_SUCCESS || hw->phy.type == ixgbe_phy_none)
goto out;
+ /* Don't reset PHY if it's shut down due to overtemp. */
+ if (!hw->phy.reset_if_overtemp &&
+ (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
+ goto out;
+
/*
* Perform soft PHY reset to the PHY_XS.
* This will cause a soft reset to the PHY
@@ -229,13 +234,19 @@ int32_t ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
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) {
@@ -289,9 +300,8 @@ int32_t ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, uint32_t reg_addr,
command = IXGBE_READ_REG(hw, IXGBE_MSCA);
- if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
+ if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
break;
- }
}
if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
@@ -438,10 +448,10 @@ int32_t ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, uint32_t reg_addr,
}
/**
- * ixgbe_setup_phy_link_generic - Set and restart autoneg
- * @hw: pointer to hardware structure
+ * ixgbe_setup_phy_link_generic - Set and restart autoneg
+ * @hw: pointer to hardware structure
*
- * Restart autonegotiation and PHY and waits for completion.
+ * Restart autonegotiation and PHY and waits for completion.
**/
int32_t ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
{
@@ -520,12 +530,15 @@ int32_t ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
&autoneg_reg);
autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
- if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE)
+ if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) {
break;
+ }
}
- if (time_out == max_time_out)
+ if (time_out == max_time_out) {
status = IXGBE_ERR_LINK_SETUP;
+ DEBUGOUT("ixgbe_setup_phy_link_generic: time out");
+ }
return status;
}
@@ -727,8 +740,9 @@ int32_t ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
&autoneg_reg);
autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
- if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE)
+ if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) {
break;
+ }
}
if (time_out == max_time_out) {
@@ -739,7 +753,6 @@ int32_t ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
return status;
}
-
/**
* ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
* @hw: pointer to hardware structure
@@ -757,7 +770,6 @@ int32_t ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
return status;
}
-
/**
* ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version
* @hw: pointer to hardware structure
@@ -888,6 +900,7 @@ int32_t ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
uint8_t comp_codes_10g = 0;
uint8_t oui_bytes[3] = {0, 0, 0};
uint8_t cable_tech = 0;
+ uint8_t cable_spec = 0;
uint16_t enforce_sfp = 0;
if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) {
@@ -900,15 +913,10 @@ int32_t ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
&identifier);
- if (status == IXGBE_ERR_SFP_NOT_PRESENT || status == IXGBE_ERR_I2C) {
- status = IXGBE_ERR_SFP_NOT_PRESENT;
- hw->phy.sfp_type = ixgbe_sfp_type_not_present;
- if (hw->phy.type != ixgbe_phy_nl) {
- hw->phy.id = 0;
- hw->phy.type = ixgbe_phy_unknown;
- }
- goto out;
- }
+ if (status == IXGBE_ERR_SWFW_SYNC ||
+ status == IXGBE_ERR_I2C ||
+ status == IXGBE_ERR_SFP_NOT_PRESENT)
+ goto err_read_i2c_eeprom;
/* LAN ID is needed for sfp_type determination */
hw->mac.ops.set_lan_id(hw);
@@ -917,15 +925,31 @@ int32_t ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
hw->phy.type = ixgbe_phy_sfp_unsupported;
status = IXGBE_ERR_SFP_NOT_SUPPORTED;
} else {
- 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);
- hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_CABLE_TECHNOLOGY,
- &cable_tech);
-
- DEBUGOUT3("SFP+ capa codes 1G %x 10G %x cable %x\n",
- comp_codes_1g, comp_codes_10g, cable_tech);
+ status = hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_1GBE_COMP_CODES,
+ &comp_codes_1g);
+
+ if (status == IXGBE_ERR_SWFW_SYNC ||
+ status == IXGBE_ERR_I2C ||
+ status == IXGBE_ERR_SFP_NOT_PRESENT)
+ goto err_read_i2c_eeprom;
+
+ status = hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_10GBE_COMP_CODES,
+ &comp_codes_10g);
+
+ if (status == IXGBE_ERR_SWFW_SYNC ||
+ status == IXGBE_ERR_I2C ||
+ status == IXGBE_ERR_SFP_NOT_PRESENT)
+ goto err_read_i2c_eeprom;
+ status = hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_CABLE_TECHNOLOGY,
+ &cable_tech);
+
+ if (status == IXGBE_ERR_SWFW_SYNC ||
+ status == IXGBE_ERR_I2C ||
+ status == IXGBE_ERR_SFP_NOT_PRESENT)
+ goto err_read_i2c_eeprom;
/* ID Module
* =========
@@ -936,6 +960,10 @@ int32_t ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
* 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)
@@ -949,29 +977,48 @@ int32_t ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
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)
@@ -988,28 +1035,49 @@ int32_t ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
/* Determine PHY vendor */
if (hw->phy.type != ixgbe_phy_nl) {
hw->phy.id = identifier;
- hw->phy.ops.read_i2c_eeprom(hw,
+ status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_VENDOR_OUI_BYTE0,
&oui_bytes[0]);
- hw->phy.ops.read_i2c_eeprom(hw,
+
+ if (status == IXGBE_ERR_SWFW_SYNC ||
+ status == IXGBE_ERR_I2C ||
+ status == IXGBE_ERR_SFP_NOT_PRESENT)
+ goto err_read_i2c_eeprom;
+
+ status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_VENDOR_OUI_BYTE1,
&oui_bytes[1]);
- hw->phy.ops.read_i2c_eeprom(hw,
+
+ if (status == IXGBE_ERR_SWFW_SYNC ||
+ status == IXGBE_ERR_I2C ||
+ status == IXGBE_ERR_SFP_NOT_PRESENT)
+ goto err_read_i2c_eeprom;
+
+ status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_VENDOR_OUI_BYTE2,
&oui_bytes[2]);
+ if (status == IXGBE_ERR_SWFW_SYNC ||
+ status == IXGBE_ERR_I2C ||
+ status == IXGBE_ERR_SFP_NOT_PRESENT)
+ goto err_read_i2c_eeprom;
+
vendor_oui =
- ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
- (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
- (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
+ ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
+ (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
+ (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
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;
@@ -1019,21 +1087,28 @@ int32_t ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
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 supported 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;
@@ -1048,7 +1123,9 @@ int32_t ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
/* unimplemented even in the intel driver */
/* ixgbe_get_device_caps(hw, &enforce_sfp); */
enforce_sfp = IXGBE_DEVICE_CAPS_ALLOW_ANY_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;
@@ -1065,6 +1142,14 @@ int32_t ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
out:
return status;
+
+err_read_i2c_eeprom:
+ hw->phy.sfp_type = ixgbe_sfp_type_not_present;
+ if (hw->phy.type != ixgbe_phy_nl) {
+ hw->phy.id = 0;
+ hw->phy.type = ixgbe_phy_unknown;
+ }
+ return IXGBE_ERR_SFP_NOT_PRESENT;
}
/**
@@ -1081,6 +1166,7 @@ int32_t ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
uint16_t *data_offset)
{
uint16_t sfp_id;
+ uint16_t sfp_type = hw->phy.sfp_type;
if (hw->phy.sfp_type == ixgbe_sfp_type_unknown)
return IXGBE_ERR_SFP_NOT_SUPPORTED;
@@ -1092,6 +1178,17 @@ int32_t ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
(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);
@@ -1108,7 +1205,7 @@ int32_t ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
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)) {
@@ -1135,9 +1232,10 @@ int32_t ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
(*list_offset) += 2;
hw->eeprom.ops.read(hw, *list_offset, data_offset);
- } else if (sfp_id == IXGBE_PHY_INIT_END_NL)
+ } else if (sfp_id == IXGBE_PHY_INIT_END_NL) {
+ DEBUGOUT("No matching SFP+ module found\n");
return IXGBE_ERR_SFP_NOT_SUPPORTED;
-
+ }
return IXGBE_SUCCESS;
}
@@ -1196,7 +1294,6 @@ int32_t ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, uint8_t byte_offset,
else
swfw_mask = IXGBE_GSSR_PHY0_SM;
-
do {
if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != IXGBE_SUCCESS) {
status = IXGBE_ERR_SWFW_SYNC;
@@ -1401,7 +1498,7 @@ int32_t ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, uint8_t *data)
for (i = 7; i >= 0; i--) {
status = ixgbe_clock_in_i2c_bit(hw, &bit);
- *data |= bit<<i;
+ *data |= bit << i;
if (status != IXGBE_SUCCESS)
break;
@@ -1670,3 +1767,29 @@ void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
/* 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
+ **/
+int32_t ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
+{
+ int32_t status = IXGBE_SUCCESS;
+ uint16_t phy_data = 0;
+
+ 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;
+}