net/bnxt: fix async link handling and update
authorAjit Khaparde <ajit.khaparde@broadcom.com>
Wed, 2 Oct 2019 17:17:34 +0000 (10:17 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 8 Oct 2019 10:14:30 +0000 (12:14 +0200)
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")
Cc: stable@dpdk.org
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Lance Richardson <lance.richardson@broadcom.com>
drivers/net/bnxt/bnxt_cpr.c
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bnxt/bnxt_irq.c
drivers/net/bnxt/bnxt_irq.h

index 4817672..f583725 100644 (file)
@@ -66,7 +66,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");
index d1c5acb..4d15ba5 100644 (file)
@@ -834,6 +834,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);
        rc = bnxt_hwrm_if_change(bp, 1);
        if (!rc) {
                if (bp->flags & BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE) {
@@ -862,7 +863,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;
@@ -926,7 +926,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);
@@ -938,6 +940,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;
@@ -1084,8 +1088,7 @@ out:
        /* 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,
index a22700a..729d68d 100644 (file)
@@ -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;
index 460a97a..1b56e08 100644 (file)
@@ -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