aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmil Tantilov <emil.s.tantilov@intel.com>2011-02-19 03:43:55 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-03-03 07:29:51 -0500
commit75f19c3c5eeb67d37ce96e0ea78dc0beb485a723 (patch)
tree117ae9d67f85495acc183d57f7a52f4992abd908
parent278675d855e03e111ca84fec6eb7d5569e56c394 (diff)
ixgbe: cleanup handling of I2C interface to PHY
The I2C interface was not being correctly locked down per port. As such this can lead to race conditions that can cause issues. This patch cleans up the handling to make certain we are not experiencing racy I2C access. Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com> Tested-by: Stephen Ko <stephen.s.ko@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index ebd6e4492a3f..16b5f499b6b8 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -858,6 +858,9 @@ err_read_i2c_eeprom:
858 * @hw: pointer to hardware structure 858 * @hw: pointer to hardware structure
859 * @list_offset: offset to the SFP ID list 859 * @list_offset: offset to the SFP ID list
860 * @data_offset: offset to the SFP data block 860 * @data_offset: offset to the SFP data block
861 *
862 * Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if
863 * so it returns the offsets to the phy init sequence block.
861 **/ 864 **/
862s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, 865s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
863 u16 *list_offset, 866 u16 *list_offset,
@@ -972,11 +975,22 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
972 u8 dev_addr, u8 *data) 975 u8 dev_addr, u8 *data)
973{ 976{
974 s32 status = 0; 977 s32 status = 0;
975 u32 max_retry = 1; 978 u32 max_retry = 10;
976 u32 retry = 0; 979 u32 retry = 0;
980 u16 swfw_mask = 0;
977 bool nack = 1; 981 bool nack = 1;
978 982
983 if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
984 swfw_mask = IXGBE_GSSR_PHY1_SM;
985 else
986 swfw_mask = IXGBE_GSSR_PHY0_SM;
987
979 do { 988 do {
989 if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) {
990 status = IXGBE_ERR_SWFW_SYNC;
991 goto read_byte_out;
992 }
993
980 ixgbe_i2c_start(hw); 994 ixgbe_i2c_start(hw);
981 995
982 /* Device Address and write indication */ 996 /* Device Address and write indication */
@@ -1019,6 +1033,8 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
1019 break; 1033 break;
1020 1034
1021fail: 1035fail:
1036 ixgbe_release_swfw_sync(hw, swfw_mask);
1037 msleep(100);
1022 ixgbe_i2c_bus_clear(hw); 1038 ixgbe_i2c_bus_clear(hw);
1023 retry++; 1039 retry++;
1024 if (retry < max_retry) 1040 if (retry < max_retry)
@@ -1028,6 +1044,9 @@ fail:
1028 1044
1029 } while (retry < max_retry); 1045 } while (retry < max_retry);
1030 1046
1047 ixgbe_release_swfw_sync(hw, swfw_mask);
1048
1049read_byte_out:
1031 return status; 1050 return status;
1032} 1051}
1033 1052
@@ -1046,6 +1065,17 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
1046 s32 status = 0; 1065 s32 status = 0;
1047 u32 max_retry = 1; 1066 u32 max_retry = 1;
1048 u32 retry = 0; 1067 u32 retry = 0;
1068 u16 swfw_mask = 0;
1069
1070 if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
1071 swfw_mask = IXGBE_GSSR_PHY1_SM;
1072 else
1073 swfw_mask = IXGBE_GSSR_PHY0_SM;
1074
1075 if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) {
1076 status = IXGBE_ERR_SWFW_SYNC;
1077 goto write_byte_out;
1078 }
1049 1079
1050 do { 1080 do {
1051 ixgbe_i2c_start(hw); 1081 ixgbe_i2c_start(hw);
@@ -1086,6 +1116,9 @@ fail:
1086 hw_dbg(hw, "I2C byte write error.\n"); 1116 hw_dbg(hw, "I2C byte write error.\n");
1087 } while (retry < max_retry); 1117 } while (retry < max_retry);
1088 1118
1119 ixgbe_release_swfw_sync(hw, swfw_mask);
1120
1121write_byte_out:
1089 return status; 1122 return status;
1090} 1123}
1091 1124
@@ -1404,6 +1437,8 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
1404 u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); 1437 u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
1405 u32 i; 1438 u32 i;
1406 1439
1440 ixgbe_i2c_start(hw);
1441
1407 ixgbe_set_i2c_data(hw, &i2cctl, 1); 1442 ixgbe_set_i2c_data(hw, &i2cctl, 1);
1408 1443
1409 for (i = 0; i < 9; i++) { 1444 for (i = 0; i < 9; i++) {
@@ -1418,6 +1453,8 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
1418 udelay(IXGBE_I2C_T_LOW); 1453 udelay(IXGBE_I2C_T_LOW);
1419 } 1454 }
1420 1455
1456 ixgbe_i2c_start(hw);
1457
1421 /* Put the i2c bus back to default state */ 1458 /* Put the i2c bus back to default state */
1422 ixgbe_i2c_stop(hw); 1459 ixgbe_i2c_stop(hw);
1423} 1460}