net/liquidio: add Tx data path for multiple segments
authorShijith Thotton <shijith.thotton@caviumnetworks.com>
Sat, 25 Mar 2017 06:24:39 +0000 (11:54 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 4 Apr 2017 16:59:49 +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>
doc/guides/nics/features/liquidio.ini
drivers/net/liquidio/lio_rxtx.c
drivers/net/liquidio/lio_rxtx.h
drivers/net/liquidio/lio_struct.h

index 554d921..d4bbea1 100644 (file)
@@ -4,6 +4,7 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Jumbo frame          = Y
 Scattered Rx         = Y
 CRC offload          = Y
 L3 checksum offload  = Y
index 14113e1..75ecbd5 100644 (file)
@@ -1451,6 +1451,68 @@ lio_dev_xmit_pkts(void *tx_queue, struct rte_mbuf **pkts, uint16_t nb_pkts)
                                            &cmdsetup, tag);
                        ndata.cmd.cmd3.dptr = rte_mbuf_data_dma_addr(m);
                        ndata.reqtype = LIO_REQTYPE_NORESP_NET;
+               } else {
+                       struct lio_buf_free_info *finfo;
+                       struct lio_gather *g;
+                       phys_addr_t phyaddr;
+                       int i, frags;
+
+                       finfo = (struct lio_buf_free_info *)rte_malloc(NULL,
+                                                       sizeof(*finfo), 0);
+                       if (finfo == NULL) {
+                               PMD_TX_LOG(lio_dev, ERR,
+                                          "free buffer alloc failed\n");
+                               goto xmit_failed;
+                       }
+
+                       rte_spinlock_lock(&lio_dev->glist_lock[iq_no]);
+                       g = (struct lio_gather *)list_delete_first_node(
+                                               &lio_dev->glist_head[iq_no]);
+                       rte_spinlock_unlock(&lio_dev->glist_lock[iq_no]);
+                       if (g == NULL) {
+                               PMD_TX_LOG(lio_dev, ERR,
+                                          "Transmit scatter gather: glist null!\n");
+                               goto xmit_failed;
+                       }
+
+                       cmdsetup.s.gather = 1;
+                       cmdsetup.s.u.gatherptrs = m->nb_segs;
+                       lio_prepare_pci_cmd(lio_dev, &ndata.cmd,
+                                           &cmdsetup, tag);
+
+                       memset(g->sg, 0, g->sg_size);
+                       g->sg[0].ptr[0] = rte_mbuf_data_dma_addr(m);
+                       lio_add_sg_size(&g->sg[0], m->data_len, 0);
+                       pkt_len = m->data_len;
+                       finfo->mbuf = m;
+
+                       /* First seg taken care above */
+                       frags = m->nb_segs - 1;
+                       i = 1;
+                       m = m->next;
+                       while (frags--) {
+                               g->sg[(i >> 2)].ptr[(i & 3)] =
+                                               rte_mbuf_data_dma_addr(m);
+                               lio_add_sg_size(&g->sg[(i >> 2)],
+                                               m->data_len, (i & 3));
+                               pkt_len += m->data_len;
+                               i++;
+                               m = m->next;
+                       }
+
+                       phyaddr = rte_mem_virt2phy(g->sg);
+                       if (phyaddr == RTE_BAD_PHYS_ADDR) {
+                               PMD_TX_LOG(lio_dev, ERR, "bad phys addr\n");
+                               goto xmit_failed;
+                       }
+
+                       ndata.cmd.cmd3.dptr = phyaddr;
+                       ndata.reqtype = LIO_REQTYPE_NORESP_NET_SG;
+
+                       finfo->g = g;
+                       finfo->lio_dev = lio_dev;
+                       finfo->iq_no = (uint64_t)iq_no;
+                       ndata.buf = finfo;
                }
 
                ndata.datasize = pkt_len;
index 6813aea..b555bde 100644 (file)
@@ -666,6 +666,17 @@ lio_opcode_slow_path(union octeon_rh *rh)
        return subcode2 != subcode1;
 }
 
+static inline void
+lio_add_sg_size(struct lio_sg_entry *sg_entry,
+               uint16_t size, uint32_t pos)
+{
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+       sg_entry->u.size[pos] = size;
+#elif RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+       sg_entry->u.size[3 - pos] = size;
+#endif
+}
+
 /* Macro to increment index.
  * Index is incremented by count; if the sum exceeds
  * max, index is wrapped-around to the start.
index 906553c..478a290 100644 (file)
@@ -298,6 +298,30 @@ struct lio_instr_queue {
        const struct rte_memzone *iq_mz;
 };
 
+/** This structure is used by driver to store information required
+ *  to free the mbuff when the packet has been fetched by Octeon.
+ *  Bytes offset below assume worst-case of a 64-bit system.
+ */
+struct lio_buf_free_info {
+       /** Bytes 1-8. Pointer to network device private structure. */
+       struct lio_device *lio_dev;
+
+       /** Bytes 9-16. Pointer to mbuff. */
+       struct rte_mbuf *mbuf;
+
+       /** Bytes 17-24. Pointer to gather list. */
+       struct lio_gather *g;
+
+       /** Bytes 25-32. Physical address of mbuf->data or gather list. */
+       uint64_t dptr;
+
+       /** Bytes 33-47. Piggybacked soft command, if any */
+       struct lio_soft_command *sc;
+
+       /** Bytes 48-63. iq no */
+       uint64_t iq_no;
+};
+
 /* The Scatter-Gather List Entry. The scatter or gather component used with
  * input instruction has this format.
  */