Skip to content

Commit abf0a1c

Browse files
tlendackydavem330
authored andcommitted
amd-xgbe: Add support for SFP+ modules
Add support for recognizing and using SFP+ modules directly. This includes using the I2C support to read and interpret the information returned from an SFP+ module and configuring things properly. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 372788f commit abf0a1c

File tree

6 files changed

+1652
-18
lines changed

6 files changed

+1652
-18
lines changed

drivers/net/ethernet/amd/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ config AMD_XGBE
178178
select BITREVERSE
179179
select CRC32
180180
select PTP_1588_CLOCK
181+
select PHYLIB
181182
select AMD_XGBE_HAVE_ECC if X86
182183
---help---
183184
This driver supports the AMD 10GbE Ethernet device found on an

drivers/net/ethernet/amd/xgbe/xgbe-common.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,8 @@
929929
#define XP_DRIVER_SCRATCH_0 0x0068
930930
#define XP_DRIVER_SCRATCH_1 0x006c
931931
#define XP_INT_EN 0x0078
932+
#define XP_I2C_MUTEX 0x0080
933+
#define XP_MDIO_MUTEX 0x0084
932934

933935
/* MAC Control register entry bit positions and sizes */
934936
#define XP_DRIVER_INT_REQ_REQUEST_INDEX 0
@@ -975,6 +977,12 @@
975977
#define XP_ECC_ISR_TX_DED_WIDTH 1
976978
#define XP_ECC_ISR_TX_SEC_INDEX 5
977979
#define XP_ECC_ISR_TX_SEC_WIDTH 1
980+
#define XP_I2C_MUTEX_BUSY_INDEX 31
981+
#define XP_I2C_MUTEX_BUSY_WIDTH 1
982+
#define XP_I2C_MUTEX_ID_INDEX 29
983+
#define XP_I2C_MUTEX_ID_WIDTH 2
984+
#define XP_I2C_MUTEX_ACTIVE_INDEX 0
985+
#define XP_I2C_MUTEX_ACTIVE_WIDTH 1
978986
#define XP_MAC_ADDR_HI_VALID_INDEX 31
979987
#define XP_MAC_ADDR_HI_VALID_WIDTH 1
980988
#define XP_PROP_0_CONN_TYPE_INDEX 28
@@ -999,6 +1007,24 @@
9991007
#define XP_PROP_2_RX_FIFO_SIZE_WIDTH 16
10001008
#define XP_PROP_2_TX_FIFO_SIZE_INDEX 0
10011009
#define XP_PROP_2_TX_FIFO_SIZE_WIDTH 16
1010+
#define XP_PROP_3_GPIO_MASK_INDEX 28
1011+
#define XP_PROP_3_GPIO_MASK_WIDTH 4
1012+
#define XP_PROP_3_GPIO_MOD_ABS_INDEX 20
1013+
#define XP_PROP_3_GPIO_MOD_ABS_WIDTH 4
1014+
#define XP_PROP_3_GPIO_RATE_SELECT_INDEX 16
1015+
#define XP_PROP_3_GPIO_RATE_SELECT_WIDTH 4
1016+
#define XP_PROP_3_GPIO_RX_LOS_INDEX 24
1017+
#define XP_PROP_3_GPIO_RX_LOS_WIDTH 4
1018+
#define XP_PROP_3_GPIO_TX_FAULT_INDEX 12
1019+
#define XP_PROP_3_GPIO_TX_FAULT_WIDTH 4
1020+
#define XP_PROP_3_GPIO_ADDR_INDEX 8
1021+
#define XP_PROP_3_GPIO_ADDR_WIDTH 3
1022+
#define XP_PROP_4_MUX_ADDR_HI_INDEX 8
1023+
#define XP_PROP_4_MUX_ADDR_HI_WIDTH 5
1024+
#define XP_PROP_4_MUX_ADDR_LO_INDEX 0
1025+
#define XP_PROP_4_MUX_ADDR_LO_WIDTH 3
1026+
#define XP_PROP_4_MUX_CHAN_INDEX 4
1027+
#define XP_PROP_4_MUX_CHAN_WIDTH 3
10021028

10031029
/* I2C Control register offsets */
10041030
#define IC_CON 0x0000
@@ -1235,6 +1261,14 @@
12351261
#define MDIO_VEND2_CTRL1_AN_RESTART BIT(9)
12361262
#endif
12371263

1264+
#ifndef MDIO_VEND2_CTRL1_SS6
1265+
#define MDIO_VEND2_CTRL1_SS6 BIT(6)
1266+
#endif
1267+
1268+
#ifndef MDIO_VEND2_CTRL1_SS13
1269+
#define MDIO_VEND2_CTRL1_SS13 BIT(13)
1270+
#endif
1271+
12381272
/* MDIO mask values */
12391273
#define XGBE_AN_CL73_INT_CMPLT BIT(0)
12401274
#define XGBE_AN_CL73_INC_LINK BIT(1)

drivers/net/ethernet/amd/xgbe/xgbe-mdio.c

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,54 @@ static void xgbe_kx_1000_mode(struct xgbe_prv_data *pdata)
252252
pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_1000);
253253
}
254254

255+
static void xgbe_sfi_mode(struct xgbe_prv_data *pdata)
256+
{
257+
/* Disable KR training */
258+
xgbe_an73_disable_kr_training(pdata);
259+
260+
/* Set MAC to 10G speed */
261+
pdata->hw_if.set_speed(pdata, SPEED_10000);
262+
263+
/* Call PHY implementation support to complete rate change */
264+
pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SFI);
265+
}
266+
267+
static void xgbe_x_mode(struct xgbe_prv_data *pdata)
268+
{
269+
/* Disable KR training */
270+
xgbe_an73_disable_kr_training(pdata);
271+
272+
/* Set MAC to 1G speed */
273+
pdata->hw_if.set_speed(pdata, SPEED_1000);
274+
275+
/* Call PHY implementation support to complete rate change */
276+
pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_X);
277+
}
278+
279+
static void xgbe_sgmii_1000_mode(struct xgbe_prv_data *pdata)
280+
{
281+
/* Disable KR training */
282+
xgbe_an73_disable_kr_training(pdata);
283+
284+
/* Set MAC to 1G speed */
285+
pdata->hw_if.set_speed(pdata, SPEED_1000);
286+
287+
/* Call PHY implementation support to complete rate change */
288+
pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_1000);
289+
}
290+
291+
static void xgbe_sgmii_100_mode(struct xgbe_prv_data *pdata)
292+
{
293+
/* Disable KR training */
294+
xgbe_an73_disable_kr_training(pdata);
295+
296+
/* Set MAC to 1G speed */
297+
pdata->hw_if.set_speed(pdata, SPEED_1000);
298+
299+
/* Call PHY implementation support to complete rate change */
300+
pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_100);
301+
}
302+
255303
static enum xgbe_mode xgbe_cur_mode(struct xgbe_prv_data *pdata)
256304
{
257305
return pdata->phy_if.phy_impl.cur_mode(pdata);
@@ -275,6 +323,18 @@ static void xgbe_change_mode(struct xgbe_prv_data *pdata,
275323
case XGBE_MODE_KR:
276324
xgbe_kr_mode(pdata);
277325
break;
326+
case XGBE_MODE_SGMII_100:
327+
xgbe_sgmii_100_mode(pdata);
328+
break;
329+
case XGBE_MODE_SGMII_1000:
330+
xgbe_sgmii_1000_mode(pdata);
331+
break;
332+
case XGBE_MODE_X:
333+
xgbe_x_mode(pdata);
334+
break;
335+
case XGBE_MODE_SFI:
336+
xgbe_sfi_mode(pdata);
337+
break;
278338
case XGBE_MODE_UNKNOWN:
279339
break;
280340
default:
@@ -972,6 +1032,8 @@ static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata)
9721032
static const char *xgbe_phy_speed_string(int speed)
9731033
{
9741034
switch (speed) {
1035+
case SPEED_100:
1036+
return "100Mbps";
9751037
case SPEED_1000:
9761038
return "1Gbps";
9771039
case SPEED_2500:
@@ -1057,6 +1119,10 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
10571119
case XGBE_MODE_KX_1000:
10581120
case XGBE_MODE_KX_2500:
10591121
case XGBE_MODE_KR:
1122+
case XGBE_MODE_SGMII_100:
1123+
case XGBE_MODE_SGMII_1000:
1124+
case XGBE_MODE_X:
1125+
case XGBE_MODE_SFI:
10601126
break;
10611127
case XGBE_MODE_UNKNOWN:
10621128
default:
@@ -1074,9 +1140,15 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
10741140

10751141
static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
10761142
{
1143+
int ret;
1144+
10771145
set_bit(XGBE_LINK_INIT, &pdata->dev_state);
10781146
pdata->link_check = jiffies;
10791147

1148+
ret = pdata->phy_if.phy_impl.an_config(pdata);
1149+
if (ret)
1150+
return ret;
1151+
10801152
if (pdata->phy.autoneg != AUTONEG_ENABLE)
10811153
return xgbe_phy_config_fixed(pdata);
10821154

@@ -1092,6 +1164,14 @@ static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
10921164
xgbe_set_mode(pdata, XGBE_MODE_KX_2500);
10931165
} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {
10941166
xgbe_set_mode(pdata, XGBE_MODE_KX_1000);
1167+
} else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {
1168+
xgbe_set_mode(pdata, XGBE_MODE_SFI);
1169+
} else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {
1170+
xgbe_set_mode(pdata, XGBE_MODE_X);
1171+
} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {
1172+
xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000);
1173+
} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
1174+
xgbe_set_mode(pdata, XGBE_MODE_SGMII_100);
10951175
} else {
10961176
enable_irq(pdata->an_irq);
10971177
return -EINVAL;
@@ -1167,13 +1247,19 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata)
11671247
mode = xgbe_phy_status_aneg(pdata);
11681248

11691249
switch (mode) {
1250+
case XGBE_MODE_SGMII_100:
1251+
pdata->phy.speed = SPEED_100;
1252+
break;
1253+
case XGBE_MODE_X:
11701254
case XGBE_MODE_KX_1000:
1255+
case XGBE_MODE_SGMII_1000:
11711256
pdata->phy.speed = SPEED_1000;
11721257
break;
11731258
case XGBE_MODE_KX_2500:
11741259
pdata->phy.speed = SPEED_2500;
11751260
break;
11761261
case XGBE_MODE_KR:
1262+
case XGBE_MODE_SFI:
11771263
pdata->phy.speed = SPEED_10000;
11781264
break;
11791265
case XGBE_MODE_UNKNOWN:
@@ -1189,6 +1275,7 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata)
11891275
static void xgbe_phy_status(struct xgbe_prv_data *pdata)
11901276
{
11911277
unsigned int link_aneg;
1278+
int an_restart;
11921279

11931280
if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) {
11941281
netif_carrier_off(pdata->netdev);
@@ -1199,7 +1286,13 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata)
11991286

12001287
link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);
12011288

1202-
pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata);
1289+
pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
1290+
&an_restart);
1291+
if (an_restart) {
1292+
xgbe_phy_config_aneg(pdata);
1293+
return;
1294+
}
1295+
12031296
if (pdata->phy.link) {
12041297
if (link_aneg && !xgbe_phy_aneg_done(pdata)) {
12051298
xgbe_check_link_timeout(pdata);
@@ -1284,6 +1377,14 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
12841377
xgbe_kx_2500_mode(pdata);
12851378
} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {
12861379
xgbe_kx_1000_mode(pdata);
1380+
} else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {
1381+
xgbe_sfi_mode(pdata);
1382+
} else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {
1383+
xgbe_x_mode(pdata);
1384+
} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {
1385+
xgbe_sgmii_1000_mode(pdata);
1386+
} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
1387+
xgbe_sgmii_100_mode(pdata);
12871388
} else {
12881389
ret = -EINVAL;
12891390
goto err_irq;
@@ -1367,10 +1468,16 @@ static int xgbe_phy_best_advertised_speed(struct xgbe_prv_data *pdata)
13671468
{
13681469
if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full)
13691470
return SPEED_10000;
1471+
else if (pdata->phy.advertising & ADVERTISED_10000baseT_Full)
1472+
return SPEED_10000;
13701473
else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full)
13711474
return SPEED_2500;
13721475
else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full)
13731476
return SPEED_1000;
1477+
else if (pdata->phy.advertising & ADVERTISED_1000baseT_Full)
1478+
return SPEED_1000;
1479+
else if (pdata->phy.advertising & ADVERTISED_100baseT_Full)
1480+
return SPEED_100;
13741481

13751482
return SPEED_UNKNOWN;
13761483
}

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,12 @@ static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
295295
return mode;
296296
}
297297

298+
static int xgbe_phy_an_config(struct xgbe_prv_data *pdata)
299+
{
300+
/* Nothing uniquely required for an configuration */
301+
return 0;
302+
}
303+
298304
static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata)
299305
{
300306
return XGBE_AN_MODE_CL73;
@@ -607,10 +613,12 @@ static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
607613
}
608614
}
609615

610-
static int xgbe_phy_link_status(struct xgbe_prv_data *pdata)
616+
static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
611617
{
612618
unsigned int reg;
613619

620+
*an_restart = 0;
621+
614622
/* Link status is latched low, so read once to clear
615623
* and then read again to get current state
616624
*/
@@ -821,6 +829,8 @@ void xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *phy_if)
821829

822830
phy_impl->an_mode = xgbe_phy_an_mode;
823831

832+
phy_impl->an_config = xgbe_phy_an_config;
833+
824834
phy_impl->an_outcome = xgbe_phy_an_outcome;
825835

826836
phy_impl->kr_training_pre = xgbe_phy_kr_training_pre;

0 commit comments

Comments
 (0)