get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 350334,
    "url": "http://patchwork.ozlabs.org/api/patches/350334/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1400518800-6111-2-git-send-email-ezequiel.garcia@free-electrons.com/",
    "project": {
        "id": 7,
        "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api",
        "name": "Linux network development",
        "link_name": "netdev",
        "list_id": "netdev.vger.kernel.org",
        "list_email": "netdev@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1400518800-6111-2-git-send-email-ezequiel.garcia@free-electrons.com>",
    "list_archive_url": null,
    "date": "2014-05-19T16:59:52",
    "name": "[1/9] net: Add a software TSO helper API",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "e29077858ebacbab981cbc4e2a3cee6d8d0f26d7",
    "submitter": {
        "id": 20433,
        "url": "http://patchwork.ozlabs.org/api/people/20433/?format=api",
        "name": "Ezequiel Garcia",
        "email": "ezequiel.garcia@free-electrons.com"
    },
    "delegate": {
        "id": 34,
        "url": "http://patchwork.ozlabs.org/api/users/34/?format=api",
        "username": "davem",
        "first_name": "David",
        "last_name": "Miller",
        "email": "davem@davemloft.net"
    },
    "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/1400518800-6111-2-git-send-email-ezequiel.garcia@free-electrons.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/350334/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/350334/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 2DB63140082\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 20 May 2014 03:00:59 +1000 (EST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S932660AbaESRA4 (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 19 May 2014 13:00:56 -0400",
            "from top.free-electrons.com ([176.31.233.9]:53586 \"EHLO\n\tmail.free-electrons.com\" rhost-flags-OK-OK-OK-FAIL) by\n\tvger.kernel.org with ESMTP id S932566AbaESRAy (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Mon, 19 May 2014 13:00:54 -0400",
            "by mail.free-electrons.com (Postfix, from userid 106)\n\tid 2A73A8B1; Mon, 19 May 2014 19:00:58 +0200 (CEST)",
            "from localhost.localdomain (unknown [190.2.108.30])\n\tby mail.free-electrons.com (Postfix) with ESMTPSA id DC7FD7A9;\n\tMon, 19 May 2014 19:00:54 +0200 (CEST)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.3.2 (2011-06-06) on\n\tmail.free-electrons.com",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT\n\tshortcircuit=ham autolearn=disabled version=3.3.2",
        "From": "Ezequiel Garcia <ezequiel.garcia@free-electrons.com>",
        "To": "<netdev@vger.kernel.org>, David Miller <davem@davemloft.net>,\n\tEric Dumazet <eric.dumazet@gmail.com>",
        "Cc": "Willy Tarreau <w@1wt.eu>,\n\tThomas Petazzoni <thomas.petazzoni@free-electrons.com>,\n\tGregory Clement <gregory.clement@free-electrons.com>,\n\tSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>,\n\tTawfik Bayouk <tawfik@marvell.com>, Lior Amsalem <alior@marvell.com>,\n\tEzequiel Garcia <ezequiel.garcia@free-electrons.com>",
        "Subject": "[PATCH 1/9] net: Add a software TSO helper API",
        "Date": "Mon, 19 May 2014 13:59:52 -0300",
        "Message-Id": "<1400518800-6111-2-git-send-email-ezequiel.garcia@free-electrons.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1400518800-6111-1-git-send-email-ezequiel.garcia@free-electrons.com>",
        "References": "<1400518800-6111-1-git-send-email-ezequiel.garcia@free-electrons.com>",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "Although the implementation probably needs a lot of work, this initial API\nallows to implement software TSO in mvneta and mv643xx_eth drivers in a not\nso intrusive way.\n\nSigned-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>\n---\n include/net/tso.h | 20 ++++++++++++++++\n net/core/Makefile |  2 +-\n net/core/tso.c    | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 93 insertions(+), 1 deletion(-)\n create mode 100644 include/net/tso.h\n create mode 100644 net/core/tso.c",
    "diff": "diff --git a/include/net/tso.h b/include/net/tso.h\nnew file mode 100644\nindex 0000000..47e5444\n--- /dev/null\n+++ b/include/net/tso.h\n@@ -0,0 +1,20 @@\n+#ifndef _TSO_H\n+#define _TSO_H\n+\n+#include <net/ip.h>\n+\n+struct tso_t {\n+\tint next_frag_idx;\n+\tvoid *data;\n+\tsize_t size;\n+\tu16 ip_id;\n+\tu32 tcp_seq;\n+};\n+\n+int tso_count_descs(struct sk_buff *skb);\n+void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,\n+\t\t   int size, bool is_last);\n+void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size);\n+void tso_start(struct sk_buff *skb, struct tso_t *tso);\n+\n+#endif\t/* _TSO_H */\ndiff --git a/net/core/Makefile b/net/core/Makefile\nindex 826b925..71093d9 100644\n--- a/net/core/Makefile\n+++ b/net/core/Makefile\n@@ -9,7 +9,7 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o\n \n obj-y\t\t     += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \\\n \t\t\tneighbour.o rtnetlink.o utils.o link_watch.o filter.o \\\n-\t\t\tsock_diag.o dev_ioctl.o\n+\t\t\tsock_diag.o dev_ioctl.o tso.o\n \n obj-$(CONFIG_XFRM) += flow.o\n obj-y += net-sysfs.o\ndiff --git a/net/core/tso.c b/net/core/tso.c\nnew file mode 100644\nindex 0000000..097821d\n--- /dev/null\n+++ b/net/core/tso.c\n@@ -0,0 +1,72 @@\n+#include <net/ip.h>\n+#include <net/tso.h>\n+\n+/* Calculate expected number of TX descriptors */\n+int tso_count_descs(struct sk_buff *skb)\n+{\n+\t/* The Marvell Way */\n+\treturn skb_shinfo(skb)->gso_segs * 2 + skb_shinfo(skb)->nr_frags;\n+}\n+\n+void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,\n+\t\t   int size, bool is_last)\n+{\n+\tstruct iphdr *iph;\n+\tstruct tcphdr *tcph;\n+\tint hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);\n+\tint mac_hdr_len = skb_network_offset(skb);\n+\n+\tmemcpy(hdr, skb->data, hdr_len);\n+\tiph = (struct iphdr *)(hdr + mac_hdr_len);\n+\tiph->id = htons(tso->ip_id);\n+\tiph->tot_len = htons(size + hdr_len - mac_hdr_len);\n+\ttcph = (struct tcphdr *)(hdr + skb_transport_offset(skb));\n+\ttcph->seq = htonl(tso->tcp_seq);\n+\ttso->ip_id++;\n+\n+\tif (!is_last) {\n+\t\t/* Clear all special flags for not last packet */\n+\t\ttcph->psh = 0;\n+\t\ttcph->fin = 0;\n+\t\ttcph->rst = 0;\n+\t}\n+}\n+\n+void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size)\n+{\n+\ttso->tcp_seq += size;\n+\ttso->size -= size;\n+\ttso->data += size;\n+\n+\tif ((tso->size == 0) &&\n+\t    (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {\n+\t\tskb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];\n+\n+\t\t/* Move to next segment */\n+\t\ttso->size = frag->size;\n+\t\ttso->data = page_address(frag->page.p) + frag->page_offset;\n+\t\ttso->next_frag_idx++;\n+\t}\n+}\n+\n+void tso_start(struct sk_buff *skb, struct tso_t *tso)\n+{\n+\tint hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);\n+\n+\ttso->ip_id = ntohs(ip_hdr(skb)->id);\n+\ttso->tcp_seq = ntohl(tcp_hdr(skb)->seq);\n+\ttso->next_frag_idx = 0;\n+\n+\t/* Build first data */\n+\ttso->size = skb_headlen(skb) - hdr_len;\n+\ttso->data = skb->data + hdr_len;\n+\tif ((tso->size == 0) &&\n+\t    (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {\n+\t\tskb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];\n+\n+\t\t/* Move to next segment */\n+\t\ttso->size = frag->size;\n+\t\ttso->data = page_address(frag->page.p) + frag->page_offset;\n+\t\ttso->next_frag_idx++;\n+\t}\n+}\n",
    "prefixes": [
        "1/9"
    ]
}