get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 541,
    "url": "https://patches.dpdk.org/api/patches/541/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1411711418-12881-2-git-send-email-jingjing.wu@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": "<1411711418-12881-2-git-send-email-jingjing.wu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1411711418-12881-2-git-send-email-jingjing.wu@intel.com",
    "date": "2014-09-26T06:03:19",
    "name": "[dpdk-dev,v3,01/20] i40e: set up and initialize flow director",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "bf578f9e27a4a05a7689fbd1a00dfcd43dc929cd",
    "submitter": {
        "id": 47,
        "url": "https://patches.dpdk.org/api/people/47/?format=api",
        "name": "Jingjing Wu",
        "email": "jingjing.wu@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1411711418-12881-2-git-send-email-jingjing.wu@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/541/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/541/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 444E47DEB;\n\tFri, 26 Sep 2014 07:57:30 +0200 (CEST)",
            "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n\tby dpdk.org (Postfix) with ESMTP id 07CAC678C\n\tfor <dev@dpdk.org>; Fri, 26 Sep 2014 07:57:27 +0200 (CEST)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga103.jf.intel.com with ESMTP; 25 Sep 2014 23:01:45 -0700",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby orsmga002.jf.intel.com with ESMTP; 25 Sep 2014 23:03:46 -0700",
            "from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com\n\t[10.239.29.89])\n\tby shvmail01.sh.intel.com with ESMTP id s8Q63iuD027969;\n\tFri, 26 Sep 2014 14:03:44 +0800",
            "from shecgisg004.sh.intel.com (localhost [127.0.0.1])\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP\n\tid s8Q63gZ6012923; Fri, 26 Sep 2014 14:03:44 +0800",
            "(from wujingji@localhost)\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s8Q63grm012919; \n\tFri, 26 Sep 2014 14:03:42 +0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.04,603,1406617200\"; d=\"scan'208\";a=\"608917271\"",
        "From": "Jingjing Wu <jingjing.wu@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri, 26 Sep 2014 14:03:19 +0800",
        "Message-Id": "<1411711418-12881-2-git-send-email-jingjing.wu@intel.com>",
        "X-Mailer": "git-send-email 1.7.4.1",
        "In-Reply-To": "<1411711418-12881-1-git-send-email-jingjing.wu@intel.com>",
        "References": "<1411711418-12881-1-git-send-email-jingjing.wu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3 01/20] i40e: set up and initialize flow\n\tdirector",
        "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": "set up fortville resources to support flow director, includes\n - queue 0 pair allocated and set up for flow director\n - create vsi\n - reserve memzone for flow director programming packet\n\nSigned-off-by: Jingjing Wu <jingjing.wu@intel.com>\nAcked-by: Chen Jing D(Mark) <jing.d.chen@intel.com>\nAcked-by: Helin Zhang <helin.zhang@intel.com>\n---\n lib/librte_pmd_i40e/Makefile      |   2 +\n lib/librte_pmd_i40e/i40e_ethdev.c |  77 +++++++++++--\n lib/librte_pmd_i40e/i40e_ethdev.h |  30 +++++-\n lib/librte_pmd_i40e/i40e_fdir.c   | 220 ++++++++++++++++++++++++++++++++++++++\n lib/librte_pmd_i40e/i40e_rxtx.c   | 127 ++++++++++++++++++++++\n 5 files changed, 444 insertions(+), 12 deletions(-)\n create mode 100644 lib/librte_pmd_i40e/i40e_fdir.c",
    "diff": "diff --git a/lib/librte_pmd_i40e/Makefile b/lib/librte_pmd_i40e/Makefile\nindex 4b31675..fdb9e26 100644\n--- a/lib/librte_pmd_i40e/Makefile\n+++ b/lib/librte_pmd_i40e/Makefile\n@@ -87,6 +87,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev.c\n SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_rxtx.c\n SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev_vf.c\n SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_pf.c\n+SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_fdir.c\n+\n # this lib depends upon:\n DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_eal lib/librte_ether\n DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_mempool lib/librte_mbuf\ndiff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c\nindex a00d6ca..d0413cb 100644\n--- a/lib/librte_pmd_i40e/i40e_ethdev.c\n+++ b/lib/librte_pmd_i40e/i40e_ethdev.c\n@@ -779,6 +779,12 @@ i40e_dev_start(struct rte_eth_dev *dev)\n \ti40e_vsi_queues_bind_intr(vsi);\n \ti40e_vsi_enable_queues_intr(vsi);\n \n+\t/* enable FDIR MSIX interrupt */\n+\tif (pf->flags & I40E_FLAG_FDIR) {\n+\t\ti40e_vsi_queues_bind_intr(pf->fdir.fdir_vsi);\n+\t\ti40e_vsi_enable_queues_intr(pf->fdir.fdir_vsi);\n+\t}\n+\n \t/* Enable all queues which have been configured */\n \tret = i40e_vsi_switch_queues(vsi, TRUE);\n \tif (ret != I40E_SUCCESS) {\n@@ -2587,16 +2593,30 @@ i40e_vsi_setup(struct i40e_pf *pf,\n \tcase I40E_VSI_SRIOV :\n \t\tvsi->nb_qps = pf->vf_nb_qps;\n \t\tbreak;\n+\tcase I40E_VSI_FDIR:\n+\t\tvsi->nb_qps = pf->fdir_nb_qps;\n+\t\tbreak;\n \tdefault:\n \t\tgoto fail_mem;\n \t}\n-\tret = i40e_res_pool_alloc(&pf->qp_pool, vsi->nb_qps);\n-\tif (ret < 0) {\n-\t\tPMD_DRV_LOG(ERR, \"VSI %d allocate queue failed %d\",\n-\t\t\t\tvsi->seid, ret);\n-\t\tgoto fail_mem;\n-\t}\n-\tvsi->base_queue = ret;\n+\t/*\n+\t * The filter status descriptor is reported in rx queue 0,\n+\t * while the tx queue for fdir filter programming has no\n+\t * such constraints, can be non-zero queues.\n+\t * To simplify it, choose FDIR vsi use queue 0 pair.\n+\t * To make sure it will use queue 0 pair, queue allocation\n+\t * need be done before this function is called\n+\t */\n+\tif (type != I40E_VSI_FDIR) {\n+\t\tret = i40e_res_pool_alloc(&pf->qp_pool, vsi->nb_qps);\n+\t\t\tif (ret < 0) {\n+\t\t\t\tPMD_DRV_LOG(ERR, \"VSI %d allocate queue failed %d\",\n+\t\t\t\t\t\tvsi->seid, ret);\n+\t\t\t\tgoto fail_mem;\n+\t\t\t}\n+\t\t\tvsi->base_queue = ret;\n+\t} else\n+\t\tvsi->base_queue = I40E_FDIR_QUEUE_ID;\n \n \t/* VF has MSIX interrupt in VF range, don't allocate here */\n \tif (type != I40E_VSI_SRIOV) {\n@@ -2728,8 +2748,24 @@ i40e_vsi_setup(struct i40e_pf *pf,\n \t\t * Since VSI is not created yet, only configure parameter,\n \t\t * will add vsi below.\n \t\t */\n-\t}\n-\telse {\n+\t} else if (type == I40E_VSI_FDIR) {\n+\t\tvsi->uplink_seid = uplink_vsi->uplink_seid;\n+\t\tctxt.pf_num = hw->pf_id;\n+\t\tctxt.vf_num = 0;\n+\t\tctxt.uplink_seid = vsi->uplink_seid;\n+\t\tctxt.connection_type = 0x1;     /* regular data port */\n+\t\tctxt.flags = I40E_AQ_VSI_TYPE_PF;\n+\t\tret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info,\n+\t\t\t\t\t\tI40E_DEFAULT_TCMAP);\n+\t\tif (ret != I40E_SUCCESS) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to configure \"\n+\t\t\t\t\t\"TC queue mapping\\n\");\n+\t\t\tgoto fail_msix_alloc;\n+\t\t}\n+\t\tctxt.info.up_enable_bits = I40E_DEFAULT_TCMAP;\n+\t\tctxt.info.valid_sections |=\n+\t\t\trte_cpu_to_le_16(I40E_AQ_VSI_PROP_SCHED_VALID);\n+\t} else {\n \t\tPMD_DRV_LOG(ERR, \"VSI: Not support other type VSI yet\");\n \t\tgoto fail_msix_alloc;\n \t}\n@@ -2915,8 +2951,16 @@ i40e_pf_setup(struct i40e_pf *pf)\n \t\tPMD_DRV_LOG(ERR, \"Could not get switch config, err %d\", ret);\n \t\treturn ret;\n \t}\n-\n-\t/* VSI setup */\n+\tif (pf->flags & I40E_FLAG_FDIR) {\n+\t\t/* make queue allocated first, let FDIR use queue pair 0*/\n+\t\tret = i40e_res_pool_alloc(&pf->qp_pool, I40E_DEFAULT_QP_NUM_FDIR);\n+\t\tif (ret != I40E_FDIR_QUEUE_ID) {\n+\t\t\tPMD_DRV_LOG(ERR, \"queue allocation fails for FDIR :\"\n+\t\t\t\t    \" ret =%d\", ret);\n+\t\t\tpf->flags &= ~I40E_FLAG_FDIR;\n+\t\t}\n+\t}\n+\t/*  main VSI setup */\n \tvsi = i40e_vsi_setup(pf, I40E_VSI_MAIN, NULL, 0);\n \tif (!vsi) {\n \t\tPMD_DRV_LOG(ERR, \"Setup of main vsi failed\");\n@@ -2926,9 +2970,20 @@ i40e_pf_setup(struct i40e_pf *pf)\n \tdev_data->nb_rx_queues = vsi->nb_qps;\n \tdev_data->nb_tx_queues = vsi->nb_qps;\n \n+\t/* setup FDIR after main vsi created.*/\n+\tif (pf->flags & I40E_FLAG_FDIR) {\n+\t\tret = i40e_fdir_setup(pf);\n+\t\tif (ret != I40E_SUCCESS) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to setup flow director\\n\");\n+\t\t\tpf->flags &= ~I40E_FLAG_FDIR;\n+\t\t}\n+\t}\n+\n \t/* Configure filter control */\n \tmemset(&settings, 0, sizeof(settings));\n \tsettings.hash_lut_size = I40E_HASH_LUT_SIZE_128;\n+\tif (pf->flags & I40E_FLAG_FDIR)\n+\t\tsettings.enable_fdir = TRUE;\n \t/* Enable ethtype and macvlan filters */\n \tsettings.enable_ethtype = TRUE;\n \tsettings.enable_macvlan = TRUE;\ndiff --git a/lib/librte_pmd_i40e/i40e_ethdev.h b/lib/librte_pmd_i40e/i40e_ethdev.h\nindex 64deef2..a2b1578 100644\n--- a/lib/librte_pmd_i40e/i40e_ethdev.h\n+++ b/lib/librte_pmd_i40e/i40e_ethdev.h\n@@ -46,11 +46,12 @@\n /* number of VSIs and queue default setting */\n #define I40E_MAX_QP_NUM_PER_VF    16\n #define I40E_DEFAULT_QP_NUM_VMDQ  64\n-#define I40E_DEFAULT_QP_NUM_FDIR  64\n+#define I40E_DEFAULT_QP_NUM_FDIR  1\n #define I40E_UINT32_BIT_SIZE      (CHAR_BIT * sizeof(uint32_t))\n #define I40E_VFTA_SIZE            (4096 / I40E_UINT32_BIT_SIZE)\n /* Default TC traffic in case DCB is not enabled */\n #define I40E_DEFAULT_TCMAP        0x1\n+#define I40E_FDIR_QUEUE_ID        0\n \n /* i40e flags */\n #define I40E_FLAG_RSS                   (1ULL << 0)\n@@ -189,6 +190,27 @@ struct i40e_pf_vf {\n };\n \n /*\n+ *  A structure used to define fields of a FDIR related info.\n+ */\n+struct i40e_fdir_info {\n+\tstruct i40e_vsi *fdir_vsi;     /* pointer to fdir VSI structure */\n+\tuint16_t match_counter_index;  /* Statistic counter index used for fdir*/\n+\tstruct i40e_tx_queue *txq;\n+\tstruct i40e_rx_queue *rxq;\n+\tvoid *prg_pkt;                 /* memory for fdir program packet */\n+\tuint64_t dma_addr;             /* physic address of packet memory*/\n+\t/*\n+\t * the rule how bytes stream is extracted as flexible payload\n+\t * for each payload layer, the setting can up to three elements\n+\t */\n+\tstruct {\n+\t\tuint8_t offset;        /* offset in words from the beginning of payload */\n+\t\tuint8_t size;          /* size in words */\n+\t} flex_set[3][3];\n+\n+};\n+\n+/*\n  * Structure to store private data specific for PF instance.\n  */\n struct i40e_pf {\n@@ -216,6 +238,7 @@ struct i40e_pf {\n \tuint16_t vmdq_nb_qps; /* The number of queue pairs of VMDq */\n \tuint16_t vf_nb_qps; /* The number of queue pairs of VF */\n \tuint16_t fdir_nb_qps; /* The number of queue pairs of Flow Director */\n+\tstruct i40e_fdir_info fdir; /* flow director info */\n };\n \n enum pending_msg {\n@@ -312,6 +335,11 @@ void i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi);\n int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,\n \t\t\t\tstruct i40e_vsi_vlan_pvid_info *info);\n int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on);\n+enum i40e_status_code i40e_fdir_setup_tx_resources(struct i40e_pf *pf,\n+\t\t\t\t    unsigned int socket_id);\n+enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf,\n+\t\t\t\t    unsigned int socket_id);\n+int i40e_fdir_setup(struct i40e_pf *pf);\n \n /* I40E_DEV_PRIVATE_TO */\n #define I40E_DEV_PRIVATE_TO_PF(adapter) \\\ndiff --git a/lib/librte_pmd_i40e/i40e_fdir.c b/lib/librte_pmd_i40e/i40e_fdir.c\nnew file mode 100644\nindex 0000000..5872494\n--- /dev/null\n+++ b/lib/librte_pmd_i40e/i40e_fdir.c\n@@ -0,0 +1,220 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2014 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+#include <sys/queue.h>\n+#include <stdio.h>\n+#include <errno.h>\n+#include <stdint.h>\n+#include <string.h>\n+#include <unistd.h>\n+#include <stdarg.h>\n+\n+#include <rte_ether.h>\n+#include <rte_ethdev.h>\n+#include <rte_log.h>\n+#include <rte_memzone.h>\n+#include <rte_malloc.h>\n+\n+#include \"i40e_logs.h\"\n+#include \"i40e/i40e_type.h\"\n+#include \"i40e_ethdev.h\"\n+#include \"i40e_rxtx.h\"\n+\n+#define I40E_FDIR_MZ_NAME          \"FDIR_MEMZONE\"\n+#define I40E_FDIR_PKT_LEN                   512\n+#define I40E_COUNTER_PF           2\n+/* Statistic counter index for one pf */\n+#define I40E_COUNTER_INDEX_FDIR(pf_id)   (0 + (pf_id) * I40E_COUNTER_PF)\n+\n+static int i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq);\n+\n+static int\n+i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq)\n+{\n+\tstruct i40e_hw *hw = I40E_VSI_TO_HW(rxq->vsi);\n+\tstruct i40e_hmc_obj_rxq rx_ctx;\n+\tint err = I40E_SUCCESS;\n+\n+\tmemset(&rx_ctx, 0, sizeof(struct i40e_hmc_obj_rxq));\n+\t/* Init the RX queue in hardware */\n+\trx_ctx.dbuff = I40E_RXBUF_SZ_1024 >> I40E_RXQ_CTX_DBUFF_SHIFT;\n+\trx_ctx.hbuff = 0;\n+\trx_ctx.base = rxq->rx_ring_phys_addr / I40E_QUEUE_BASE_ADDR_UNIT;\n+\trx_ctx.qlen = rxq->nb_rx_desc;\n+#ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC\n+\trx_ctx.dsize = 1;\n+#endif\n+\trx_ctx.dtype = i40e_header_split_none;\n+\trx_ctx.hsplit_0 = I40E_HEADER_SPLIT_NONE;\n+\trx_ctx.rxmax = ETHER_MAX_LEN;\n+\trx_ctx.tphrdesc_ena = 1;\n+\trx_ctx.tphwdesc_ena = 1;\n+\trx_ctx.tphdata_ena = 1;\n+\trx_ctx.tphhead_ena = 1;\n+\trx_ctx.lrxqthresh = 2;\n+\trx_ctx.crcstrip = 0;\n+\trx_ctx.l2tsel = 1;\n+\trx_ctx.showiv = 1;\n+\trx_ctx.prefena = 1;\n+\n+\terr = i40e_clear_lan_rx_queue_context(hw, rxq->reg_idx);\n+\tif (err != I40E_SUCCESS) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to clear FDIR RX queue context.\");\n+\t\treturn err;\n+\t}\n+\terr = i40e_set_lan_rx_queue_context(hw, rxq->reg_idx, &rx_ctx);\n+\tif (err != I40E_SUCCESS) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set FDIR RX queue context.\");\n+\t\treturn err;\n+\t}\n+\trxq->qrx_tail = hw->hw_addr +\n+\t\tI40E_QRX_TAIL(rxq->vsi->base_queue);\n+\n+\trte_wmb();\n+\t/* Init the RX tail regieter. */\n+\tI40E_PCI_REG_WRITE(rxq->qrx_tail, 0);\n+\tI40E_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1);\n+\n+\treturn err;\n+}\n+\n+/*\n+ * i40e_fdir_setup - reserve and initialize the Flow Director resources\n+ * @pf: board private structure\n+ */\n+int\n+i40e_fdir_setup(struct i40e_pf *pf)\n+{\n+\tstruct i40e_hw *hw = I40E_PF_TO_HW(pf);\n+\tstruct i40e_vsi *vsi;\n+\tint err = I40E_SUCCESS;\n+\tchar z_name[RTE_MEMZONE_NAMESIZE];\n+\tconst struct rte_memzone *mz = NULL;\n+\tstruct rte_eth_dev *eth_dev = pf->adapter->eth_dev;\n+\n+\tPMD_DRV_LOG(INFO, \"FDIR HW Capabilities: num_filters_guaranteed = %u,\"\n+\t\t\t\" num_filters_best_effort = %u.\\n\",\n+\t\t\thw->func_caps.fd_filters_guaranteed,\n+\t\t\thw->func_caps.fd_filters_best_effort);\n+\n+\tvsi = pf->fdir.fdir_vsi;\n+\tif (vsi) {\n+\t\tPMD_DRV_LOG(ERR, \"FDIR vsi pointer needs\"\n+\t\t\t\t \"to be null before creation.\");\n+\t\treturn I40E_ERR_BAD_PTR;\n+\t}\n+\t/* make new FDIR VSI */\n+\tvsi = i40e_vsi_setup(pf, I40E_VSI_FDIR, pf->main_vsi, 0);\n+\tif (!vsi) {\n+\t\tPMD_DRV_LOG(ERR, \"Couldn't create FDIR VSI.\");\n+\t\treturn I40E_ERR_NO_AVAILABLE_VSI;\n+\t}\n+\tpf->fdir.fdir_vsi = vsi;\n+\n+\t/*Fdir tx queue setup*/\n+\terr = i40e_fdir_setup_tx_resources(pf, 0);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup FDIR TX resources.\");\n+\t\tgoto fail_setup_tx;\n+\t}\n+\n+\t/*Fdir rx queue setup*/\n+\terr = i40e_fdir_setup_rx_resources(pf, 0);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup FDIR RX resources.\");\n+\t\tgoto fail_setup_rx;\n+\t}\n+\n+\terr = i40e_tx_queue_init(pf->fdir.txq);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to do FDIR TX initialization.\");\n+\t\tgoto fail_mem;\n+\t}\n+\n+\t/* need switch on before dev start*/\n+\terr = i40e_switch_tx_queue(hw, vsi->base_queue, TRUE);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to do fdir TX switch on.\");\n+\t\tgoto fail_mem;\n+\t}\n+\n+\t/* Init the rx queue in hardware */\n+\terr = i40e_fdir_rx_queue_init(pf->fdir.rxq);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to do FDIR RX initialization.\");\n+\t\tgoto fail_mem;\n+\t}\n+\n+\t/* switch on rx queue */\n+\terr = i40e_switch_rx_queue(hw, vsi->base_queue, TRUE);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to do FDIR RX switch on.\");\n+\t\tgoto fail_mem;\n+\t}\n+\n+\t/* reserve memory for the fdir programming packet */\n+\tsnprintf(z_name, sizeof(z_name), \"%s_%s_%d\",\n+\t\t\teth_dev->driver->pci_drv.name,\n+\t\t\tI40E_FDIR_MZ_NAME,\n+\t\t\teth_dev->data->port_id);\n+\tmz = rte_memzone_lookup(z_name);\n+\tif (!mz) {\n+\t\tmz = rte_memzone_reserve(z_name,\n+\t\t\t\tI40E_FDIR_PKT_LEN,\n+\t\t\t\trte_socket_id(),\n+\t\t\t\t0);\n+\t\tif (!mz) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Cannot init memzone for\"\n+\t\t\t\t\"flow director program packet.\");\n+\t\t\terr = I40E_ERR_NO_MEMORY;\n+\t\t\tgoto fail_mem;\n+\t\t}\n+\t}\n+\tpf->fdir.prg_pkt = mz->addr;\n+\tpf->fdir.dma_addr = (uint64_t)mz->phys_addr;\n+\tpf->fdir.match_counter_index = I40E_COUNTER_INDEX_FDIR(hw->pf_id);\n+\tPMD_DRV_LOG(INFO, \"FDIR setup successfully, with programming queue %u.\\n\",\n+\t\t    vsi->base_queue);\n+\treturn I40E_SUCCESS;\n+\n+fail_mem:\n+\ti40e_dev_rx_queue_release(pf->fdir.rxq);\n+\tpf->fdir.rxq = NULL;\n+fail_setup_rx:\n+\ti40e_dev_tx_queue_release(pf->fdir.txq);\n+\tpf->fdir.txq = NULL;\n+fail_setup_tx:\n+\ti40e_vsi_release(vsi);\n+\tpf->fdir.fdir_vsi = NULL;\n+\treturn err;\n+}\ndiff --git a/lib/librte_pmd_i40e/i40e_rxtx.c b/lib/librte_pmd_i40e/i40e_rxtx.c\nindex 099699c..4435367 100644\n--- a/lib/librte_pmd_i40e/i40e_rxtx.c\n+++ b/lib/librte_pmd_i40e/i40e_rxtx.c\n@@ -2107,6 +2107,8 @@ i40e_tx_queue_init(struct i40e_tx_queue *txq)\n \ttx_ctx.base = txq->tx_ring_phys_addr / I40E_QUEUE_BASE_ADDR_UNIT;\n \ttx_ctx.qlen = txq->nb_tx_desc;\n \ttx_ctx.rdylist = rte_le_to_cpu_16(vsi->info.qs_handle[0]);\n+\tif (vsi->type == I40E_VSI_FDIR)\n+\t\ttx_ctx.fd_ena = TRUE;\n \n \terr = i40e_clear_lan_tx_queue_context(hw, pf_q);\n \tif (err != I40E_SUCCESS) {\n@@ -2323,3 +2325,128 @@ i40e_dev_clear_queues(struct rte_eth_dev *dev)\n \t\ti40e_reset_rx_queue(dev->data->rx_queues[i]);\n \t}\n }\n+\n+enum i40e_status_code\n+i40e_fdir_setup_tx_resources(struct i40e_pf *pf,\n+\t\t\t\t    unsigned int socket_id)\n+{\n+\tstruct i40e_tx_queue *txq;\n+\tconst struct rte_memzone *tz = NULL;\n+\tuint32_t ring_size;\n+\tstruct rte_eth_dev *dev = pf->adapter->eth_dev;\n+\n+#define I40E_FDIR_NUM_TX_DESC  I40E_MIN_RING_DESC\n+\tif (!pf) {\n+\t\tPMD_DRV_LOG(ERR, \"PF is not available\");\n+\t\treturn I40E_ERR_BAD_PTR;\n+\t}\n+\n+\t/* Allocate the TX queue data structure. */\n+\ttxq = rte_zmalloc_socket(\"i40e fdir tx queue\",\n+\t\t\t\t  sizeof(struct i40e_tx_queue),\n+\t\t\t\t  CACHE_LINE_SIZE,\n+\t\t\t\t  socket_id);\n+\tif (!txq) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate memory for \"\n+\t\t\t\t\t\"tx queue structure\\n\");\n+\t\treturn I40E_ERR_NO_MEMORY;\n+\t}\n+\n+\t/* Allocate TX hardware ring descriptors. */\n+\tring_size = sizeof(struct i40e_tx_desc) * I40E_FDIR_NUM_TX_DESC;\n+\tring_size = RTE_ALIGN(ring_size, I40E_DMA_MEM_ALIGN);\n+\n+\ttz = i40e_ring_dma_zone_reserve(dev,\n+\t\t\t\t\t\"fdir_tx_ring\",\n+\t\t\t\t\tI40E_FDIR_QUEUE_ID,\n+\t\t\t\t\tring_size,\n+\t\t\t\t\tsocket_id);\n+\tif (!tz) {\n+\t\ti40e_dev_tx_queue_release(txq);\n+\t\tPMD_DRV_LOG(ERR, \"Failed to reserve DMA memory for TX\\n\");\n+\t\treturn I40E_ERR_NO_MEMORY;\n+\t}\n+\n+\ttxq->nb_tx_desc = I40E_FDIR_NUM_TX_DESC;\n+\ttxq->queue_id = I40E_FDIR_QUEUE_ID;\n+\ttxq->reg_idx = pf->fdir.fdir_vsi->base_queue;\n+\ttxq->vsi = pf->fdir.fdir_vsi;\n+\n+#ifdef RTE_LIBRTE_XEN_DOM0\n+\ttxq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);\n+#else\n+\ttxq->tx_ring_phys_addr = (uint64_t)tz->phys_addr;\n+#endif\n+\ttxq->tx_ring = (struct i40e_tx_desc *)tz->addr;\n+\t/*\n+\t * don't need to allocate software ring and reset for the fdir\n+\t * program queue just set the queue has been configured.\n+\t */\n+\ttxq->q_set = TRUE;\n+\tpf->fdir.txq = txq;\n+\n+\treturn I40E_SUCCESS;\n+}\n+\n+enum i40e_status_code\n+i40e_fdir_setup_rx_resources(struct i40e_pf *pf,\n+\t\t\t\t    unsigned int socket_id)\n+{\n+\tstruct i40e_rx_queue *rxq;\n+\tconst struct rte_memzone *rz = NULL;\n+\tuint32_t ring_size;\n+\tstruct rte_eth_dev *dev = pf->adapter->eth_dev;\n+\n+#define I40E_FDIR_NUM_RX_DESC  I40E_MIN_RING_DESC\n+\tif (!pf) {\n+\t\tPMD_DRV_LOG(ERR, \"PF is not available\");\n+\t\treturn I40E_ERR_BAD_PTR;\n+\t}\n+\n+\t/* Allocate the TX queue data structure. */\n+\trxq = rte_zmalloc_socket(\"i40e fdir rx queue\",\n+\t\t\t\t  sizeof(struct i40e_rx_queue),\n+\t\t\t\t  CACHE_LINE_SIZE,\n+\t\t\t\t  socket_id);\n+\tif (!rxq) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate memory for \"\n+\t\t\t\t\t\"rx queue structure\\n\");\n+\t\treturn I40E_ERR_NO_MEMORY;\n+\t}\n+\n+\t/* Allocate TX hardware ring descriptors. */\n+\tring_size = sizeof(union i40e_rx_desc) * I40E_FDIR_NUM_RX_DESC;\n+\tring_size = RTE_ALIGN(ring_size, I40E_DMA_MEM_ALIGN);\n+\n+\trz = i40e_ring_dma_zone_reserve(dev,\n+\t\t\t\t\t\"fdir_rx_ring\",\n+\t\t\t\t\tI40E_FDIR_QUEUE_ID,\n+\t\t\t\t\tring_size,\n+\t\t\t\t\tsocket_id);\n+\tif (!rz) {\n+\t\ti40e_dev_rx_queue_release(rxq);\n+\t\tPMD_DRV_LOG(ERR, \"Failed to reserve DMA memory for RX\\n\");\n+\t\treturn I40E_ERR_NO_MEMORY;\n+\t}\n+\n+\trxq->nb_rx_desc = I40E_FDIR_NUM_RX_DESC;\n+\trxq->queue_id = I40E_FDIR_QUEUE_ID;\n+\trxq->reg_idx = pf->fdir.fdir_vsi->base_queue;\n+\trxq->vsi = pf->fdir.fdir_vsi;\n+\n+#ifdef RTE_LIBRTE_XEN_DOM0\n+\trxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);\n+#else\n+\trxq->rx_ring_phys_addr = (uint64_t)rz->phys_addr;\n+#endif\n+\trxq->rx_ring = (union i40e_rx_desc *)rz->addr;\n+\n+\t/*\n+\t * Don't need to allocate software ring and reset for the fdir\n+\t * rx queue, just set the queue has been configured.\n+\t */\n+\trxq->q_set = TRUE;\n+\tpf->fdir.rxq = rxq;\n+\n+\treturn I40E_SUCCESS;\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "01/20"
    ]
}