Skip to content

Commit 117df65

Browse files
tlendackydavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 96f4d43 commit 117df65

File tree

1 file changed

+54
-17
lines changed

1 file changed

+54
-17
lines changed

drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ enum xgbe_sfp_speed {
253253
#define XGBE_SFP_BASE_VENDOR_SN 4
254254
#define XGBE_SFP_BASE_VENDOR_SN_LEN 16
255255

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+
256260
#define XGBE_SFP_EXTD_DIAG 28
257261
#define XGBE_SFP_EXTD_DIAG_ADDR_CHANGE BIT(2)
258262

@@ -332,6 +336,7 @@ struct xgbe_phy_data {
332336

333337
unsigned int sfp_gpio_address;
334338
unsigned int sfp_gpio_mask;
339+
unsigned int sfp_gpio_inputs;
335340
unsigned int sfp_gpio_rx_los;
336341
unsigned int sfp_gpio_tx_fault;
337342
unsigned int sfp_gpio_mod_absent;
@@ -986,6 +991,49 @@ static void xgbe_phy_sfp_external_phy(struct xgbe_prv_data *pdata)
986991
phy_data->sfp_phy_avail = 1;
987992
}
988993

994+
static 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+
1010+
static 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+
1026+
static 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+
9891037
static bool xgbe_phy_belfuse_parse_quirks(struct xgbe_prv_data *pdata)
9901038
{
9911039
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)
10311079
if (sfp_base[XGBE_SFP_BASE_EXT_ID] != XGBE_SFP_EXT_ID_SFP)
10321080
return;
10331081

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+
10341086
if (xgbe_phy_sfp_parse_quirks(pdata))
10351087
return;
10361088

@@ -1196,7 +1248,6 @@ static int xgbe_phy_sfp_read_eeprom(struct xgbe_prv_data *pdata)
11961248
static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
11971249
{
11981250
struct xgbe_phy_data *phy_data = pdata->phy_data;
1199-
unsigned int gpio_input;
12001251
u8 gpio_reg, gpio_ports[2];
12011252
int ret;
12021253

@@ -1211,23 +1262,9 @@ static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
12111262
return;
12121263
}
12131264

1214-
gpio_input = (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;
1265+
phy_data->sfp_gpio_inputs = (gpio_ports[1] << 8) | gpio_ports[0];
12271266

1228-
if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT) &&
1229-
(gpio_input & (1 << phy_data->sfp_gpio_tx_fault)))
1230-
phy_data->sfp_tx_fault = 1;
1267+
phy_data->sfp_mod_absent = xgbe_phy_check_sfp_mod_absent(phy_data);
12311268
}
12321269

12331270
static void xgbe_phy_sfp_mod_absent(struct xgbe_prv_data *pdata)

0 commit comments

Comments
 (0)