get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 17330,
    "url": "https://patches.dpdk.org/api/patches/17330/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1480436367-20749-26-git-send-email-arybchenko@solarflare.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": "<1480436367-20749-26-git-send-email-arybchenko@solarflare.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1480436367-20749-26-git-send-email-arybchenko@solarflare.com",
    "date": "2016-11-29T16:18:57",
    "name": "[dpdk-dev,v2,25/55] net/sfc: import libefx support for Rx packed stream mode",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "4ec73baf1db71a50964af335b0621d1887b266c9",
    "submitter": {
        "id": 607,
        "url": "https://patches.dpdk.org/api/people/607/?format=api",
        "name": "Andrew Rybchenko",
        "email": "arybchenko@solarflare.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1480436367-20749-26-git-send-email-arybchenko@solarflare.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/17330/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/17330/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 46980FB1D;\n\tTue, 29 Nov 2016 17:23:10 +0100 (CET)",
            "from nbfkord-smmo01.seg.att.com (nbfkord-smmo01.seg.att.com\n\t[209.65.160.76]) by dpdk.org (Postfix) with ESMTP id 9A2BF5584\n\tfor <dev@dpdk.org>; Tue, 29 Nov 2016 17:21:02 +0100 (CET)",
            "from unknown [12.187.104.26] (EHLO nbfkord-smmo01.seg.att.com)\n\tby nbfkord-smmo01.seg.att.com(mxl_mta-7.2.4-7) with ESMTP id\n\teeaad385.2b3e60c0d940.83700.00-2488.174154.nbfkord-smmo01.seg.att.com\n\t(envelope-from <arybchenko@solarflare.com>); \n\tTue, 29 Nov 2016 16:21:02 +0000 (UTC)",
            "from unknown [12.187.104.26]\n\tby nbfkord-smmo01.seg.att.com(mxl_mta-7.2.4-7) with SMTP id\n\t7eaad385.0.83424.00-2384.173970.nbfkord-smmo01.seg.att.com\n\t(envelope-from <arybchenko@solarflare.com>); \n\tTue, 29 Nov 2016 16:20:56 +0000 (UTC)",
            "from ocex03.SolarFlarecom.com (10.20.40.36) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id 15.0.1044.25; Tue, 29 Nov 2016 08:20:25 -0800",
            "from opal.uk.solarflarecom.com (10.17.10.1) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id\n\t15.0.1044.25 via Frontend Transport; Tue, 29 Nov 2016 08:20:25 -0800",
            "from uklogin.uk.solarflarecom.com (uklogin.uk.solarflarecom.com\n\t[10.17.10.10])\n\tby opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuATGKNnT029964; Tue, 29 Nov 2016 16:20:24 GMT",
            "from uklogin.uk.solarflarecom.com (localhost.localdomain\n\t[127.0.0.1])\n\tby uklogin.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuATGKM1X021233; Tue, 29 Nov 2016 16:20:23 GMT"
        ],
        "X-MXL-Hash": [
            "583daaee5ac2b284-574fdd1963c068f4c3517dabb8e9b9773c519ccf",
            "583daae80e8c24a5-b8371347589ffff1d89f427f3c3d40835b8a49bf"
        ],
        "From": "Andrew Rybchenko <arybchenko@solarflare.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@intel.com>",
        "Date": "Tue, 29 Nov 2016 16:18:57 +0000",
        "Message-ID": "<1480436367-20749-26-git-send-email-arybchenko@solarflare.com>",
        "X-Mailer": "git-send-email 1.8.2.3",
        "In-Reply-To": "<1480436367-20749-1-git-send-email-arybchenko@solarflare.com>",
        "References": "<1479740470-6723-1-git-send-email-arybchenko@solarflare.com>\n\t<1480436367-20749-1-git-send-email-arybchenko@solarflare.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-AnalysisOut": [
            "[v=2.1 cv=UoJlQrEB c=1 sm=1 tr=0 a=8BlWFWvVlq5taO8ncb8nKg==]",
            "[:17 a=L24OOQBejmoA:10 a=zRKbQ67AAAAA:8 a=oK2piXy12vXre7btV]",
            "[f8A:9 a=2fpFcx1hTWp0U-_R:21 a=VIxwUnCJ__16ZQRO:21 a=jxLPmO]",
            "[af6ifyahUF:21 a=PA03WX8tBzeizutn5_OT:22]"
        ],
        "X-Spam": "[F=0.4097586523; CM=0.500; S=0.409(2015072901)]",
        "X-MAIL-FROM": "<arybchenko@solarflare.com>",
        "X-SOURCE-IP": "[12.187.104.26]",
        "Subject": "[dpdk-dev] [PATCH v2 25/55] net/sfc: import libefx support for Rx\n\tpacked stream mode",
        "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": "In packed stream mode, large buffers are provided to the NIC\ninto which many packets can be delivered. This reduces the\nnumber of queue refills needed compared to delivering every\npacket into a separate buffer.\n\nEFSYS_OPT_RX_PACKED_STREAM should be enabled to use it.\n\nFrom Solarflare Communications Inc.\n\nSigned-off-by: Andrew Rybchenko <arybchenko@solarflare.com>\n---\n drivers/net/sfc/base/ef10_ev.c   | 124 +++++++++++++++++++++++++++++++++++++++\n drivers/net/sfc/base/ef10_impl.h |  46 +++++++++++++++\n drivers/net/sfc/base/ef10_rx.c   | 114 +++++++++++++++++++++++++++++++++++\n drivers/net/sfc/base/efx.h       |  48 +++++++++++++++\n drivers/net/sfc/base/efx_check.h |   7 +++\n drivers/net/sfc/base/efx_impl.h  |  11 ++++\n drivers/net/sfc/base/efx_rx.c    |  84 ++++++++++++++++++++++++++\n 7 files changed, 434 insertions(+)",
    "diff": "diff --git a/drivers/net/sfc/base/ef10_ev.c b/drivers/net/sfc/base/ef10_ev.c\nindex e93b458..3522674 100644\n--- a/drivers/net/sfc/base/ef10_ev.c\n+++ b/drivers/net/sfc/base/ef10_ev.c\n@@ -759,6 +759,84 @@ ef10_ev_qstats_update(\n }\n #endif /* EFSYS_OPT_QSTATS */\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\n+static\t__checkReturn\tboolean_t\n+ef10_ev_rx_packed_stream(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__in\t\tconst efx_ev_callbacks_t *eecp,\n+\t__in_opt\tvoid *arg)\n+{\n+\tuint32_t label;\n+\tuint32_t next_read_lbits;\n+\tuint16_t flags;\n+\tboolean_t should_abort;\n+\tefx_evq_rxq_state_t *eersp;\n+\tunsigned int pkt_count;\n+\tunsigned int current_id;\n+\tboolean_t new_buffer;\n+\n+\tnext_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);\n+\tlabel = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);\n+\tnew_buffer = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_ROTATE);\n+\n+\tflags = 0;\n+\n+\teersp = &eep->ee_rxq_state[label];\n+\tpkt_count = (EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS) + 1 +\n+\t    next_read_lbits - eersp->eers_rx_stream_npackets) &\n+\t    EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);\n+\teersp->eers_rx_stream_npackets += pkt_count;\n+\n+\tif (new_buffer) {\n+\t\tflags |= EFX_PKT_PACKED_STREAM_NEW_BUFFER;\n+\t\tif (eersp->eers_rx_packed_stream_credits <\n+\t\t    EFX_RX_PACKED_STREAM_MAX_CREDITS)\n+\t\t\teersp->eers_rx_packed_stream_credits++;\n+\t\teersp->eers_rx_read_ptr++;\n+\t}\n+\tcurrent_id = eersp->eers_rx_read_ptr & eersp->eers_rx_mask;\n+\n+\t/* Check for errors that invalidate checksum and L3/L4 fields */\n+\tif (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {\n+\t\t/* RX frame truncated (error flag is misnamed) */\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);\n+\t\tflags |= EFX_DISCARD;\n+\t\tgoto deliver;\n+\t}\n+\tif (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {\n+\t\t/* Bad Ethernet frame CRC */\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);\n+\t\tflags |= EFX_DISCARD;\n+\t\tgoto deliver;\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE)) {\n+\t\tflags |= EFX_PKT_PACKED_STREAM_PARSE_INCOMPLETE;\n+\t\tgoto deliver;\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR))\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);\n+\n+\tif (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR))\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);\n+\n+deliver:\n+\t/* If we're not discarding the packet then it is ok */\n+\tif (~flags & EFX_DISCARD)\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_OK);\n+\n+\tEFSYS_ASSERT(eecp->eec_rx_ps != NULL);\n+\tshould_abort = eecp->eec_rx_ps(arg, label, current_id, pkt_count,\n+\t    flags);\n+\n+\treturn (should_abort);\n+}\n+\n+#endif /* EFSYS_OPT_RX_PACKED_STREAM */\n+\n static\t__checkReturn\tboolean_t\n ef10_ev_rx(\n \t__in\t\tefx_evq_t *eep,\n@@ -791,6 +869,15 @@ ef10_ev_rx(\n \tlabel = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);\n \teersp = &eep->ee_rxq_state[label];\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\t/*\n+\t * Packed stream events are very different,\n+\t * so handle them separately\n+\t */\n+\tif (eersp->eers_rx_packed_stream)\n+\t\treturn (ef10_ev_rx_packed_stream(eep, eqp, eecp, arg));\n+#endif\n+\n \tsize = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);\n \tnext_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);\n \teth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);\n@@ -1253,9 +1340,41 @@ ef10_ev_rxlabel_init(\n \n \tEFSYS_ASSERT3U(eersp->eers_rx_mask, ==, 0);\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\t/*\n+\t * For packed stream modes, the very first event will\n+\t * have a new buffer flag set, so it will be incremented,\n+\t * yielding the correct pointer. That results in a simpler\n+\t * code than trying to detect start-of-the-world condition\n+\t * in the event handler.\n+\t */\n+\teersp->eers_rx_read_ptr = packed_stream ? ~0 : 0;\n+#else\n \teersp->eers_rx_read_ptr = 0;\n+#endif\n \teersp->eers_rx_mask = erp->er_mask;\n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\teersp->eers_rx_stream_npackets = 0;\n+\teersp->eers_rx_packed_stream = packed_stream;\n+\tif (packed_stream) {\n+\t\teersp->eers_rx_packed_stream_credits = (eep->ee_mask + 1) /\n+\t\t    (EFX_RX_PACKED_STREAM_MEM_PER_CREDIT /\n+\t\t    EFX_RX_PACKED_STREAM_MIN_PACKET_SPACE);\n+\t\tEFSYS_ASSERT3U(eersp->eers_rx_packed_stream_credits, !=, 0);\n+\t\t/*\n+\t\t * A single credit is allocated to the queue when it is started.\n+\t\t * It is immediately spent by the first packet which has NEW\n+\t\t * BUFFER flag set, though, but still we shall take into\n+\t\t * account, as to not wrap around the maximum number of credits\n+\t\t * accidentally\n+\t\t */\n+\t\teersp->eers_rx_packed_stream_credits--;\n+\t\tEFSYS_ASSERT3U(eersp->eers_rx_packed_stream_credits, <=,\n+\t\t    EFX_RX_PACKED_STREAM_MAX_CREDITS);\n+\t}\n+#else\n \tEFSYS_ASSERT(!packed_stream);\n+#endif\n }\n \n \t\tvoid\n@@ -1272,6 +1391,11 @@ ef10_ev_rxlabel_fini(\n \n \teersp->eers_rx_read_ptr = 0;\n \teersp->eers_rx_mask = 0;\n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\teersp->eers_rx_stream_npackets = 0;\n+\teersp->eers_rx_packed_stream = B_FALSE;\n+\teersp->eers_rx_packed_stream_credits = 0;\n+#endif\n }\n \n #endif\t/* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */\ndiff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h\nindex 01c48c8..94706dc 100644\n--- a/drivers/net/sfc/base/ef10_impl.h\n+++ b/drivers/net/sfc/base/ef10_impl.h\n@@ -462,6 +462,22 @@ ef10_tx_qpush(\n \t__in\t\tunsigned int added,\n \t__in\t\tunsigned int pushed);\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+extern\t\t\tvoid\n+ef10_rx_qps_update_credits(\n+\t__in\tefx_rxq_t *erp);\n+\n+extern\t__checkReturn\tuint8_t *\n+ef10_rx_qps_packet_info(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in\t\tuint8_t *buffer,\n+\t__in\t\tuint32_t buffer_length,\n+\t__in\t\tuint32_t current_offset,\n+\t__out\t\tuint16_t *lengthp,\n+\t__out\t\tuint32_t *next_offsetp,\n+\t__out\t\tuint32_t *timestamp);\n+#endif\n+\n extern\t__checkReturn\tefx_rc_t\n ef10_tx_qpace(\n \t__in\t\tefx_txq_t *etp,\n@@ -844,6 +860,36 @@ ef10_external_port_mapping(\n \t__in\t\tuint32_t port,\n \t__out\t\tuint8_t *external_portp);\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\n+/* Data space per credit in packed stream mode */\n+#define\tEFX_RX_PACKED_STREAM_MEM_PER_CREDIT (1 << 16)\n+\n+/*\n+ * Received packets are always aligned at this boundary. Also there always\n+ * exists a gap of this size between packets.\n+ * (see SF-112241-TC, 4.5)\n+ */\n+#define\tEFX_RX_PACKED_STREAM_ALIGNMENT 64\n+\n+/*\n+ * Size of a pseudo-header prepended to received packets\n+ * in packed stream mode\n+ */\n+#define\tEFX_RX_PACKED_STREAM_RX_PREFIX_SIZE 8\n+\n+/* Minimum space for packet in packed stream mode */\n+#define\tEFX_RX_PACKED_STREAM_MIN_PACKET_SPACE\t\t     \\\n+\tP2ROUNDUP(EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE +\t     \\\n+\t\t  EFX_MAC_PDU_MIN +\t\t\t     \\\n+\t\t  EFX_RX_PACKED_STREAM_ALIGNMENT,\t     \\\n+\t\t  EFX_RX_PACKED_STREAM_ALIGNMENT)\n+\n+/* Maximum number of credits */\n+#define\tEFX_RX_PACKED_STREAM_MAX_CREDITS 127\n+\n+#endif /* EFSYS_OPT_RX_PACKED_STREAM */\n+\n #ifdef\t__cplusplus\n }\n #endif\ndiff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c\nindex 09a6314..2bcd823 100644\n--- a/drivers/net/sfc/base/ef10_rx.c\n+++ b/drivers/net/sfc/base/ef10_rx.c\n@@ -714,6 +714,81 @@ ef10_rx_qpush(\n \t\t\t    erp->er_index, &dword, B_FALSE);\n }\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\n+\t\t\tvoid\n+ef10_rx_qps_update_credits(\n+\t__in\tefx_rxq_t *erp)\n+{\n+\tefx_nic_t *enp = erp->er_enp;\n+\tefx_dword_t dword;\n+\tefx_evq_rxq_state_t *rxq_state =\n+\t\t&erp->er_eep->ee_rxq_state[erp->er_label];\n+\n+\tEFSYS_ASSERT(rxq_state->eers_rx_packed_stream);\n+\n+\tif (rxq_state->eers_rx_packed_stream_credits == 0)\n+\t\treturn;\n+\n+\tEFX_POPULATE_DWORD_3(dword,\n+\t    ERF_DZ_RX_DESC_MAGIC_DOORBELL, 1,\n+\t    ERF_DZ_RX_DESC_MAGIC_CMD,\n+\t    ERE_DZ_RX_DESC_MAGIC_CMD_PS_CREDITS,\n+\t    ERF_DZ_RX_DESC_MAGIC_DATA,\n+\t    rxq_state->eers_rx_packed_stream_credits);\n+\tEFX_BAR_TBL_WRITED(enp, ER_DZ_RX_DESC_UPD_REG,\n+\t    erp->er_index, &dword, B_FALSE);\n+\n+\trxq_state->eers_rx_packed_stream_credits = 0;\n+}\n+\n+\t__checkReturn\tuint8_t *\n+ef10_rx_qps_packet_info(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in\t\tuint8_t *buffer,\n+\t__in\t\tuint32_t buffer_length,\n+\t__in\t\tuint32_t current_offset,\n+\t__out\t\tuint16_t *lengthp,\n+\t__out\t\tuint32_t *next_offsetp,\n+\t__out\t\tuint32_t *timestamp)\n+{\n+\tuint16_t buf_len;\n+\tuint8_t *pkt_start;\n+\tefx_qword_t *qwordp;\n+\tefx_evq_rxq_state_t *rxq_state =\n+\t\t&erp->er_eep->ee_rxq_state[erp->er_label];\n+\n+\tEFSYS_ASSERT(rxq_state->eers_rx_packed_stream);\n+\n+\tbuffer += current_offset;\n+\tpkt_start = buffer + EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE;\n+\n+\tqwordp = (efx_qword_t *)buffer;\n+\t*timestamp = EFX_QWORD_FIELD(*qwordp, ES_DZ_PS_RX_PREFIX_TSTAMP);\n+\t*lengthp   = EFX_QWORD_FIELD(*qwordp, ES_DZ_PS_RX_PREFIX_ORIG_LEN);\n+\tbuf_len    = EFX_QWORD_FIELD(*qwordp, ES_DZ_PS_RX_PREFIX_CAP_LEN);\n+\n+\tbuf_len = P2ROUNDUP(buf_len + EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE,\n+\t\t\t    EFX_RX_PACKED_STREAM_ALIGNMENT);\n+\t*next_offsetp =\n+\t    current_offset + buf_len + EFX_RX_PACKED_STREAM_ALIGNMENT;\n+\n+\tEFSYS_ASSERT3U(*next_offsetp, <=, buffer_length);\n+\tEFSYS_ASSERT3U(current_offset + *lengthp, <, *next_offsetp);\n+\n+\tif ((*next_offsetp ^ current_offset) &\n+\t    EFX_RX_PACKED_STREAM_MEM_PER_CREDIT) {\n+\t\tif (rxq_state->eers_rx_packed_stream_credits <\n+\t\t    EFX_RX_PACKED_STREAM_MAX_CREDITS)\n+\t\t\trxq_state->eers_rx_packed_stream_credits++;\n+\t}\n+\n+\treturn (pkt_start);\n+}\n+\n+\n+#endif\n+\n \t__checkReturn\tefx_rc_t\n ef10_rx_qflush(\n \t__in\tefx_rxq_t *erp)\n@@ -781,12 +856,45 @@ ef10_rx_qcreate(\n \tcase EFX_RXQ_TYPE_SCATTER:\n \t\tps_buf_size = 0;\n \t\tbreak;\n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\tcase EFX_RXQ_TYPE_PACKED_STREAM_1M:\n+\t\tps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M;\n+\t\tbreak;\n+\tcase EFX_RXQ_TYPE_PACKED_STREAM_512K:\n+\t\tps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K;\n+\t\tbreak;\n+\tcase EFX_RXQ_TYPE_PACKED_STREAM_256K:\n+\t\tps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K;\n+\t\tbreak;\n+\tcase EFX_RXQ_TYPE_PACKED_STREAM_128K:\n+\t\tps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K;\n+\t\tbreak;\n+\tcase EFX_RXQ_TYPE_PACKED_STREAM_64K:\n+\t\tps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K;\n+\t\tbreak;\n+#endif /* EFSYS_OPT_RX_PACKED_STREAM */\n \tdefault:\n \t\trc = ENOTSUP;\n \t\tgoto fail3;\n \t}\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\tif (ps_buf_size != 0) {\n+\t\t/* Check if datapath firmware supports packed stream mode */\n+\t\tif (encp->enc_rx_packed_stream_supported == B_FALSE) {\n+\t\t\trc = ENOTSUP;\n+\t\t\tgoto fail4;\n+\t\t}\n+\t\t/* Check if packed stream allows configurable buffer sizes */\n+\t\tif ((type != EFX_RXQ_TYPE_PACKED_STREAM_1M) &&\n+\t\t    (encp->enc_rx_var_packed_stream_supported == B_FALSE)) {\n+\t\t\trc = ENOTSUP;\n+\t\t\tgoto fail5;\n+\t\t}\n+\t}\n+#else /* EFSYS_OPT_RX_PACKED_STREAM */\n \tEFSYS_ASSERT(ps_buf_size == 0);\n+#endif /* EFSYS_OPT_RX_PACKED_STREAM */\n \n \t/* Scatter can only be disabled if the firmware supports doing so */\n \tif (type == EFX_RXQ_TYPE_SCATTER)\n@@ -807,6 +915,12 @@ ef10_rx_qcreate(\n \n fail6:\n \tEFSYS_PROBE(fail6);\n+#if EFSYS_OPT_RX_PACKED_STREAM\n+fail5:\n+\tEFSYS_PROBE(fail5);\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+#endif /* EFSYS_OPT_RX_PACKED_STREAM */\n fail3:\n \tEFSYS_PROBE(fail3);\n fail2:\ndiff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h\nindex 700e45d..85fd6f1 100644\n--- a/drivers/net/sfc/base/efx.h\n+++ b/drivers/net/sfc/base/efx.h\n@@ -1419,6 +1419,28 @@ typedef\t__checkReturn\tboolean_t\n \t__in\t\tuint32_t size,\n \t__in\t\tuint16_t flags);\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\n+/*\n+ * Packed stream mode is documented in SF-112241-TC.\n+ * The general idea is that, instead of putting each incoming\n+ * packet into a separate buffer which is specified in a RX\n+ * descriptor, a large buffer is provided to the hardware and\n+ * packets are put there in a continuous stream.\n+ * The main advantage of such an approach is that RX queue refilling\n+ * happens much less frequently.\n+ */\n+\n+typedef\t__checkReturn\tboolean_t\n+(*efx_rx_ps_ev_t)(\n+\t__in_opt\tvoid *arg,\n+\t__in\t\tuint32_t label,\n+\t__in\t\tuint32_t id,\n+\t__in\t\tuint32_t pkt_count,\n+\t__in\t\tuint16_t flags);\n+\n+#endif\n+\n typedef\t__checkReturn\tboolean_t\n (*efx_tx_ev_t)(\n \t__in_opt\tvoid *arg,\n@@ -1508,6 +1530,9 @@ typedef __checkReturn\tboolean_t\n typedef struct efx_ev_callbacks_s {\n \tefx_initialized_ev_t\t\teec_initialized;\n \tefx_rx_ev_t\t\t\teec_rx;\n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\tefx_rx_ps_ev_t\t\t\teec_rx_ps;\n+#endif\n \tefx_tx_ev_t\t\t\teec_tx;\n \tefx_exception_ev_t\t\teec_exception;\n \tefx_rxq_flush_done_ev_t\t\teec_rxq_flush_done;\n@@ -1731,6 +1756,29 @@ efx_rx_qpush(\n \t__in\tunsigned int added,\n \t__inout\tunsigned int *pushedp);\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\n+/*\n+ * Fake length for RXQ descriptors in packed stream mode\n+ * to make hardware happy\n+ */\n+#define\tEFX_RXQ_PACKED_STREAM_FAKE_BUF_SIZE 32\n+\n+extern\t\t\tvoid\n+efx_rx_qps_update_credits(\n+\t__in\t\tefx_rxq_t *erp);\n+\n+extern\t__checkReturn\tuint8_t *\n+efx_rx_qps_packet_info(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in\t\tuint8_t *buffer,\n+\t__in\t\tuint32_t buffer_length,\n+\t__in\t\tuint32_t current_offset,\n+\t__out\t\tuint16_t *lengthp,\n+\t__out\t\tuint32_t *next_offsetp,\n+\t__out\t\tuint32_t *timestamp);\n+#endif\n+\n extern\t__checkReturn\tefx_rc_t\n efx_rx_qflush(\n \t__in\tefx_rxq_t *erp);\ndiff --git a/drivers/net/sfc/base/efx_check.h b/drivers/net/sfc/base/efx_check.h\nindex 35615e6..5522838 100644\n--- a/drivers/net/sfc/base/efx_check.h\n+++ b/drivers/net/sfc/base/efx_check.h\n@@ -305,4 +305,11 @@\n # endif\n #endif /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+/* Support packed stream mode */\n+# if !(EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)\n+#  error \"PACKED_STREAM requires HUNTINGTON or MEDFORD\"\n+# endif\n+#endif\n+\n #endif /* _SYS_EFX_CHECK_H */\ndiff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h\nindex c9d2d11..f563eda 100644\n--- a/drivers/net/sfc/base/efx_impl.h\n+++ b/drivers/net/sfc/base/efx_impl.h\n@@ -166,6 +166,12 @@ typedef struct efx_rx_ops_s {\n \t\t\t\t      unsigned int, unsigned int,\n \t\t\t\t      unsigned int);\n \tvoid\t\t(*erxo_qpush)(efx_rxq_t *, unsigned int, unsigned int *);\n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\tvoid\t\t(*erxo_qps_update_credits)(efx_rxq_t *);\n+\tuint8_t *\t(*erxo_qps_packet_info)(efx_rxq_t *, uint8_t *,\n+\t\t\t\t\t\tuint32_t, uint32_t,\n+\t\t\t\t\t\tuint16_t *, uint32_t *, uint32_t *);\n+#endif\n \tefx_rc_t\t(*erxo_qflush)(efx_rxq_t *);\n \tvoid\t\t(*erxo_qenable)(efx_rxq_t *);\n \tefx_rc_t\t(*erxo_qcreate)(efx_nic_t *enp, unsigned int,\n@@ -525,6 +531,11 @@ typedef\tboolean_t (*efx_ev_handler_t)(efx_evq_t *, efx_qword_t *,\n typedef struct efx_evq_rxq_state_s {\n \tunsigned int\t\t\teers_rx_read_ptr;\n \tunsigned int\t\t\teers_rx_mask;\n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\tunsigned int\t\t\teers_rx_stream_npackets;\n+\tboolean_t\t\t\teers_rx_packed_stream;\n+\tunsigned int\t\t\teers_rx_packed_stream_credits;\n+#endif\n } efx_evq_rxq_state_t;\n \n struct efx_evq_s {\ndiff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c\nindex 9a01b75..330d2aa 100644\n--- a/drivers/net/sfc/base/efx_rx.c\n+++ b/drivers/net/sfc/base/efx_rx.c\n@@ -98,6 +98,22 @@ siena_rx_qpush(\n \t__in\t\tunsigned int added,\n \t__inout\t\tunsigned int *pushedp);\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+static\t\tvoid\n+siena_rx_qps_update_credits(\n+\t__in\t\tefx_rxq_t *erp);\n+\n+static\t__checkReturn\tuint8_t *\n+siena_rx_qps_packet_info(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in\t\tuint8_t *buffer,\n+\t__in\t\tuint32_t buffer_length,\n+\t__in\t\tuint32_t current_offset,\n+\t__out\t\tuint16_t *lengthp,\n+\t__out\t\tuint32_t *next_offsetp,\n+\t__out\t\tuint32_t *timestamp);\n+#endif\n+\n static\t__checkReturn\tefx_rc_t\n siena_rx_qflush(\n \t__in\t\tefx_rxq_t *erp);\n@@ -141,6 +157,10 @@ static const efx_rx_ops_t __efx_rx_siena_ops = {\n \tsiena_rx_prefix_pktlen,\t\t\t/* erxo_prefix_pktlen */\n \tsiena_rx_qpost,\t\t\t\t/* erxo_qpost */\n \tsiena_rx_qpush,\t\t\t\t/* erxo_qpush */\n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\tsiena_rx_qps_update_credits,\t\t/* erxo_qps_update_credits */\n+\tsiena_rx_qps_packet_info,\t\t/* erxo_qps_packet_info */\n+#endif\n \tsiena_rx_qflush,\t\t\t/* erxo_qflush */\n \tsiena_rx_qenable,\t\t\t/* erxo_qenable */\n \tsiena_rx_qcreate,\t\t\t/* erxo_qcreate */\n@@ -164,6 +184,10 @@ static const efx_rx_ops_t __efx_rx_ef10_ops = {\n \tef10_rx_prefix_pktlen,\t\t\t/* erxo_prefix_pktlen */\n \tef10_rx_qpost,\t\t\t\t/* erxo_qpost */\n \tef10_rx_qpush,\t\t\t\t/* erxo_qpush */\n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\tef10_rx_qps_update_credits,\t\t/* erxo_qps_update_credits */\n+\tef10_rx_qps_packet_info,\t\t/* erxo_qps_packet_info */\n+#endif\n \tef10_rx_qflush,\t\t\t\t/* erxo_qflush */\n \tef10_rx_qenable,\t\t\t/* erxo_qenable */\n \tef10_rx_qcreate,\t\t\t/* erxo_qcreate */\n@@ -425,6 +449,40 @@ efx_rx_qpost(\n \terxop->erxo_qpost(erp, addrp, size, n, completed, added);\n }\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+\n+\t\t\tvoid\n+efx_rx_qps_update_credits(\n+\t__in\t\tefx_rxq_t *erp)\n+{\n+\tefx_nic_t *enp = erp->er_enp;\n+\tconst efx_rx_ops_t *erxop = enp->en_erxop;\n+\n+\tEFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);\n+\n+\terxop->erxo_qps_update_credits(erp);\n+}\n+\n+\t__checkReturn\tuint8_t *\n+efx_rx_qps_packet_info(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in\t\tuint8_t *buffer,\n+\t__in\t\tuint32_t buffer_length,\n+\t__in\t\tuint32_t current_offset,\n+\t__out\t\tuint16_t *lengthp,\n+\t__out\t\tuint32_t *next_offsetp,\n+\t__out\t\tuint32_t *timestamp)\n+{\n+\tefx_nic_t *enp = erp->er_enp;\n+\tconst efx_rx_ops_t *erxop = enp->en_erxop;\n+\n+\treturn (erxop->erxo_qps_packet_info(erp, buffer,\n+\t\tbuffer_length, current_offset, lengthp,\n+\t\tnext_offsetp, timestamp));\n+}\n+\n+#endif /* EFSYS_OPT_RX_PACKED_STREAM */\n+\n \t\t\tvoid\n efx_rx_qpush(\n \t__in\t\tefx_rxq_t *erp,\n@@ -1071,6 +1129,32 @@ siena_rx_qpush(\n \t\t\t    erp->er_index, &dword, B_FALSE);\n }\n \n+#if EFSYS_OPT_RX_PACKED_STREAM\n+static\t\tvoid\n+siena_rx_qps_update_credits(\n+\t__in\t\tefx_rxq_t *erp)\n+{\n+\t/* Not supported by Siena hardware */\n+\tEFSYS_ASSERT(0);\n+}\n+\n+static\t\tuint8_t *\n+siena_rx_qps_packet_info(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in\t\tuint8_t *buffer,\n+\t__in\t\tuint32_t buffer_length,\n+\t__in\t\tuint32_t current_offset,\n+\t__out\t\tuint16_t *lengthp,\n+\t__out\t\tuint32_t *next_offsetp,\n+\t__out\t\tuint32_t *timestamp)\n+{\n+\t/* Not supported by Siena hardware */\n+\tEFSYS_ASSERT(0);\n+\n+\treturn (NULL);\n+}\n+#endif /* EFSYS_OPT_RX_PACKED_STREAM */\n+\n static\t__checkReturn\tefx_rc_t\n siena_rx_qflush(\n \t__in\tefx_rxq_t *erp)\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "25/55"
    ]
}