aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTom Lendacky <thomas.lendacky@amd.com>2018-04-23 12:43:34 -0400
committerDavid S. Miller <davem@davemloft.net>2018-04-23 21:24:22 -0400
commit117df655f8ed51adb6e6b163812a06ebeae9f453 (patch)
treedd2873463ce6a30e76bfac45dd2bc6c9ef74b253 /drivers
parent96f4d430c507ed4856048c2dc9c1a2ea5b5e74e4 (diff)
amd-xgbe: Only use the SFP supported transceiver signals
The SFP eeprom indicates the transceiver signals (Rx LOS, Tx Fault, etc.) that it supports. Update the driver to include checking the eeprom data when deciding whether to use a transceiver signal. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
index b48efc04c4da..aac884314000 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
@@ -253,6 +253,10 @@ enum xgbe_sfp_speed {
253#define XGBE_SFP_BASE_VENDOR_SN 4 253#define XGBE_SFP_BASE_VENDOR_SN 4
254#define XGBE_SFP_BASE_VENDOR_SN_LEN 16 254#define XGBE_SFP_BASE_VENDOR_SN_LEN 16
255 255
256#define XGBE_SFP_EXTD_OPT1 1
257#define XGBE_SFP_EXTD_OPT1_RX_LOS BIT(1)
258#define XGBE_SFP_EXTD_OPT1_TX_FAULT BIT(3)
259
256#define XGBE_SFP_EXTD_DIAG 28 260#define XGBE_SFP_EXTD_DIAG 28
257#define XGBE_SFP_EXTD_DIAG_ADDR_CHANGE BIT(2) 261#define XGBE_SFP_EXTD_DIAG_ADDR_CHANGE BIT(2)
258 262
@@ -332,6 +336,7 @@ struct xgbe_phy_data {
332 336
333 unsigned int sfp_gpio_address; 337 unsigned int sfp_gpio_address;
334 unsigned int sfp_gpio_mask; 338 unsigned int sfp_gpio_mask;
339 unsigned int sfp_gpio_inputs;
335 unsigned int sfp_gpio_rx_los; 340 unsigned int sfp_gpio_rx_los;
336 unsigned int sfp_gpio_tx_fault; 341 unsigned int sfp_gpio_tx_fault;
337 unsigned int sfp_gpio_mod_absent; 342 unsigned int sfp_gpio_mod_absent;
@@ -986,6 +991,49 @@ static void xgbe_phy_sfp_external_phy(struct xgbe_prv_data *pdata)
986 phy_data->sfp_phy_avail = 1; 991 phy_data->sfp_phy_avail = 1;
987} 992}
988 993
994static bool xgbe_phy_check_sfp_rx_los(struct xgbe_phy_data *phy_data)
995{
996 u8 *sfp_extd = phy_data->sfp_eeprom.extd;
997
998 if (!(sfp_extd[XGBE_SFP_EXTD_OPT1] & XGBE_SFP_EXTD_OPT1_RX_LOS))
999 return false;
1000
1001 if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS)
1002 return false;
1003
1004 if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_rx_los))
1005 return true;
1006
1007 return false;
1008}
1009
1010static bool xgbe_phy_check_sfp_tx_fault(struct xgbe_phy_data *phy_data)
1011{
1012 u8 *sfp_extd = phy_data->sfp_eeprom.extd;
1013
1014 if (!(sfp_extd[XGBE_SFP_EXTD_OPT1] & XGBE_SFP_EXTD_OPT1_TX_FAULT))
1015 return false;
1016
1017 if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT)
1018 return false;
1019
1020 if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_tx_fault))
1021 return true;
1022
1023 return false;
1024}
1025
1026static bool xgbe_phy_check_sfp_mod_absent(struct xgbe_phy_data *phy_data)
1027{
1028 if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT)
1029 return false;
1030
1031 if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_mod_absent))
1032 return true;
1033
1034 return false;
1035}
1036
989static bool xgbe_phy_belfuse_parse_quirks(struct xgbe_prv_data *pdata) 1037static bool xgbe_phy_belfuse_parse_quirks(struct xgbe_prv_data *pdata)
990{ 1038{
991 struct xgbe_phy_data *phy_data = pdata->phy_data; 1039 struct xgbe_phy_data *phy_data = pdata->phy_data;
@@ -1031,6 +1079,10 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
1031 if (sfp_base[XGBE_SFP_BASE_EXT_ID] != XGBE_SFP_EXT_ID_SFP) 1079 if (sfp_base[XGBE_SFP_BASE_EXT_ID] != XGBE_SFP_EXT_ID_SFP)
1032 return; 1080 return;
1033 1081
1082 /* Update transceiver signals (eeprom extd/options) */
1083 phy_data->sfp_tx_fault = xgbe_phy_check_sfp_tx_fault(phy_data);
1084 phy_data->sfp_rx_los = xgbe_phy_check_sfp_rx_los(phy_data);
1085
1034 if (xgbe_phy_sfp_parse_quirks(pdata)) 1086 if (xgbe_phy_sfp_parse_quirks(pdata))
1035 return; 1087 return;
1036 1088
@@ -1196,7 +1248,6 @@ put:
1196static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata) 1248static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
1197{ 1249{
1198 struct xgbe_phy_data *phy_data = pdata->phy_data; 1250 struct xgbe_phy_data *phy_data = pdata->phy_data;
1199 unsigned int gpio_input;
1200 u8 gpio_reg, gpio_ports[2]; 1251 u8 gpio_reg, gpio_ports[2];
1201 int ret; 1252 int ret;
1202 1253
@@ -1211,23 +1262,9 @@ static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
1211 return; 1262 return;
1212 } 1263 }
1213 1264
1214 gpio_input = (gpio_ports[1] << 8) | gpio_ports[0]; 1265 phy_data->sfp_gpio_inputs = (gpio_ports[1] << 8) | gpio_ports[0];
1215
1216 if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT) {
1217 /* No GPIO, just assume the module is present for now */
1218 phy_data->sfp_mod_absent = 0;
1219 } else {
1220 if (!(gpio_input & (1 << phy_data->sfp_gpio_mod_absent)))
1221 phy_data->sfp_mod_absent = 0;
1222 }
1223
1224 if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS) &&
1225 (gpio_input & (1 << phy_data->sfp_gpio_rx_los)))
1226 phy_data->sfp_rx_los = 1;
1227 1266
1228 if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT) && 1267 phy_data->sfp_mod_absent = xgbe_phy_check_sfp_mod_absent(phy_data);
1229 (gpio_input & (1 << phy_data->sfp_gpio_tx_fault)))
1230 phy_data->sfp_tx_fault = 1;
1231} 1268}
1232 1269
1233static void xgbe_phy_sfp_mod_absent(struct xgbe_prv_data *pdata) 1270static void xgbe_phy_sfp_mod_absent(struct xgbe_prv_data *pdata)