Skip to content

Commit 751d6fd

Browse files
isubramadavem330
authored andcommitted
drivers: net: xgene: fix: Use GPIO to get link status
The link value reported by the link status register is not reliable when no SPF module inserted. This patchset fixes this issue by using GPIO to determine the link status. Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> Signed-off-by: Quan Nguyen <qnguyen@apm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent c66549f commit 751d6fd

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

drivers/net/ethernet/apm/xgene/xgene_enet_main.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1381,9 +1381,13 @@ static void xgene_enet_gpiod_get(struct xgene_enet_pdata *pdata)
13811381
{
13821382
struct device *dev = &pdata->pdev->dev;
13831383

1384-
if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII)
1384+
pdata->sfp_gpio_en = false;
1385+
if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII ||
1386+
(!device_property_present(dev, "sfp-gpios") &&
1387+
!device_property_present(dev, "rxlos-gpios")))
13851388
return;
13861389

1390+
pdata->sfp_gpio_en = true;
13871391
pdata->sfp_rdy = gpiod_get(dev, "rxlos", GPIOD_IN);
13881392
if (IS_ERR(pdata->sfp_rdy))
13891393
pdata->sfp_rdy = gpiod_get(dev, "sfp", GPIOD_IN);

drivers/net/ethernet/apm/xgene/xgene_enet_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ struct xgene_enet_pdata {
219219
u8 rx_delay;
220220
bool mdio_driver;
221221
struct gpio_desc *sfp_rdy;
222+
bool sfp_gpio_en;
222223
};
223224

224225
struct xgene_indirect_ctl {

drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,16 +415,31 @@ static void xgene_enet_clear(struct xgene_enet_pdata *pdata,
415415
xgene_enet_wr_ring_if(pdata, addr, data);
416416
}
417417

418+
static int xgene_enet_gpio_lookup(struct xgene_enet_pdata *pdata)
419+
{
420+
struct device *dev = &pdata->pdev->dev;
421+
422+
pdata->sfp_rdy = gpiod_get(dev, "rxlos", GPIOD_IN);
423+
if (IS_ERR(pdata->sfp_rdy))
424+
pdata->sfp_rdy = gpiod_get(dev, "sfp", GPIOD_IN);
425+
426+
if (IS_ERR(pdata->sfp_rdy))
427+
return -ENODEV;
428+
429+
return 0;
430+
}
431+
418432
static void xgene_enet_link_state(struct work_struct *work)
419433
{
420434
struct xgene_enet_pdata *pdata = container_of(to_delayed_work(work),
421435
struct xgene_enet_pdata, link_work);
422-
struct gpio_desc *sfp_rdy = pdata->sfp_rdy;
423436
struct net_device *ndev = pdata->ndev;
424437
u32 link_status, poll_interval;
425438

426439
link_status = xgene_enet_link_status(pdata);
427-
if (link_status && !IS_ERR(sfp_rdy) && !gpiod_get_value(sfp_rdy))
440+
if (pdata->sfp_gpio_en && link_status &&
441+
(!IS_ERR(pdata->sfp_rdy) || !xgene_enet_gpio_lookup(pdata)) &&
442+
!gpiod_get_value(pdata->sfp_rdy))
428443
link_status = 0;
429444

430445
if (link_status) {

0 commit comments

Comments
 (0)