When updating the link because of an async link notification
there is no need to set wait_for_completion. At this point
the link related information should be available without need to poll.
Use rte_eth_linkstatus_set instead of memcpy to ensure atomicity
while updating the link status.
We force the physical link down as a part of device stop.
But we are not waiting there enough and handling the async notification
before exiting. It just sits in the default CQ till we do a device start.
Fix it by calling the CQ handler in device stop.

Fixes: 7bc8e9a227cc ("net/bnxt: support async link notification")
Reviewed-by: Kalesh Anakkur Purayil <kalesh-anakkur.pura...@broadcom.com>
Reviewed-by: Lance Richardson <lance.richard...@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khapa...@broadcom.com>
---
 drivers/net/bnxt/bnxt_cpr.c    |  2 +-
 drivers/net/bnxt/bnxt_ethdev.c | 11 +++++++----
 drivers/net/bnxt/bnxt_irq.c    |  2 +-
 drivers/net/bnxt/bnxt_irq.h    |  1 +
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 3cedb891e..eb44d872d 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -31,7 +31,7 @@ void bnxt_handle_async_event(struct bnxt *bp,
        case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
        case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
                /* FALLTHROUGH */
-               bnxt_link_update_op(bp->eth_dev, 1);
+               bnxt_link_update_op(bp->eth_dev, 0);
                break;
        case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD:
                PMD_DRV_LOG(INFO, "Async event: PF driver unloaded\n");
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 3c8307b63..f6383327c 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -815,6 +815,7 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
                        bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS);
        }
 
+       bnxt_enable_int(bp);
        bnxt_hwrm_if_change(bp, 1);
 
        rc = bnxt_init_chip(bp);
@@ -836,7 +837,6 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
        eth_dev->rx_pkt_burst = bnxt_receive_function(eth_dev);
        eth_dev->tx_pkt_burst = bnxt_transmit_function(eth_dev);
 
-       bnxt_enable_int(bp);
        bp->flags |= BNXT_FLAG_INIT_DONE;
        eth_dev->data->dev_started = 1;
        bp->dev_stopped = 0;
@@ -897,7 +897,9 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
                /* TBD: STOP HW queues DMA */
                eth_dev->data->dev_link.link_status = 0;
        }
-       bnxt_set_hwrm_link_config(bp, false);
+       bnxt_dev_set_link_down_op(eth_dev);
+       /* Wait for link to be reset and the async notification to process. */
+       rte_delay_ms(BNXT_LINK_WAIT_INTERVAL * 2);
 
        /* Clean queue intr-vector mapping */
        rte_intr_efd_disable(intr_handle);
@@ -909,6 +911,8 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
        bnxt_hwrm_port_clr_stats(bp);
        bnxt_free_tx_mbufs(bp);
        bnxt_free_rx_mbufs(bp);
+       /* Process any remaining notifications in default completion queue */
+       bnxt_int_handler(eth_dev);
        bnxt_shutdown_nic(bp);
        bnxt_hwrm_if_change(bp, 0);
        bp->dev_stopped = 1;
@@ -1055,8 +1059,7 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int 
wait_to_complete)
        /* Timed out or success */
        if (new.link_status != eth_dev->data->dev_link.link_status ||
        new.link_speed != eth_dev->data->dev_link.link_speed) {
-               memcpy(&eth_dev->data->dev_link, &new,
-                       sizeof(struct rte_eth_link));
+               rte_eth_linkstatus_set(eth_dev, &new);
 
                _rte_eth_dev_callback_process(eth_dev,
                                              RTE_ETH_EVENT_INTR_LSC,
diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c
index a22700a0d..729d68d70 100644
--- a/drivers/net/bnxt/bnxt_irq.c
+++ b/drivers/net/bnxt/bnxt_irq.c
@@ -18,7 +18,7 @@
  * Interrupts
  */
 
-static void bnxt_int_handler(void *param)
+void bnxt_int_handler(void *param)
 {
        struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
        struct bnxt *bp = eth_dev->data->dev_private;
diff --git a/drivers/net/bnxt/bnxt_irq.h b/drivers/net/bnxt/bnxt_irq.h
index 460a97a09..1b56e0806 100644
--- a/drivers/net/bnxt/bnxt_irq.h
+++ b/drivers/net/bnxt/bnxt_irq.h
@@ -22,5 +22,6 @@ void bnxt_disable_int(struct bnxt *bp);
 void bnxt_enable_int(struct bnxt *bp);
 int bnxt_setup_int(struct bnxt *bp);
 int bnxt_request_int(struct bnxt *bp);
+void bnxt_int_handler(void *param);
 
 #endif
-- 
2.20.1 (Apple Git-117)

Reply via email to