mbuf: sort TCP segmentation offload flag
[dpdk.git] / lib / librte_mbuf / rte_mbuf.h
index f855e64..2e5fce5 100644 (file)
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  *
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2014 6WIND S.A.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -68,61 +69,127 @@ extern "C" {
 /*
  * Packet Offload Features Flags. It also carry packet type information.
  * Critical resources. Both rx/tx shared these bits. Be cautious on any change
+ *
+ * - RX flags start at bit position zero, and get added to the left of previous
+ *   flags.
+ * - The most-significant 8 bits are reserved for generic mbuf flags
+ * - TX flags therefore start at bit position 55 (i.e. 63-8), and new flags get
+ *   added to the right of the previously defined flags
+ *
+ * Keep these flags synchronized with rte_get_rx_ol_flag_name() and
+ * rte_get_tx_ol_flag_name().
  */
-#define PKT_RX_VLAN_PKT      0x0001 /**< RX packet is a 802.1q VLAN packet. */
-#define PKT_RX_RSS_HASH      0x0002 /**< RX packet with RSS hash result. */
-#define PKT_RX_FDIR          0x0004 /**< RX packet with FDIR infos. */
-#define PKT_RX_L4_CKSUM_BAD  0x0008 /**< L4 cksum of RX pkt. is not OK. */
-#define PKT_RX_IP_CKSUM_BAD  0x0010 /**< IP cksum of RX pkt. is not OK. */
-#define PKT_RX_EIP_CKSUM_BAD 0x0000 /**< External IP header checksum error. */
-#define PKT_RX_OVERSIZE      0x0000 /**< Num of desc of an RX pkt oversize. */
-#define PKT_RX_HBUF_OVERFLOW 0x0000 /**< Header buffer overflow. */
-#define PKT_RX_RECIP_ERR     0x0000 /**< Hardware processing error. */
-#define PKT_RX_MAC_ERR       0x0000 /**< MAC error. */
-#define PKT_RX_IPV4_HDR      0x0020 /**< RX packet with IPv4 header. */
-#define PKT_RX_IPV4_HDR_EXT  0x0040 /**< RX packet with extended IPv4 header. */
-#define PKT_RX_IPV6_HDR      0x0080 /**< RX packet with IPv6 header. */
-#define PKT_RX_IPV6_HDR_EXT  0x0100 /**< RX packet with extended IPv6 header. */
-#define PKT_RX_IEEE1588_PTP  0x0200 /**< RX IEEE1588 L2 Ethernet PT Packet. */
-#define PKT_RX_IEEE1588_TMST 0x0400 /**< RX IEEE1588 L2/L4 timestamped packet.*/
-
-#define PKT_TX_VLAN_PKT      0x0800 /**< TX packet is a 802.1q VLAN packet. */
-#define PKT_TX_IP_CKSUM      0x1000 /**< IP cksum of TX pkt. computed by NIC. */
-#define PKT_TX_IPV4_CSUM     0x1000 /**< Alias of PKT_TX_IP_CKSUM. */
-#define PKT_TX_IPV4          PKT_RX_IPV4_HDR /**< IPv4 with no IP checksum offload. */
-#define PKT_TX_IPV6          PKT_RX_IPV6_HDR /**< IPv6 packet */
+#define PKT_RX_VLAN_PKT      (1ULL << 0)  /**< RX packet is a 802.1q VLAN packet. */
+#define PKT_RX_RSS_HASH      (1ULL << 1)  /**< RX packet with RSS hash result. */
+#define PKT_RX_FDIR          (1ULL << 2)  /**< RX packet with FDIR match indicate. */
+#define PKT_RX_L4_CKSUM_BAD  (1ULL << 3)  /**< L4 cksum of RX pkt. is not OK. */
+#define PKT_RX_IP_CKSUM_BAD  (1ULL << 4)  /**< IP cksum of RX pkt. is not OK. */
+#define PKT_RX_EIP_CKSUM_BAD (0ULL << 0)  /**< External IP header checksum error. */
+#define PKT_RX_OVERSIZE      (0ULL << 0)  /**< Num of desc of an RX pkt oversize. */
+#define PKT_RX_HBUF_OVERFLOW (0ULL << 0)  /**< Header buffer overflow. */
+#define PKT_RX_RECIP_ERR     (0ULL << 0)  /**< Hardware processing error. */
+#define PKT_RX_MAC_ERR       (0ULL << 0)  /**< MAC error. */
+#define PKT_RX_IPV4_HDR      (1ULL << 5)  /**< RX packet with IPv4 header. */
+#define PKT_RX_IPV4_HDR_EXT  (1ULL << 6)  /**< RX packet with extended IPv4 header. */
+#define PKT_RX_IPV6_HDR      (1ULL << 7)  /**< RX packet with IPv6 header. */
+#define PKT_RX_IPV6_HDR_EXT  (1ULL << 8)  /**< RX packet with extended IPv6 header. */
+#define PKT_RX_IEEE1588_PTP  (1ULL << 9)  /**< RX IEEE1588 L2 Ethernet PT Packet. */
+#define PKT_RX_IEEE1588_TMST (1ULL << 10) /**< RX IEEE1588 L2/L4 timestamped packet.*/
+#define PKT_RX_TUNNEL_IPV4_HDR (1ULL << 11) /**< RX tunnel packet with IPv4 header.*/
+#define PKT_RX_TUNNEL_IPV6_HDR (1ULL << 12) /**< RX tunnel packet with IPv6 header. */
+#define PKT_RX_FDIR_ID       (1ULL << 13) /**< FD id reported if FDIR match. */
+#define PKT_RX_FDIR_FLX      (1ULL << 14) /**< Flexible bytes reported if FDIR match. */
+/* add new RX flags here */
+
+/* add new TX flags here */
 
-/*
- * Bit 14~13 used for L4 packet type with checksum enabled.
- *     00: Reserved
- *     01: TCP checksum
- *     10: SCTP checksum
- *     11: UDP checksum
+/**
+ * TCP segmentation offload. To enable this offload feature for a
+ * packet to be transmitted on hardware supporting TSO:
+ *  - set the PKT_TX_TCP_SEG flag in mbuf->ol_flags (this flag implies
+ *    PKT_TX_TCP_CKSUM)
+ *  - set the flag PKT_TX_IPV4 or PKT_TX_IPV6
+ *  - if it's IPv4, set the PKT_TX_IP_CKSUM flag and write the IP checksum
+ *    to 0 in the packet
+ *  - fill the mbuf offload information: l2_len, l3_len, l4_len, tso_segsz
+ *  - calculate the pseudo header checksum without taking ip_len in account,
+ *    and set it in the TCP header. Refer to rte_ipv4_phdr_cksum() and
+ *    rte_ipv6_phdr_cksum() that can be used as helpers.
+ */
+#define PKT_TX_TCP_SEG       (1ULL << 49)
+
+#define PKT_TX_VXLAN_CKSUM   (1ULL << 50) /**< TX checksum of VXLAN computed by NIC */
+#define PKT_TX_IEEE1588_TMST (1ULL << 51) /**< TX IEEE1588 packet to timestamp. */
+
+/**
+ * Bits 52+53 used for L4 packet type with checksum enabled: 00: Reserved,
+ * 01: TCP checksum, 10: SCTP checksum, 11: UDP checksum. To use hardware
+ * L4 checksum offload, the user needs to:
+ *  - fill l2_len and l3_len in mbuf
+ *  - set the flags PKT_TX_TCP_CKSUM, PKT_TX_SCTP_CKSUM or PKT_TX_UDP_CKSUM
+ *  - set the flag PKT_TX_IPV4 or PKT_TX_IPV6
+ *  - calculate the pseudo header checksum and set it in the L4 header (only
+ *    for TCP or UDP). See rte_ipv4_phdr_cksum() and rte_ipv6_phdr_cksum().
+ *    For SCTP, set the crc field to 0.
  */
-#define PKT_TX_L4_MASK       0x6000 /**< Mask bits for L4 checksum offload request. */
-#define PKT_TX_L4_NO_CKSUM   0x0000 /**< Disable L4 cksum of TX pkt. */
-#define PKT_TX_TCP_CKSUM     0x2000 /**< TCP cksum of TX pkt. computed by NIC. */
-#define PKT_TX_SCTP_CKSUM    0x4000 /**< SCTP cksum of TX pkt. computed by NIC. */
-#define PKT_TX_UDP_CKSUM     0x6000 /**< UDP cksum of TX pkt. computed by NIC. */
-/* Bit 15 */
-#define PKT_TX_IEEE1588_TMST 0x8000 /**< TX IEEE1588 packet to timestamp. */
+#define PKT_TX_L4_NO_CKSUM   (0ULL << 52) /**< Disable L4 cksum of TX pkt. */
+#define PKT_TX_TCP_CKSUM     (1ULL << 52) /**< TCP cksum of TX pkt. computed by NIC. */
+#define PKT_TX_SCTP_CKSUM    (2ULL << 52) /**< SCTP cksum of TX pkt. computed by NIC. */
+#define PKT_TX_UDP_CKSUM     (3ULL << 52) /**< UDP cksum of TX pkt. computed by NIC. */
+#define PKT_TX_L4_MASK       (3ULL << 52) /**< Mask for L4 cksum offload request. */
+
+#define PKT_TX_IP_CKSUM      (1ULL << 54) /**< IP cksum of TX pkt. computed by NIC. */
+#define PKT_TX_IPV4_CSUM     PKT_TX_IP_CKSUM /**< Alias of PKT_TX_IP_CKSUM. */
+
+/** Tell the NIC it's an IPv4 packet. Required for L4 checksum offload or TSO. */
+#define PKT_TX_IPV4          PKT_RX_IPV4_HDR
+
+/** Tell the NIC it's an IPv6 packet. Required for L4 checksum offload or TSO. */
+#define PKT_TX_IPV6          PKT_RX_IPV6_HDR
+
+#define PKT_TX_VLAN_PKT      (1ULL << 55) /**< TX packet is a 802.1q VLAN packet. */
 
 /* Use final bit of flags to indicate a control mbuf */
-#define CTRL_MBUF_FLAG       (1ULL << 63)
+#define CTRL_MBUF_FLAG       (1ULL << 63) /**< Mbuf contains control data */
+
+/**
+ * Get the name of a RX offload flag
+ *
+ * @param mask
+ *   The mask describing the flag.
+ * @return
+ *   The name of this flag, or NULL if it's not a valid RX flag.
+ */
+const char *rte_get_rx_ol_flag_name(uint64_t mask);
 
 /**
- * Bit Mask to indicate what bits required for building TX context
+ * Get the name of a TX offload flag
+ *
+ * @param mask
+ *   The mask describing the flag. Usually only one bit must be set.
+ *   Several bits can be given if they belong to the same mask.
+ *   Ex: PKT_TX_L4_MASK.
+ * @return
+ *   The name of this flag, or NULL if it's not a valid TX flag.
  */
-#define PKT_TX_OFFLOAD_MASK (PKT_TX_VLAN_PKT | PKT_TX_IP_CKSUM | PKT_TX_L4_MASK)
+const char *rte_get_tx_ol_flag_name(uint64_t mask);
 
+/* define a set of marker types that can be used to refer to set points in the
+ * mbuf */
+typedef void    *MARKER[0];   /**< generic marker for a point in a structure */
+typedef uint64_t MARKER64[0]; /**< marker that allows us to overwrite 8 bytes
+                               * with a single assignment */
 /**
  * The generic rte_mbuf, containing a packet mbuf.
  */
 struct rte_mbuf {
+       MARKER cacheline0;
+
        void *buf_addr;           /**< Virtual address of segment buffer. */
        phys_addr_t buf_physaddr; /**< Physical address of segment buffer. */
 
        /* next 8 bytes are initialised on RX descriptor rearm */
+       MARKER64 rearm_data;
        uint16_t buf_len;         /**< Length of segment buffer. */
        uint16_t data_off;
 
@@ -147,49 +214,66 @@ struct rte_mbuf {
        uint64_t ol_flags;        /**< Offload features. */
 
        /* remaining bytes are set on RX when pulling packet from descriptor */
-       uint16_t reserved2;       /**< Unused field. Required for padding */
+       MARKER rx_descriptor_fields1;
+
+       /**
+        * The packet type, which is used to indicate ordinary packet and also
+        * tunneled packet format, i.e. each number is represented a type of
+        * packet.
+        */
+       uint16_t packet_type;
+
        uint16_t data_len;        /**< Amount of data in segment buffer. */
        uint32_t pkt_len;         /**< Total pkt len: sum of all segments. */
-       union {
-               uint16_t l2_l3_len; /**< combined l2/l3 lengths as single var */
-               struct {
-                       uint16_t l3_len:9;      /**< L3 (IP) Header Length. */
-                       uint16_t l2_len:7;      /**< L2 (MAC) Header Length. */
-               };
-       };
        uint16_t vlan_tci;        /**< VLAN Tag Control Identifier (CPU order) */
+       uint16_t reserved;
        union {
                uint32_t rss;     /**< RSS hash result if RSS enabled */
                struct {
-                       uint16_t hash;
-                       uint16_t id;
+                       union {
+                               struct {
+                                       uint16_t hash;
+                                       uint16_t id;
+                               };
+                               uint32_t lo;
+                               /**< Second 4 flexible bytes */
+                       };
+                       uint32_t hi;
+                       /**< First 4 flexible bytes or FD ID, dependent on
+                            PKT_RX_FDIR_* flag in ol_flags. */
                } fdir;           /**< Filter identifier if FDIR enabled */
                uint32_t sched;   /**< Hierarchical scheduler */
+               uint32_t usr;     /**< User defined tags. See @rte_distributor_process */
        } hash;                   /**< hash information */
 
-       /* fields only used in slow path or on TX */
+       /* second cache line - fields only used in slow path or on TX */
+       MARKER cacheline1 __rte_cache_aligned;
+
+       union {
+               void *userdata;   /**< Can be used for external metadata */
+               uint64_t udata64; /**< Allow 8-byte userdata on 32-bit */
+       };
+
        struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */
        struct rte_mbuf *next;    /**< Next segment of scattered packet. */
 
-} __rte_cache_aligned;
+       /* fields to support TX offloads */
+       union {
+               uint64_t tx_offload;       /**< combined for easy fetch */
+               struct {
+                       uint64_t l2_len:7; /**< L2 (MAC) Header Length. */
+                       uint64_t l3_len:9; /**< L3 (IP) Header Length. */
+                       uint64_t l4_len:8; /**< L4 (TCP/UDP) Header Length. */
+                       uint64_t tso_segsz:16; /**< TCP TSO segment size */
 
-#define RTE_MBUF_METADATA_UINT8(mbuf, offset)              \
-       (((uint8_t *)&(mbuf)[1])[offset])
-#define RTE_MBUF_METADATA_UINT16(mbuf, offset)             \
-       (((uint16_t *)&(mbuf)[1])[offset/sizeof(uint16_t)])
-#define RTE_MBUF_METADATA_UINT32(mbuf, offset)             \
-       (((uint32_t *)&(mbuf)[1])[offset/sizeof(uint32_t)])
-#define RTE_MBUF_METADATA_UINT64(mbuf, offset)             \
-       (((uint64_t *)&(mbuf)[1])[offset/sizeof(uint64_t)])
-
-#define RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset)          \
-       (&RTE_MBUF_METADATA_UINT8(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset)         \
-       (&RTE_MBUF_METADATA_UINT16(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset)         \
-       (&RTE_MBUF_METADATA_UINT32(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset)         \
-       (&RTE_MBUF_METADATA_UINT64(mbuf, offset))
+                       /* fields for TX offloading of tunnels */
+                       uint64_t inner_l3_len:9; /**< inner L3 (IP) Hdr Length. */
+                       uint64_t inner_l2_len:7; /**< inner L2 (MAC) Hdr Length. */
+
+                       /* uint64_t unused:8; */
+               };
+       };
+} __rte_cache_aligned;
 
 /**
  * Given the buf_addr returns the pointer to corresponding mbuf.
@@ -538,12 +622,13 @@ static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
 {
        m->next = NULL;
        m->pkt_len = 0;
-       m->l2_l3_len = 0;
+       m->tx_offload = 0;
        m->vlan_tci = 0;
        m->nb_segs = 1;
        m->port = 0xff;
 
        m->ol_flags = 0;
+       m->packet_type = 0;
        m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
                        RTE_PKTMBUF_HEADROOM : m->buf_len;
 
@@ -606,13 +691,14 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
        mi->data_len = md->data_len;
        mi->port = md->port;
        mi->vlan_tci = md->vlan_tci;
-       mi->l2_l3_len = md->l2_l3_len;
+       mi->tx_offload = md->tx_offload;
        mi->hash = md->hash;
 
        mi->next = NULL;
        mi->pkt_len = mi->data_len;
        mi->nb_segs = 1;
        mi->ol_flags = md->ol_flags;
+       mi->packet_type = md->packet_type;
 
        __rte_mbuf_sanity_check(mi, 1);
        __rte_mbuf_sanity_check(md, 0);
@@ -688,8 +774,10 @@ __rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
 static inline void __attribute__((always_inline))
 rte_pktmbuf_free_seg(struct rte_mbuf *m)
 {
-       if (likely(NULL != (m = __rte_pktmbuf_prefree_seg(m))))
+       if (likely(NULL != (m = __rte_pktmbuf_prefree_seg(m)))) {
+               m->next = NULL;
                __rte_mbuf_raw_free(m);
+       }
 }
 
 /**