summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatricio Noyola <patricion@google.com>2020-09-11 10:38:50 -0700
committerDavid S. Miller <davem@davemloft.net>2020-09-11 14:31:54 -0700
commit3b7cc73628ff7a545c3ae0762706d2039a1a6446 (patch)
tree81ba4d3d9f3cef71b073903fab04eef72b93518b
parent5cdad90de62c27c6af53edb1b4b91712622b892b (diff)
gve: Use link status register to report link status
This makes the driver better aware of the connectivity status of the device. Based on the device's status register, the driver can call netif_carrier_{on,off}. Reviewed-by: Yangchun Fu <yangchun@google.com> Signed-off-by: Patricio Noyola <patricion@google.com> Signed-off-by: David Awogbemila <awogbemila@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/google/gve/gve_main.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 28e5cc52410e..48a433154ce0 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -774,7 +774,7 @@ static int gve_open(struct net_device *dev)
msecs_to_jiffies(priv->stats_report_timer_period)));
gve_turnup(priv);
- netif_carrier_on(dev);
+ queue_work(priv->gve_wq, &priv->service_task);
priv->interface_up_cnt++;
return 0;
@@ -1032,16 +1032,34 @@ void gve_handle_report_stats(struct gve_priv *priv)
}
}
+static void gve_handle_link_status(struct gve_priv *priv, bool link_status)
+{
+ if (!gve_get_napi_enabled(priv))
+ return;
+
+ if (link_status == netif_carrier_ok(priv->dev))
+ return;
+
+ if (link_status) {
+ netdev_info(priv->dev, "Device link is up.\n");
+ netif_carrier_on(priv->dev);
+ } else {
+ netdev_info(priv->dev, "Device link is down.\n");
+ netif_carrier_off(priv->dev);
+ }
+}
+
/* Handle NIC status register changes, reset requests and report stats */
static void gve_service_task(struct work_struct *work)
{
struct gve_priv *priv = container_of(work, struct gve_priv,
service_task);
+ u32 status = ioread32be(&priv->reg_bar0->device_status);
- gve_handle_status(priv,
- ioread32be(&priv->reg_bar0->device_status));
+ gve_handle_status(priv, status);
gve_handle_reset(priv);
+ gve_handle_link_status(priv, GVE_DEVICE_STATUS_LINK_STATUS_MASK & status);
}
static int gve_init_priv(struct gve_priv *priv, bool skip_describe_device)