net/octeontx2: support TSO offload
[dpdk.git] / drivers / net / octeontx2 / otx2_rx.h
index 629768a..1a1ac40 100644 (file)
@@ -8,9 +8,10 @@
 /* Default mark value used when none is provided. */
 #define OTX2_FLOW_ACTION_FLAG_DEFAULT  0xffff
 
-#define PTYPE_WIDTH 12
-#define PTYPE_NON_TUNNEL_ARRAY_SZ      BIT(PTYPE_WIDTH)
-#define PTYPE_TUNNEL_ARRAY_SZ          BIT(PTYPE_WIDTH)
+#define PTYPE_NON_TUNNEL_WIDTH         16
+#define PTYPE_TUNNEL_WIDTH             12
+#define PTYPE_NON_TUNNEL_ARRAY_SZ      BIT(PTYPE_NON_TUNNEL_WIDTH)
+#define PTYPE_TUNNEL_ARRAY_SZ          BIT(PTYPE_TUNNEL_WIDTH)
 #define PTYPE_ARRAY_SZ                 ((PTYPE_NON_TUNNEL_ARRAY_SZ +\
                                         PTYPE_TUNNEL_ARRAY_SZ) *\
                                         sizeof(uint16_t))
 #define NIX_RX_OFFLOAD_MARK_UPDATE_F   BIT(4)
 #define NIX_RX_OFFLOAD_TSTAMP_F        BIT(5)
 
+/* Flags to control cqe_to_mbuf conversion function.
+ * Defining it from backwards to denote its been
+ * not used as offload flags to pick function
+ */
+#define NIX_RX_MULTI_SEG_F            BIT(15)
 #define NIX_TIMESYNC_RX_OFFSET         8
 
 struct otx2_timesync_info {
@@ -45,22 +51,26 @@ union mbuf_initializer {
 
 static __rte_always_inline void
 otx2_nix_mbuf_to_tstamp(struct rte_mbuf *mbuf,
-                       struct otx2_timesync_info *tstamp, const uint16_t flag)
+                       struct otx2_timesync_info *tstamp, const uint16_t flag,
+                       uint64_t *tstamp_ptr)
 {
        if ((flag & NIX_RX_OFFLOAD_TSTAMP_F) &&
-           mbuf->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC &&
            (mbuf->data_off == RTE_PKTMBUF_HEADROOM +
             NIX_TIMESYNC_RX_OFFSET)) {
-               uint64_t *tstamp_ptr;
 
-               /* Deal with rx timestamp */
-               tstamp_ptr = rte_pktmbuf_mtod_offset(mbuf, uint64_t *,
-                                                    -NIX_TIMESYNC_RX_OFFSET);
+               /* Reading the rx timestamp inserted by CGX, viz at
+                * starting of the packet data.
+                */
                mbuf->timestamp = rte_be_to_cpu_64(*tstamp_ptr);
-               tstamp->rx_tstamp = mbuf->timestamp;
-               tstamp->rx_ready = 1;
-               mbuf->ol_flags |= PKT_RX_IEEE1588_PTP | PKT_RX_IEEE1588_TMST
-                       | PKT_RX_TIMESTAMP;
+               /* PKT_RX_IEEE1588_TMST flag needs to be set only in case
+                * PTP packets are received.
+                */
+               if (mbuf->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC) {
+                       tstamp->rx_tstamp = mbuf->timestamp;
+                       tstamp->rx_ready = 1;
+                       mbuf->ol_flags |= PKT_RX_IEEE1588_PTP |
+                               PKT_RX_IEEE1588_TMST | PKT_RX_TIMESTAMP;
+               }
        }
 }
 
@@ -88,11 +98,11 @@ static __rte_always_inline uint32_t
 nix_ptype_get(const void * const lookup_mem, const uint64_t in)
 {
        const uint16_t * const ptype = lookup_mem;
-       const uint16_t lg_lf_le = (in & 0xFFF000000000000) >> 48;
-       const uint16_t tu_l2 = ptype[(in & 0x000FFF000000000) >> 36];
-       const uint16_t il4_tu = ptype[PTYPE_NON_TUNNEL_ARRAY_SZ + lg_lf_le];
+       const uint16_t lh_lg_lf = (in & 0xFFF0000000000000) >> 52;
+       const uint16_t tu_l2 = ptype[(in & 0x000FFFF000000000) >> 36];
+       const uint16_t il4_tu = ptype[PTYPE_NON_TUNNEL_ARRAY_SZ + lh_lg_lf];
 
-       return (il4_tu << PTYPE_WIDTH) | tu_l2;
+       return (il4_tu << PTYPE_NON_TUNNEL_WIDTH) | tu_l2;
 }
 
 static __rte_always_inline uint32_t
@@ -133,6 +143,51 @@ nix_update_match_id(const uint16_t match_id, uint64_t ol_flags,
        return ol_flags;
 }
 
+static __rte_always_inline void
+nix_cqe_xtract_mseg(const struct nix_rx_parse_s *rx,
+                   struct rte_mbuf *mbuf, uint64_t rearm)
+{
+       const rte_iova_t *iova_list;
+       struct rte_mbuf *head;
+       const rte_iova_t *eol;
+       uint8_t nb_segs;
+       uint64_t sg;
+
+       sg = *(const uint64_t *)(rx + 1);
+       nb_segs = (sg >> 48) & 0x3;
+       mbuf->nb_segs = nb_segs;
+       mbuf->data_len = sg & 0xFFFF;
+       sg = sg >> 16;
+
+       eol = ((const rte_iova_t *)(rx + 1) + ((rx->desc_sizem1 + 1) << 1));
+       /* Skip SG_S and first IOVA*/
+       iova_list = ((const rte_iova_t *)(rx + 1)) + 2;
+       nb_segs--;
+
+       rearm = rearm & ~0xFFFF;
+
+       head = mbuf;
+       while (nb_segs) {
+               mbuf->next = ((struct rte_mbuf *)*iova_list) - 1;
+               mbuf = mbuf->next;
+
+               __mempool_check_cookies(mbuf->pool, (void **)&mbuf, 1, 1);
+
+               mbuf->data_len = sg & 0xFFFF;
+               sg = sg >> 16;
+               *(uint64_t *)(&mbuf->rearm_data) = rearm;
+               nb_segs--;
+               iova_list++;
+
+               if (!nb_segs && (iova_list + 1 < eol)) {
+                       sg = *(const uint64_t *)(iova_list);
+                       nb_segs = (sg >> 48) & 0x3;
+                       head->nb_segs += nb_segs;
+                       iova_list = (const rte_iova_t *)(iova_list + 1);
+               }
+       }
+}
+
 static __rte_always_inline void
 otx2_nix_cqe_to_mbuf(const struct nix_cqe_hdr_s *cq, const uint32_t tag,
                     struct rte_mbuf *mbuf, const void *lookup_mem,
@@ -178,7 +233,10 @@ otx2_nix_cqe_to_mbuf(const struct nix_cqe_hdr_s *cq, const uint32_t tag,
        *(uint64_t *)(&mbuf->rearm_data) = val;
        mbuf->pkt_len = len;
 
-       mbuf->data_len = len;
+       if (flag & NIX_RX_MULTI_SEG_F)
+               nix_cqe_xtract_mseg(rx, mbuf, val);
+       else
+               mbuf->data_len = len;
 }
 
 #define CKSUM_F NIX_RX_OFFLOAD_CHECKSUM_F