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.kall...@cavium.com>
Signed-off-by: Ariel Elior <ariel.el...@cavium.com>
Signed-off-by: Michal Kalderon <michal.kalde...@cavium.com>
---
 drivers/net/ethernet/qlogic/qede/qede.h      | 1 +
 drivers/net/ethernet/qlogic/qede/qede_main.c | 8 ++++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede.h 
b/drivers/net/ethernet/qlogic/qede/qede.h
index f8ced12..8c0fe59 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -170,6 +170,7 @@ struct qede_rdma_dev {
 
 enum qede_flags_bit {
        QEDE_FLAGS_IS_VF = 0,
+       QEDE_FLAGS_LINK_REQUESTED,
        QEDE_FLAGS_PTP_TX_IN_PRORGESS,
        QEDE_FLAGS_TX_TIMESTAMPING_EN
 };
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c 
b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 61f9664..c6e387e 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -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;
        }
 
-- 
1.8.3.1

Reply via email to