Skip to content

Commit 27ecf87

Browse files
isubramadavem330
authored andcommitted
drivers: net: xgene: Poll link status via GPIO
When 10GbE SFP+ module is not plugged in or cable is not connected, the link status register does not report the proper state due to floating signal. This patch checks the module present status via an GPIO to determine whether to ignore the link status register and report link down. Signed-off-by: Quan Nguyen <qnguyen@apm.com> Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> Tested-by: Fushen Chen <fchen@apm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 3eb7cb9 commit 27ecf87

File tree

4 files changed

+23
-0
lines changed

4 files changed

+23
-0
lines changed

drivers/net/ethernet/apm/xgene/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ config NET_XGENE
44
depends on ARCH_XGENE || COMPILE_TEST
55
select PHYLIB
66
select MDIO_XGENE
7+
select GPIOLIB
78
help
89
This is the Ethernet driver for the on-chip ethernet interface on the
910
APM X-Gene SoC.

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* along with this program. If not, see <http://www.gnu.org/licenses/>.
2020
*/
2121

22+
#include <linux/gpio.h>
2223
#include "xgene_enet_main.h"
2324
#include "xgene_enet_hw.h"
2425
#include "xgene_enet_sgmac.h"
@@ -1320,6 +1321,18 @@ static int xgene_enet_check_phy_handle(struct xgene_enet_pdata *pdata)
13201321
return 0;
13211322
}
13221323

1324+
static void xgene_enet_gpiod_get(struct xgene_enet_pdata *pdata)
1325+
{
1326+
struct device *dev = &pdata->pdev->dev;
1327+
1328+
if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII)
1329+
return;
1330+
1331+
pdata->sfp_rdy = gpiod_get(dev, "rxlos", GPIOD_IN);
1332+
if (IS_ERR(pdata->sfp_rdy))
1333+
pdata->sfp_rdy = gpiod_get(dev, "sfp", GPIOD_IN);
1334+
}
1335+
13231336
static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
13241337
{
13251338
struct platform_device *pdev;
@@ -1409,6 +1422,8 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
14091422
if (ret)
14101423
return ret;
14111424

1425+
xgene_enet_gpiod_get(pdata);
1426+
14121427
pdata->clk = devm_clk_get(&pdev->dev, NULL);
14131428
if (IS_ERR(pdata->clk)) {
14141429
/* Firmware may have set up the clock already. */

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ struct xgene_enet_pdata {
217217
u8 tx_delay;
218218
u8 rx_delay;
219219
bool mdio_driver;
220+
struct gpio_desc *sfp_rdy;
220221
};
221222

222223
struct xgene_indirect_ctl {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1919
*/
2020

21+
#include <linux/of_gpio.h>
22+
#include <linux/gpio.h>
2123
#include "xgene_enet_main.h"
2224
#include "xgene_enet_hw.h"
2325
#include "xgene_enet_xgmac.h"
@@ -399,10 +401,14 @@ static void xgene_enet_link_state(struct work_struct *work)
399401
{
400402
struct xgene_enet_pdata *pdata = container_of(to_delayed_work(work),
401403
struct xgene_enet_pdata, link_work);
404+
struct gpio_desc *sfp_rdy = pdata->sfp_rdy;
402405
struct net_device *ndev = pdata->ndev;
403406
u32 link_status, poll_interval;
404407

405408
link_status = xgene_enet_link_status(pdata);
409+
if (link_status && !IS_ERR(sfp_rdy) && !gpiod_get_value(sfp_rdy))
410+
link_status = 0;
411+
406412
if (link_status) {
407413
if (!netif_carrier_ok(ndev)) {
408414
netif_carrier_on(ndev);

0 commit comments

Comments
 (0)