net/liquidio: add API to setup Tx queue
authorShijith Thotton <shijith.thotton@caviumnetworks.com>
Sat, 25 Mar 2017 06:24:35 +0000 (11:54 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 4 Apr 2017 16:59:48 +0000 (18:59 +0200)
Signed-off-by: Shijith Thotton <shijith.thotton@caviumnetworks.com>
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Venkat Koppula <venkat.koppula@caviumnetworks.com>
Signed-off-by: Srisivasubramanian S <ssrinivasan@caviumnetworks.com>
Signed-off-by: Mallesham Jatharakonda <mjatharakonda@oneconvergence.com>
drivers/net/liquidio/lio_ethdev.c
drivers/net/liquidio/lio_rxtx.c
drivers/net/liquidio/lio_rxtx.h

index d5f650e..9e2d3f8 100644 (file)
@@ -148,6 +148,65 @@ lio_dev_rx_queue_release(void *rxq)
        }
 }
 
+/**
+ * Allocate and initialize SW ring. Initialize associated HW registers.
+ *
+ * @param eth_dev
+ *   Pointer to structure rte_eth_dev
+ *
+ * @param q_no
+ *   Queue number
+ *
+ * @param num_tx_descs
+ *   Number of ringbuffer descriptors
+ *
+ * @param socket_id
+ *   NUMA socket id, used for memory allocations
+ *
+ * @param tx_conf
+ *   Pointer to the structure rte_eth_txconf
+ *
+ * @return
+ *   - On success, return 0
+ *   - On failure, return -errno value
+ */
+static int
+lio_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t q_no,
+                      uint16_t num_tx_descs, unsigned int socket_id,
+                      const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+       struct lio_device *lio_dev = LIO_DEV(eth_dev);
+       int fw_mapped_iq = lio_dev->linfo.txpciq[q_no].s.q_no;
+       int retval;
+
+       if (q_no >= lio_dev->nb_tx_queues) {
+               lio_dev_err(lio_dev, "Invalid tx queue number %u\n", q_no);
+               return -EINVAL;
+       }
+
+       lio_dev_dbg(lio_dev, "setting up tx queue %u\n", q_no);
+
+       if ((lio_dev->instr_queue[fw_mapped_iq] != NULL) &&
+           (num_tx_descs != lio_dev->instr_queue[fw_mapped_iq]->max_count)) {
+               lio_dev_err(lio_dev,
+                           "Reconfiguring Tx descs not supported. Configure descs to same value %u or restart application\n",
+                           lio_dev->instr_queue[fw_mapped_iq]->max_count);
+               return -ENOTSUP;
+       }
+
+       retval = lio_setup_iq(lio_dev, q_no, lio_dev->linfo.txpciq[q_no],
+                             num_tx_descs, lio_dev, socket_id);
+
+       if (retval) {
+               lio_dev_err(lio_dev, "Runtime IQ(TxQ) creation failed.\n");
+               return retval;
+       }
+
+       eth_dev->data->tx_queues[q_no] = lio_dev->instr_queue[fw_mapped_iq];
+
+       return 0;
+}
+
 static int lio_dev_configure(struct rte_eth_dev *eth_dev)
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -294,6 +353,7 @@ static const struct eth_dev_ops liovf_eth_dev_ops = {
        .dev_configure          = lio_dev_configure,
        .rx_queue_setup         = lio_dev_rx_queue_setup,
        .rx_queue_release       = lio_dev_rx_queue_release,
+       .tx_queue_setup         = lio_dev_tx_queue_setup,
 };
 
 static void
index 4e63a50..b0dfc9b 100644 (file)
@@ -861,6 +861,45 @@ lio_free_instr_queue0(struct lio_device *lio_dev)
        lio_dev->num_iqs--;
 }
 
+/* Return 0 on success, -1 on failure */
+int
+lio_setup_iq(struct lio_device *lio_dev, int q_index,
+            union octeon_txpciq txpciq, uint32_t num_descs, void *app_ctx,
+            unsigned int socket_id)
+{
+       uint32_t iq_no = (uint32_t)txpciq.s.q_no;
+
+       if (lio_dev->instr_queue[iq_no]) {
+               lio_dev_dbg(lio_dev, "IQ is in use. Cannot create the IQ: %d again\n",
+                           iq_no);
+               lio_dev->instr_queue[iq_no]->txpciq.txpciq64 = txpciq.txpciq64;
+               lio_dev->instr_queue[iq_no]->app_ctx = app_ctx;
+               return 0;
+       }
+
+       lio_dev->instr_queue[iq_no] = rte_zmalloc_socket("ethdev TX queue",
+                                               sizeof(struct lio_instr_queue),
+                                               RTE_CACHE_LINE_SIZE, socket_id);
+       if (lio_dev->instr_queue[iq_no] == NULL)
+               return -1;
+
+       lio_dev->instr_queue[iq_no]->q_index = q_index;
+       lio_dev->instr_queue[iq_no]->app_ctx = app_ctx;
+
+       if (lio_init_instr_queue(lio_dev, txpciq, num_descs, socket_id))
+               goto release_lio_iq;
+
+       lio_dev->num_iqs++;
+
+       return 0;
+
+release_lio_iq:
+       rte_free(lio_dev->instr_queue[iq_no]);
+       lio_dev->instr_queue[iq_no] = NULL;
+
+       return -1;
+}
+
 static inline void
 lio_ring_doorbell(struct lio_device *lio_dev,
                  struct lio_instr_queue *iq)
index 76d067e..86d5864 100644 (file)
@@ -548,6 +548,9 @@ uint16_t lio_dev_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
                           uint16_t budget);
 void lio_delete_droq_queue(struct lio_device *lio_dev, int oq_no);
 
+int lio_setup_iq(struct lio_device *lio_dev, int q_index,
+                union octeon_txpciq iq_no, uint32_t num_descs, void *app_ctx,
+                unsigned int socket_id);
 /** Setup instruction queue zero for the device
  *  @param lio_dev which lio device to setup
  *