From 20e4a2fb7aee324473988653653956ec568dd27c Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran Date: Sun, 22 Dec 2019 21:53:18 -0800 Subject: [PATCH] nvethernet: Call netif_carrier_on/off based on PHY link Issue: When configuring loopback mode, netif_carrier_on/off APIs are directly used i.e, netif_carrier_on when loopback mode enabled, netif_carrier_off when loopback mode is disabled. If anyone enables/disables loopback mode when link is alreay up, then link is not restored. Stack is not sending packets due to netif_carrier_off. Fix: Check PHY link status before calling netif_carrier_* APIs. If link is up, then PHY framework would have already invoked these APIs. Bug 200512681 Change-Id: I1e07df202a8915737be8992f838aa5bd5534c512 Signed-off-by: Srinivas Ramachandran Reviewed-on: https://git-master.nvidia.com/r/2267401 GVS: Gerrit_Virtual_Submit Reviewed-by: Bhadram Varka Reviewed-by: Narayan Reddy Reviewed-by: Ashutosh Jha Reviewed-by: mobile promotions Tested-by: mobile promotions --- .../net/ethernet/nvidia/nvethernet/ioctl.c | 19 +++++++++++++++++-- .../net/ethernet/nvidia/nvethernet/sysfs.c | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/nvidia/nvethernet/ioctl.c b/drivers/net/ethernet/nvidia/nvethernet/ioctl.c index 11c2a2f2..eb391274 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ioctl.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ioctl.c @@ -598,6 +598,7 @@ static int ether_config_loopback_mode(struct net_device *ndev, unsigned int flags) { struct ether_priv_data *pdata = netdev_priv(ndev); + struct phy_device *phydev = ndev->phydev; struct osi_core_priv_data *osi_core = pdata->osi_core; int ret = 0; @@ -608,7 +609,14 @@ static int ether_config_loopback_mode(struct net_device *ndev, } if (flags) { - netif_carrier_on(ndev); + if (!phydev->link) { + /* If no phy link, then turn on carrier explicitly so + * that nw stack can send packets. If PHY link is + * present, PHY framework would have already taken care + * of netif_carrier_* status. + */ + netif_carrier_on(ndev); + } ret = osi_config_mac_loopback(osi_core, OSI_ENABLE); if (ret < 0) { dev_err(pdata->dev, @@ -618,7 +626,14 @@ static int ether_config_loopback_mode(struct net_device *ndev, dev_info(pdata->dev, "MAC loopback enabled\n"); } } else { - netif_carrier_off(ndev); + if (!phydev->link) { + /* If no phy link, then turn off carrier explicitly so + * that nw stack doesn't send packets. If PHY link is + * present, PHY framework would have already taken care + * of netif_carrier_* status. + */ + netif_carrier_off(ndev); + } ret = osi_config_mac_loopback(osi_core, OSI_DISABLE); if (ret < 0) { dev_err(pdata->dev, diff --git a/drivers/net/ethernet/nvidia/nvethernet/sysfs.c b/drivers/net/ethernet/nvidia/nvethernet/sysfs.c index 4593de6f..03abeb12 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/sysfs.c +++ b/drivers/net/ethernet/nvidia/nvethernet/sysfs.c @@ -57,6 +57,7 @@ static ssize_t ether_mac_loopback_store(struct device *dev, const char *buf, size_t size) { struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev); + struct phy_device *phydev = ndev->phydev; struct ether_priv_data *pdata = netdev_priv(ndev); int ret = -1; @@ -67,7 +68,14 @@ static ssize_t ether_mac_loopback_store(struct device *dev, } if (strncmp(buf, "enable", 6) == 0U) { - netif_carrier_on(ndev); + if (!phydev->link) { + /* If no phy link, then turn on carrier explicitly so + * that nw stack can send packets. If PHY link is + * present, PHY framework would have already taken care + * of netif_carrier_* status. + */ + netif_carrier_on(ndev); + } /* Enabling the MAC Loopback Mode */ ret = osi_config_mac_loopback(pdata->osi_core, OSI_ENABLE); if (ret < 0) { @@ -77,7 +85,14 @@ static ssize_t ether_mac_loopback_store(struct device *dev, dev_info(pdata->dev, "Enabling MAC Loopback\n"); } } else if (strncmp(buf, "disable", 7) == 0U) { - netif_carrier_off(ndev); + if (!phydev->link) { + /* If no phy link, then turn off carrier explicitly so + * that nw stack doesn't send packets. If PHY link is + * present, PHY framework would have already taken care + * of netif_carrier_* status. + */ + netif_carrier_off(ndev); + } /* Disabling the MAC Loopback Mode */ ret = osi_config_mac_loopback(pdata->osi_core, OSI_DISABLE); if (ret < 0) {