get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/16288/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 16288,
    "url": "https://patches.dpdk.org/api/patches/16288/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20160930090039.10164-2-tomaszx.kulasek@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20160930090039.10164-2-tomaszx.kulasek@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20160930090039.10164-2-tomaszx.kulasek@intel.com",
    "date": "2016-09-30T09:00:34",
    "name": "[dpdk-dev,v4,1/6] ethdev: add Tx preparation",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "bc2dc58f8694d341beb040e578a5524d3e3ef62b",
    "submitter": {
        "id": 155,
        "url": "https://patches.dpdk.org/api/people/155/?format=api",
        "name": "Tomasz Kulasek",
        "email": "tomaszx.kulasek@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20160930090039.10164-2-tomaszx.kulasek@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/16288/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/16288/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id DAAB258D4;\n\tFri, 30 Sep 2016 11:01:12 +0200 (CEST)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby dpdk.org (Postfix) with ESMTP id 2142056A1\n\tfor <dev@dpdk.org>; Fri, 30 Sep 2016 11:01:04 +0200 (CEST)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby orsmga105.jf.intel.com with ESMTP; 30 Sep 2016 02:01:04 -0700",
            "from unknown (HELO IGKLOANER07.ger.corp.intel.com)\n\t([10.103.102.90])\n\tby fmsmga001.fm.intel.com with ESMTP; 30 Sep 2016 02:01:04 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos; i=\"5.31,271,1473145200\"; d=\"scan'208\";\n\ta=\"1047845878\"",
        "From": "Tomasz Kulasek <tomaszx.kulasek@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "konstantin.ananyev@intel.com, Tomasz Kulasek <tomaszx.kulasek@intel.com>",
        "Date": "Fri, 30 Sep 2016 11:00:34 +0200",
        "Message-Id": "<20160930090039.10164-2-tomaszx.kulasek@intel.com>",
        "In-Reply-To": "<20160930090039.10164-1-tomaszx.kulasek@intel.com>",
        "References": "<20160928111052.9968-1-tomaszx.kulasek@intel.com>\n\t<20160930090039.10164-1-tomaszx.kulasek@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v4 1/6] ethdev: add Tx preparation",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Added API for `rte_eth_tx_prep`\n\nuint16_t rte_eth_tx_prep(uint8_t port_id, uint16_t queue_id,\n\tstruct rte_mbuf **tx_pkts, uint16_t nb_pkts)\n\nAdded fields to the `struct rte_eth_desc_lim`:\n\n\tuint16_t nb_seg_max;\n\t\t/**< Max number of segments per whole packet. */\n\n\tuint16_t nb_mtu_seg_max;\n\t\t/**< Max number of segments per one MTU */\n\nCreated `rte_pkt.h` header with common used functions:\n\nint rte_validate_tx_offload(struct rte_mbuf *m)\n\tto validate general requirements for tx offload in packet such a\n\tflag completness. In current implementation this function is called\n\toptionaly when RTE_LIBRTE_ETHDEV_DEBUG is enabled.\n\nint rte_phdr_cksum_fix(struct rte_mbuf *m)\n\tto fix pseudo header checksum for TSO and non-TSO tcp/udp packets\n\tbefore hardware tx checksum offload.\n\t - for non-TSO tcp/udp packets full pseudo-header checksum is\n\t   counted and set.\n\t - for TSO the IP payload length is not included.\n\nSigned-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>\n---\n config/common_base            |    1 +\n lib/librte_ether/rte_ethdev.h |   85 ++++++++++++++++++++++++++\n lib/librte_mbuf/rte_mbuf.h    |    8 +++\n lib/librte_net/Makefile       |    2 +-\n lib/librte_net/rte_pkt.h      |  133 +++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 228 insertions(+), 1 deletion(-)\n create mode 100644 lib/librte_net/rte_pkt.h",
    "diff": "diff --git a/config/common_base b/config/common_base\nindex 7830535..7ada9e0 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -120,6 +120,7 @@ CONFIG_RTE_MAX_QUEUES_PER_PORT=1024\n CONFIG_RTE_LIBRTE_IEEE1588=n\n CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16\n CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y\n+CONFIG_RTE_ETHDEV_TX_PREP=y\n \n #\n # Support NIC bypass logic\ndiff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h\nindex 96575e8..6594544 100644\n--- a/lib/librte_ether/rte_ethdev.h\n+++ b/lib/librte_ether/rte_ethdev.h\n@@ -182,6 +182,7 @@ extern \"C\" {\n #include <rte_pci.h>\n #include <rte_dev.h>\n #include <rte_devargs.h>\n+#include <rte_errno.h>\n #include \"rte_ether.h\"\n #include \"rte_eth_ctrl.h\"\n #include \"rte_dev_info.h\"\n@@ -699,6 +700,8 @@ struct rte_eth_desc_lim {\n \tuint16_t nb_max;   /**< Max allowed number of descriptors. */\n \tuint16_t nb_min;   /**< Min allowed number of descriptors. */\n \tuint16_t nb_align; /**< Number of descriptors should be aligned to. */\n+\tuint16_t nb_seg_max;     /**< Max number of segments per whole packet. */\n+\tuint16_t nb_mtu_seg_max; /**< Max number of segments per one MTU */\n };\n \n /**\n@@ -1184,6 +1187,11 @@ typedef uint16_t (*eth_tx_burst_t)(void *txq,\n \t\t\t\t   uint16_t nb_pkts);\n /**< @internal Send output packets on a transmit queue of an Ethernet device. */\n \n+typedef uint16_t (*eth_tx_prep_t)(void *txq,\n+\t\t\t\t   struct rte_mbuf **tx_pkts,\n+\t\t\t\t   uint16_t nb_pkts);\n+/**< @internal Prepare output packets on a transmit queue of an Ethernet device. */\n+\n typedef int (*flow_ctrl_get_t)(struct rte_eth_dev *dev,\n \t\t\t       struct rte_eth_fc_conf *fc_conf);\n /**< @internal Get current flow control parameter on an Ethernet device */\n@@ -1629,6 +1637,7 @@ enum rte_eth_dev_type {\n struct rte_eth_dev {\n \teth_rx_burst_t rx_pkt_burst; /**< Pointer to PMD receive function. */\n \teth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */\n+\teth_tx_prep_t tx_pkt_prep; /**< Pointer to PMD transmit prepare function. */\n \tstruct rte_eth_dev_data *data;  /**< Pointer to device data */\n \tconst struct eth_driver *driver;/**< Driver for this device */\n \tconst struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */\n@@ -2837,6 +2846,82 @@ rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,\n \treturn (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id], tx_pkts, nb_pkts);\n }\n \n+/**\n+ * Process a burst of output packets on a transmit queue of an Ethernet device.\n+ *\n+ * The rte_eth_tx_prep() function is invoked to prepare output packets to be\n+ * transmitted on the output queue *queue_id* of the Ethernet device designated\n+ * by its *port_id*.\n+ * The *nb_pkts* parameter is the number of packets to be prepared which are\n+ * supplied in the *tx_pkts* array of *rte_mbuf* structures, each of them\n+ * allocated from a pool created with rte_pktmbuf_pool_create().\n+ * For each packet to send, the rte_eth_tx_prep() function performs\n+ * the following operations:\n+ *\n+ * - Check if packet meets devices requirements for tx offloads.\n+ *\n+ * - Check limitations about number of segments.\n+ *\n+ * - Check additional requirements when debug is enabled.\n+ *\n+ * - Update and/or reset required checksums when tx offload is set for packet.\n+ *\n+ * The rte_eth_tx_prep() function returns the number of packets ready to be\n+ * sent. A return value equal to *nb_pkts* means that all packets are valid and\n+ * ready to be sent.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param queue_id\n+ *   The index of the transmit queue through which output packets must be\n+ *   sent.\n+ *   The value must be in the range [0, nb_tx_queue - 1] previously supplied\n+ *   to rte_eth_dev_configure().\n+ * @param tx_pkts\n+ *   The address of an array of *nb_pkts* pointers to *rte_mbuf* structures\n+ *   which contain the output packets.\n+ * @param nb_pkts\n+ *   The maximum number of packets to process.\n+ * @return\n+ *   The number of packets correct and ready to be sent. The return value can be\n+ *   less than the value of the *tx_pkts* parameter when some packet doesn't\n+ *   meet devices requirements with rte_errno set appropriately.\n+ */\n+\n+#ifdef RTE_ETHDEV_TX_PREP\n+\n+static inline uint16_t\n+rte_eth_tx_prep(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **tx_pkts,\n+\t\tuint16_t nb_pkts)\n+{\n+\tstruct rte_eth_dev *dev = &rte_eth_devices[port_id];\n+\n+\tif (!dev->tx_pkt_prep)\n+\t\treturn nb_pkts;\n+\n+#ifdef RTE_LIBRTE_ETHDEV_DEBUG\n+\tif (queue_id >= dev->data->nb_tx_queues) {\n+\t\tRTE_PMD_DEBUG_TRACE(\"Invalid TX queue_id=%d\\n\", queue_id);\n+\t\trte_errno = -EINVAL;\n+\t\treturn 0;\n+\t}\n+#endif\n+\n+\treturn (*dev->tx_pkt_prep)(dev->data->tx_queues[queue_id],\n+\t\t\ttx_pkts, nb_pkts);\n+}\n+\n+#else\n+\n+static inline uint16_t\n+rte_eth_tx_prep(uint8_t port_id __rte_unused, uint16_t queue_id __rte_unused,\n+\t\tstruct rte_mbuf **tx_pkts __rte_unused, uint16_t nb_pkts)\n+{\n+\treturn nb_pkts;\n+}\n+\n+#endif\n+\n typedef void (*buffer_tx_error_fn)(struct rte_mbuf **unsent, uint16_t count,\n \t\tvoid *userdata);\n \ndiff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h\nindex 23b7bf8..8b73261 100644\n--- a/lib/librte_mbuf/rte_mbuf.h\n+++ b/lib/librte_mbuf/rte_mbuf.h\n@@ -211,6 +211,14 @@ extern \"C\" {\n  */\n #define PKT_TX_OUTER_IPV4   (1ULL << 59)\n \n+#define PKT_TX_OFFLOAD_MASK (    \\\n+\t\tPKT_TX_IP_CKSUM |        \\\n+\t\tPKT_TX_L4_MASK |         \\\n+\t\tPKT_TX_OUTER_IP_CKSUM |  \\\n+\t\tPKT_TX_TCP_SEG |         \\\n+\t\tPKT_TX_QINQ_PKT |        \\\n+\t\tPKT_TX_VLAN_PKT)\n+\n /**\n  * Packet outer header is IPv6. This flag must be set when using any\n  * outer offload feature (L4 checksum) to tell the NIC that the outer\ndiff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile\nindex ad2e482..b5abe84 100644\n--- a/lib/librte_net/Makefile\n+++ b/lib/librte_net/Makefile\n@@ -34,7 +34,7 @@ include $(RTE_SDK)/mk/rte.vars.mk\n CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3\n \n # install includes\n-SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h rte_udp.h rte_sctp.h rte_icmp.h rte_arp.h\n+SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h rte_udp.h rte_sctp.h rte_icmp.h rte_arp.h rte_pkt.h\n \n \n include $(RTE_SDK)/mk/rte.install.mk\ndiff --git a/lib/librte_net/rte_pkt.h b/lib/librte_net/rte_pkt.h\nnew file mode 100644\nindex 0000000..72903ac\n--- /dev/null\n+++ b/lib/librte_net/rte_pkt.h\n@@ -0,0 +1,133 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _RTE_PKT_H_\n+#define _RTE_PKT_H_\n+\n+#include <rte_ip.h>\n+#include <rte_udp.h>\n+#include <rte_tcp.h>\n+#include <rte_sctp.h>\n+\n+/**\n+ * Validate general requirements for tx offload in packet.\n+ */\n+static inline int\n+rte_validate_tx_offload(struct rte_mbuf *m)\n+{\n+\tuint64_t ol_flags = m->ol_flags;\n+\n+\t/* Does packet set any of available offloads? */\n+\tif (!(ol_flags & PKT_TX_OFFLOAD_MASK))\n+\t\treturn 0;\n+\n+\t/* IP checksum can be counted only for IPv4 packet */\n+\tif ((ol_flags & PKT_TX_IP_CKSUM) && (ol_flags & PKT_TX_IPV6))\n+\t\treturn -EINVAL;\n+\n+\tif (ol_flags & (PKT_TX_L4_MASK | PKT_TX_TCP_SEG))\n+\t\t/* IP type not set */\n+\t\tif (!(ol_flags & (PKT_TX_IPV4 | PKT_TX_IPV6)))\n+\t\t\treturn -EINVAL;\n+\n+\tif (ol_flags & PKT_TX_TCP_SEG)\n+\t\t/* PKT_TX_IP_CKSUM offload not set for IPv4 TSO packet */\n+\t\tif ((m->tso_segsz == 0) ||\n+\t\t\t\t((ol_flags & PKT_TX_IPV4) && !(ol_flags & PKT_TX_IP_CKSUM)))\n+\t\t\treturn -EINVAL;\n+\n+\t/* PKT_TX_OUTER_IP_CKSUM set for non outer IPv4 packet. */\n+\tif ((ol_flags & PKT_TX_OUTER_IP_CKSUM) && !(ol_flags & PKT_TX_OUTER_IPV4))\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Fix pseudo header checksum for TSO and non-TSO tcp/udp packets before\n+ * hardware tx checksum.\n+ * For non-TSO tcp/udp packets full pseudo-header checksum is counted and set.\n+ * For TSO the IP payload length is not included.\n+ */\n+static inline int\n+rte_phdr_cksum_fix(struct rte_mbuf *m)\n+{\n+\tstruct ipv4_hdr *ipv4_hdr;\n+\tstruct ipv6_hdr *ipv6_hdr;\n+\tstruct tcp_hdr *tcp_hdr;\n+\tstruct udp_hdr *udp_hdr;\n+\tuint64_t inner_l3_offset = m->l2_len;\n+\n+\tif (m->ol_flags & PKT_TX_OUTER_IP_CKSUM)\n+\t\tinner_l3_offset += m->outer_l2_len + m->outer_l3_len;\n+\n+\tif (m->ol_flags & PKT_TX_IPV4) {\n+\t\tipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,\n+\t\t\t\tinner_l3_offset);\n+\n+\t\tif (m->ol_flags & PKT_TX_IP_CKSUM)\n+\t\t\tipv4_hdr->hdr_checksum = 0;\n+\n+\t\tif ((m->ol_flags & PKT_TX_UDP_CKSUM) == PKT_TX_UDP_CKSUM) {\n+\t\t\t/* non-TSO udp */\n+\t\t\tudp_hdr = rte_pktmbuf_mtod_offset(m, struct udp_hdr *,\n+\t\t\t\t\tinner_l3_offset + m->l3_len);\n+\t\t\tudp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr, m->ol_flags);\n+\t\t} else if ((m->ol_flags & PKT_TX_TCP_CKSUM) ||\n+\t\t\t\t(m->ol_flags & PKT_TX_TCP_SEG)) {\n+\t\t\t/* non-TSO tcp or TSO */\n+\t\t\ttcp_hdr = rte_pktmbuf_mtod_offset(m, struct tcp_hdr *,\n+\t\t\t\t\tinner_l3_offset + m->l3_len);\n+\t\t\ttcp_hdr->cksum = rte_ipv4_phdr_cksum(ipv4_hdr, m->ol_flags);\n+\t\t}\n+\t} else if (m->ol_flags & PKT_TX_IPV6) {\n+\t\tipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,\n+\t\t\t\tinner_l3_offset);\n+\n+\t\tif ((m->ol_flags & PKT_TX_UDP_CKSUM) == PKT_TX_UDP_CKSUM) {\n+\t\t\t/* non-TSO udp */\n+\t\t\tudp_hdr = rte_pktmbuf_mtod_offset(m, struct udp_hdr *,\n+\t\t\t\t\tinner_l3_offset + m->l3_len);\n+\t\t\tudp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr, m->ol_flags);\n+\t\t} else if ((m->ol_flags & PKT_TX_TCP_CKSUM) ||\n+\t\t\t\t(m->ol_flags & PKT_TX_TCP_SEG)) {\n+\t\t\t/* non-TSO tcp or TSO */\n+\t\t\ttcp_hdr = rte_pktmbuf_mtod_offset(m, struct tcp_hdr *,\n+\t\t\t\t\tinner_l3_offset + m->l3_len);\n+\t\t\ttcp_hdr->cksum = rte_ipv6_phdr_cksum(ipv6_hdr, m->ol_flags);\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+#endif /* _RTE_PKT_H_ */\n",
    "prefixes": [
        "dpdk-dev",
        "v4",
        "1/6"
    ]
}