summaryrefslogtreecommitdiffstats
path: root/sys/dev/ixgbe/ixgbe_phy.c
diff options
context:
space:
mode:
authorjfv <jfv@FreeBSD.org>2010-11-26 22:46:32 +0000
committerjfv <jfv@FreeBSD.org>2010-11-26 22:46:32 +0000
commit48bbd73f9a053707dcc36c64c6f44045e8178dc3 (patch)
treee2b66ea0565164dc8a27eec1d115e996508a5c83 /sys/dev/ixgbe/ixgbe_phy.c
parentdfd9c1b97641876cc379f1deb217b1d89114b6ff (diff)
downloadFreeBSD-src-48bbd73f9a053707dcc36c64c6f44045e8178dc3.zip
FreeBSD-src-48bbd73f9a053707dcc36c64c6f44045e8178dc3.tar.gz
Update ixgbe driver to verion 2.3.6
- This adds a VM SRIOV interface, ixv, it is however transparent to the user, it links with the ixgbe.ko, but when ixgbe is loaded in a virtualized guest with SRIOV configured this will be detected. - Sync shared code to latest - Many bug fixes and improvements, thanks to everyone who has been using the driver and reporting issues.
Diffstat (limited to 'sys/dev/ixgbe/ixgbe_phy.c')
-rw-r--r--sys/dev/ixgbe/ixgbe_phy.c175
1 files changed, 105 insertions, 70 deletions
diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c
index 7ec2981..a2e3e38 100644
--- a/sys/dev/ixgbe/ixgbe_phy.c
+++ b/sys/dev/ixgbe/ixgbe_phy.c
@@ -78,7 +78,6 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
phy->ops.identify_sfp = &ixgbe_identify_sfp_module_generic;
phy->sfp_type = ixgbe_sfp_type_unknown;
phy->ops.check_overtemp = &ixgbe_tn_check_overtemp;
- phy->ops.set_low_power_state = &ixgbe_tn_set_low_power_state;
return IXGBE_SUCCESS;
}
@@ -110,9 +109,8 @@ s32 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
@@ -124,6 +122,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
break;
}
}
+ /* clear value if nothing found */
if (status != IXGBE_SUCCESS)
hw->phy.addr = 0;
} else {
@@ -234,6 +233,11 @@ s32 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
@@ -460,10 +464,10 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 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.
**/
s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
{
@@ -774,7 +778,6 @@ s32 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
@@ -794,7 +797,6 @@ s32 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
@@ -938,20 +940,16 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
hw->phy.sfp_type = ixgbe_sfp_type_not_present;
status = IXGBE_ERR_SFP_NOT_PRESENT;
goto out;
- }
+ }
- status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
+ 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);
@@ -960,12 +958,31 @@ s32 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);
+ 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
* =========
@@ -978,6 +995,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
* 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)
@@ -1001,25 +1020,33 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
hw, IXGBE_SFF_CABLE_SPEC_COMP,
&cable_spec);
if (cable_spec &
- IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
+ 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
+ } else {
hw->phy.sfp_type =
- ixgbe_sfp_type_unknown;
+ ixgbe_sfp_type_unknown;
+ }
} else if (comp_codes_10g &
(IXGBE_SFF_10GBASESR_CAPABLE |
- IXGBE_SFF_10GBASELR_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_1g & IXGBE_SFF_1GBASET_CAPABLE) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_cu_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_cu_core1;
} else {
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
}
@@ -1039,20 +1066,37 @@ s32 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:
@@ -1092,8 +1136,10 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
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;
@@ -1106,7 +1152,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
}
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;
@@ -1122,6 +1170,14 @@ s32 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;
}
/**
@@ -1152,10 +1208,15 @@ s32 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 must be initialized as SR modules */
- if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0)
+ /*
+ * 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)
+ 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 */
@@ -1259,7 +1320,6 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 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;
@@ -1472,7 +1532,7 @@ static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *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;
@@ -1761,7 +1821,7 @@ void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
}
/**
- * ixgbe_check_overtemp - Checks if an overtemp occured.
+ * 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
@@ -1787,28 +1847,3 @@ s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
out:
return status;
}
-
-
-/**
- * ixgbe_set_tn_low_power_state - Sets the teranetics phy into low power state
- * @hw: pointer to hardware structure
- *
- * Sets the phy into low power mode when LASI temp alarm status is triggered
- **/
-s32 ixgbe_tn_set_low_power_state(struct ixgbe_hw *hw)
-{
- s32 status = IXGBE_SUCCESS;
- u16 phy_data = 0;
-
- DEBUGFUNC("ixgbe_set_tn_low_power_state");
-
- /* Set the phy into low power mode */
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_CONTROL_ADDR,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data);
- phy_data |= IXGBE_MDIO_PHY_LOW_POWER_MODE;
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_PMD_CONTROL_ADDR,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, phy_data);
-
- return status;
-}
-
OpenPOWER on IntegriCloud