net/bnxt: support Rx/Tx queue start/stop
authorAjit Khaparde <ajit.khaparde@broadcom.com>
Fri, 26 Jan 2018 17:31:58 +0000 (09:31 -0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 29 Jan 2018 09:04:28 +0000 (10:04 +0100)
Currently this is implemented entirely in the PMD as there is no
explicit support in the HW. Re-program the RSS Table without this queue
on stop and add it back to the table on start.

Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bnxt/bnxt_hwrm.c
drivers/net/bnxt/bnxt_hwrm.h
drivers/net/bnxt/bnxt_rxq.c
drivers/net/bnxt/bnxt_rxq.h
drivers/net/bnxt/bnxt_rxr.c
drivers/net/bnxt/bnxt_rxr.h
drivers/net/bnxt/bnxt_txq.h
drivers/net/bnxt/bnxt_txr.c
drivers/net/bnxt/bnxt_txr.h
drivers/net/bnxt/bnxt_vnic.h

index 76fff71..2268aba 100644 (file)
@@ -202,7 +202,7 @@ alloc_mem_err:
 
 static int bnxt_init_chip(struct bnxt *bp)
 {
-       unsigned int i, rss_idx, fw_idx;
+       unsigned int i;
        struct rte_eth_link new;
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
@@ -279,27 +279,12 @@ static int bnxt_init_chip(struct bnxt *bp)
                                i, rc);
                        goto err_out;
                }
-               if (vnic->rss_table && vnic->hash_type) {
-                       /*
-                        * Fill the RSS hash & redirection table with
-                        * ring group ids for all VNICs
-                        */
-                       for (rss_idx = 0, fw_idx = 0;
-                            rss_idx < HW_HASH_INDEX_SIZE;
-                            rss_idx++, fw_idx++) {
-                               if (vnic->fw_grp_ids[fw_idx] ==
-                                   INVALID_HW_RING_ID)
-                                       fw_idx = 0;
-                               vnic->rss_table[rss_idx] =
-                                               vnic->fw_grp_ids[fw_idx];
-                       }
-                       rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
-                       if (rc) {
-                               PMD_DRV_LOG(ERR,
-                                       "HWRM vnic %d set RSS failure rc: %x\n",
-                                       i, rc);
-                               goto err_out;
-                       }
+
+               rc = bnxt_vnic_rss_configure(bp, vnic);
+               if (rc) {
+                       PMD_DRV_LOG(ERR,
+                                   "HWRM vnic set RSS failure rc: %x\n", rc);
+                       goto err_out;
                }
 
                bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
@@ -3022,6 +3007,10 @@ static const struct eth_dev_ops bnxt_dev_ops = {
        .rx_queue_count = bnxt_rx_queue_count_op,
        .rx_descriptor_status = bnxt_rx_descriptor_status_op,
        .tx_descriptor_status = bnxt_tx_descriptor_status_op,
+       .rx_queue_start = bnxt_rx_queue_start,
+       .rx_queue_stop = bnxt_rx_queue_stop,
+       .tx_queue_start = bnxt_tx_queue_start,
+       .tx_queue_stop = bnxt_tx_queue_stop,
        .filter_ctrl = bnxt_filter_ctrl_op,
        .dev_supported_ptypes_get = bnxt_dev_supported_ptypes_get_op,
        .get_eeprom_length    = bnxt_get_eeprom_length_op,
index 75e03ad..8fac052 100644 (file)
@@ -3676,3 +3676,31 @@ int bnxt_hwrm_clear_ntuple_filter(struct bnxt *bp,
 
        return 0;
 }
+
+int bnxt_vnic_rss_configure(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+       unsigned int rss_idx, fw_idx, i;
+
+       if (vnic->rss_table && vnic->hash_type) {
+               /*
+                * Fill the RSS hash & redirection table with
+                * ring group ids for all VNICs
+                */
+               for (rss_idx = 0, fw_idx = 0; rss_idx < HW_HASH_INDEX_SIZE;
+                       rss_idx++, fw_idx++) {
+                       for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+                               fw_idx %= bp->rx_cp_nr_rings;
+                               if (vnic->fw_grp_ids[fw_idx] !=
+                                   INVALID_HW_RING_ID)
+                                       break;
+                               fw_idx++;
+                       }
+                       if (i == bp->rx_cp_nr_rings)
+                               return 0;
+                       vnic->rss_table[rss_idx] =
+                               vnic->fw_grp_ids[fw_idx];
+               }
+               return bnxt_hwrm_vnic_rss_cfg(bp, vnic);
+       }
+       return 0;
+}
index 108f8e8..f11e72a 100644 (file)
@@ -187,4 +187,6 @@ int bnxt_hwrm_flash_nvram(struct bnxt *bp, uint16_t dir_type,
                          uint16_t dir_attr, const uint8_t *data,
                          size_t data_len);
 int bnxt_hwrm_ptp_cfg(struct bnxt *bp);
+int bnxt_vnic_rss_configure(struct bnxt *bp,
+                           struct bnxt_vnic_info *vnic);
 #endif
index 736936a..1630486 100644 (file)
@@ -405,3 +405,56 @@ bnxt_rx_queue_intr_disable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)
        }
        return rc;
 }
+
+int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+       struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+       struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+       struct bnxt_rx_queue *rxq = bp->rx_queues[rx_queue_id];
+       struct bnxt_vnic_info *vnic = NULL;
+
+       if (rxq == NULL) {
+               PMD_DRV_LOG(ERR, "Invalid Rx queue %d\n", rx_queue_id);
+               return -EINVAL;
+       }
+
+       dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+       rxq->rx_deferred_start = false;
+       PMD_DRV_LOG(INFO, "Rx queue started %d\n", rx_queue_id);
+       if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) {
+               vnic = rxq->vnic;
+               if (vnic->fw_grp_ids[rx_queue_id] != INVALID_HW_RING_ID)
+                       return 0;
+               PMD_DRV_LOG(DEBUG, "vnic = %p fw_grp_id = %d\n",
+                       vnic, bp->grp_info[rx_queue_id + 1].fw_grp_id);
+               vnic->fw_grp_ids[rx_queue_id] =
+                                       bp->grp_info[rx_queue_id + 1].fw_grp_id;
+               return bnxt_vnic_rss_configure(bp, vnic);
+       }
+
+       return 0;
+}
+
+int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+       struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+       struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+       struct bnxt_rx_queue *rxq = bp->rx_queues[rx_queue_id];
+       struct bnxt_vnic_info *vnic = NULL;
+
+       if (rxq == NULL) {
+               PMD_DRV_LOG(ERR, "Invalid Rx queue %d\n", rx_queue_id);
+               return -EINVAL;
+       }
+
+       dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+       rxq->rx_deferred_start = true;
+       PMD_DRV_LOG(DEBUG, "Rx queue stopped\n");
+
+       if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) {
+               vnic = rxq->vnic;
+               vnic->fw_grp_ids[rx_queue_id] = INVALID_HW_RING_ID;
+               return bnxt_vnic_rss_configure(bp, vnic);
+       }
+       return 0;
+}
index be19019..c7acaa7 100644 (file)
@@ -50,6 +50,7 @@ struct bnxt_rx_queue {
        uint16_t                reg_idx; /* RX queue register index */
        uint16_t                port_id; /* Device port identifier */
        uint8_t                 crc_len; /* 0 if CRC stripped, 4 otherwise */
+       uint8_t                 rx_deferred_start; /* not in global dev start */
 
        struct bnxt             *bp;
        int                     index;
@@ -75,5 +76,8 @@ int bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev,
                                 uint16_t queue_id);
 int bnxt_rx_queue_intr_disable_op(struct rte_eth_dev *eth_dev,
                                  uint16_t queue_id);
-
+int bnxt_rx_queue_start(struct rte_eth_dev *dev,
+                       uint16_t rx_queue_id);
+int bnxt_rx_queue_stop(struct rte_eth_dev *dev,
+                      uint16_t rx_queue_id);
 #endif
index 3f07c11..9e70c86 100644 (file)
@@ -545,6 +545,10 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
        uint16_t ag_prod = rxr->ag_prod;
        int rc = 0;
 
+       /* If Rx Q was stopped return */
+       if (rxq->rx_deferred_start)
+               return 0;
+
        /* Handle RX burst request */
        while (1) {
                cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
index a94373d..f3ed49b 100644 (file)
@@ -120,5 +120,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 void bnxt_free_rx_rings(struct bnxt *bp);
 int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id);
 int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq);
-
+int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
+int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 #endif
index f753c10..e27c34f 100644 (file)
@@ -71,5 +71,4 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
                               uint16_t nb_desc,
                               unsigned int socket_id,
                               const struct rte_eth_txconf *tx_conf);
-
 #endif
index 2f2c871..2c81a37 100644 (file)
@@ -349,6 +349,11 @@ uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
        /* Handle TX completions */
        bnxt_handle_tx_cp(txq);
 
+       /* Tx queue was stopped; wait for it to be restarted */
+       if (txq->tx_deferred_start) {
+               PMD_DRV_LOG(DEBUG, "Tx q stopped;return\n");
+               return 0;
+       }
        /* Handle TX burst request */
        for (nb_tx_pkts = 0; nb_tx_pkts < nb_pkts; nb_tx_pkts++) {
                if (bnxt_start_xmit(tx_pkts[nb_tx_pkts], txq)) {
@@ -364,3 +369,30 @@ uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 
        return nb_tx_pkts;
 }
+
+int bnxt_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+       struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+       struct bnxt_tx_queue *txq = bp->tx_queues[tx_queue_id];
+
+       dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+       txq->tx_deferred_start = false;
+       PMD_DRV_LOG(DEBUG, "Tx queue started\n");
+
+       return 0;
+}
+
+int bnxt_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+       struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+       struct bnxt_tx_queue *txq = bp->tx_queues[tx_queue_id];
+
+       /* Handle TX completions */
+       bnxt_handle_tx_cp(txq);
+
+       dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+       txq->tx_deferred_start = true;
+       PMD_DRV_LOG(DEBUG, "Tx queue stopped\n");
+
+       return 0;
+}
index 2feac51..d88b15a 100644 (file)
@@ -68,6 +68,8 @@ int bnxt_init_one_tx_ring(struct bnxt_tx_queue *txq);
 int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id);
 uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
                               uint16_t nb_pkts);
+int bnxt_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+int bnxt_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 
 #define PKT_TX_OIP_IIP_TCP_UDP_CKSUM   (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
                                        PKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM)
index 875dc3c..d8d35c7 100644 (file)
@@ -93,5 +93,4 @@ void bnxt_free_vnic_attributes(struct bnxt *bp);
 int bnxt_alloc_vnic_attributes(struct bnxt *bp);
 void bnxt_free_vnic_mem(struct bnxt *bp);
 int bnxt_alloc_vnic_mem(struct bnxt *bp);
-
 #endif