diff --git a/drivers/net/ethernet/ti/j721e-cpsw-virt-mac.c b/drivers/net/ethernet/ti/j721e-cpsw-virt-mac.c index aa7200d43..b2c614887 100644 --- a/drivers/net/ethernet/ti/j721e-cpsw-virt-mac.c +++ b/drivers/net/ethernet/ti/j721e-cpsw-virt-mac.c @@ -259,14 +259,51 @@ static void virt_cpsw_nuss_common_stop(struct virt_cpsw_common *common) static int virt_cpsw_nuss_del_mc(struct net_device *ndev, const u8 *addr); +static inline int virt_cpsw_get_ipaddr(struct net_device *ndev, unsigned int *ip_addr) +{ + struct in_device *in_dev; + struct in_ifaddr *ifa; + int result = -ENOENT; + + rcu_read_lock(); + in_dev = __in_dev_get_rcu(ndev); + if (in_dev != NULL) { + ifa = rcu_dereference(in_dev->ifa_list); + if (ifa != NULL) { + *ip_addr = ifa->ifa_address; + result = 0; + } + } + rcu_read_unlock(); + return result; +} + static int virt_cpsw_nuss_ndo_stop(struct net_device *ndev) { struct virt_cpsw_common *common = virt_ndev_to_common(ndev); struct rpmsg_remotedev_eth_switch_ops *rdev_ops; struct device *dev = common->dev; + unsigned int if_address; int ret; rdev_ops = common->rdev_switch_ops; + + /* Forcefully calling NETDEV_DOWN event while bringing + * down the interface + */ + ret = virt_cpsw_get_ipaddr(ndev, &if_address); + if (!ret) { + ret = rdev_ops->unregister_ipv4(common->rdev, + if_address); + if (ret) { + dev_err(dev, "unregister_ipv4 rpmsg - fail %d\n", + ret); + } else { + dev_info(dev, "Force NETDEV_DOWN event for IP %pI4 on %s\n", + &if_address, dev_name(dev)); + } + } + netif_tx_stop_all_queues(ndev); netif_carrier_off(ndev); @@ -288,6 +325,7 @@ static int virt_cpsw_nuss_ndo_open(struct net_device *ndev) struct virt_cpsw_common *common = virt_ndev_to_common(ndev); struct rpmsg_remotedev_eth_switch_ops *rdev_ops; struct device *dev = common->dev; + unsigned int if_address; int ret; rdev_ops = common->rdev_switch_ops; @@ -306,6 +344,19 @@ static int virt_cpsw_nuss_ndo_open(struct net_device *ndev) return ret; } + /* Forcefully call NETDEV UP while bringing up the interface */ + ret = virt_cpsw_get_ipaddr(ndev, &if_address); + if (!ret) { + ret = rdev_ops->register_ipv4(common->rdev, + ndev->dev_addr, if_address); + if (ret) { + dev_err(common->dev, "register_ipv4 rpmsg - fail %d\n", + ret); + } else { + dev_info(common->dev, "Force NETDEV_UP event for IP %pI4 " + "on %s \n", &if_address, dev_name(dev)); + } + } netif_tx_wake_all_queues(ndev); netif_carrier_on(ndev);