qede: Update link status only when interface is ready.
authorSudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com>
Mon, 26 Nov 2018 10:26:59 +0000 (02:26 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 28 Nov 2018 00:17:20 +0000 (16:17 -0800)
In the case of internal reload (e.g., mtu change), there could be a race
between link-up notification from mfw and the driver unload processing. In
such case kernel assumes the link is up and starts using the queues which
leads to the server crash.

Send link notification to the kernel only when driver has already requested
MFW for the link.

Signed-off-by: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qede/qede.h
drivers/net/ethernet/qlogic/qede/qede_main.c

index f8ced12bfc1ac4587e4a5f614b9d394d69de8578..8c0fe59eaad5d1ee8aabf1617908606b52be8e70 100644 (file)
@@ -170,6 +170,7 @@ struct qede_ptp;
 
 enum qede_flags_bit {
        QEDE_FLAGS_IS_VF = 0,
+       QEDE_FLAGS_LINK_REQUESTED,
        QEDE_FLAGS_PTP_TX_IN_PRORGESS,
        QEDE_FLAGS_TX_TIMESTAMPING_EN
 };
index 0f1c480759e0074e9afbd471f46a70d18179bbd3..efbb4f3f0f4bad98d7752a988726fe0c75b1989c 100644 (file)
@@ -2057,6 +2057,8 @@ static void qede_unload(struct qede_dev *edev, enum qede_unload_mode mode,
        if (!is_locked)
                __qede_lock(edev);
 
+       clear_bit(QEDE_FLAGS_LINK_REQUESTED, &edev->flags);
+
        edev->state = QEDE_STATE_CLOSED;
 
        qede_rdma_dev_event_close(edev);
@@ -2163,6 +2165,8 @@ static int qede_load(struct qede_dev *edev, enum qede_load_mode mode,
        /* Program un-configured VLANs */
        qede_configure_vlan_filters(edev);
 
+       set_bit(QEDE_FLAGS_LINK_REQUESTED, &edev->flags);
+
        /* Ask for link-up using current configuration */
        memset(&link_params, 0, sizeof(link_params));
        link_params.link_up = true;
@@ -2258,8 +2262,8 @@ static void qede_link_update(void *dev, struct qed_link_output *link)
 {
        struct qede_dev *edev = dev;
 
-       if (!netif_running(edev->ndev)) {
-               DP_VERBOSE(edev, NETIF_MSG_LINK, "Interface is not running\n");
+       if (!test_bit(QEDE_FLAGS_LINK_REQUESTED, &edev->flags)) {
+               DP_VERBOSE(edev, NETIF_MSG_LINK, "Interface is not ready\n");
                return;
        }