Show a patch.

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

{
    "id": 246,
    "url": "https://patches.dpdk.org/api/patches/246/",
    "web_url": "https://patches.dpdk.org/patch/246/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/",
        "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"
    },
    "msgid": "<1409105634-29980-2-git-send-email-jingjing.wu@intel.com>",
    "date": "2014-08-27T02:13:48",
    "name": "[dpdk-dev,v2,1/7] i40e: flow director resource reserve and initialize on i40e",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "c8e3ea34fecbf75f80b8eb7eaa349badb0f9f2fb",
    "submitter": {
        "id": 47,
        "url": "https://patches.dpdk.org/api/people/47/",
        "name": "Wu, Jingjing",
        "email": "jingjing.wu@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/patch/246/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/246/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/246/checks/",
    "tags": {},
    "headers": {
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Date": "Wed, 27 Aug 2014 10:13:48 +0800",
        "In-Reply-To": "<1409105634-29980-1-git-send-email-jingjing.wu@intel.com>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "X-BeenThere": "dev@dpdk.org",
        "References": "<1409105634-29980-1-git-send-email-jingjing.wu@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "To": "dev@dpdk.org",
        "Received": [
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id 6757A58EE\n\tfor <dev@dpdk.org>; Wed, 27 Aug 2014 04:10:43 +0200 (CEST)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n\tby orsmga101.jf.intel.com with ESMTP; 26 Aug 2014 19:14:44 -0700",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby orsmga001.jf.intel.com with ESMTP; 26 Aug 2014 19:14:11 -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 s7R2EAFV005139;\n\tWed, 27 Aug 2014 10:14:10 +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 s7R2E7Ln030096; Wed, 27 Aug 2014 10:14:09 +0800",
            "(from wujingji@localhost)\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s7R2E70N030092; \n\tWed, 27 Aug 2014 10:14:07 +0800"
        ],
        "From": "Jingjing Wu <jingjing.wu@intel.com>",
        "Precedence": "list",
        "X-ExtLoop1": "1",
        "Message-Id": "<1409105634-29980-2-git-send-email-jingjing.wu@intel.com>",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "Subject": "[dpdk-dev] [PATCH v2 1/7] i40e: flow director resource reserve and\n\tinitialize on i40e",
        "X-List-Received-Date": "Wed, 27 Aug 2014 02:10:44 -0000",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "Return-Path": "<wujingji@shecgisg004.sh.intel.com>",
        "X-IronPort-AV": "E=Sophos;i=\"5.04,408,1406617200\"; d=\"scan'208\";a=\"563918846\"",
        "List-Post": "<mailto:dev@dpdk.org>",
        "X-Mailman-Version": "2.1.15"
    },
    "content": "flow director resource reserve and initialize on i40e, it includes\n - queue initialization and switch on and vsi creation during setup\n - queue vsi for flow director release during close\n \nSigned-off-by: jingjing.wu <jingjing.wu@intel.com>\nReviewed-by: Helin Zhang <helin.zhang@intel.com>\nReviewed-by: Jing Chen <jing.d.chen@intel.com>\nReviewed-by: Jijiang Liu <jijiang.liu@intel.com>\n\n---\n lib/librte_pmd_i40e/Makefile      |   1 +\n lib/librte_pmd_i40e/i40e_ethdev.c |  81 ++++++++++++---\n lib/librte_pmd_i40e/i40e_ethdev.h |  22 +++-\n lib/librte_pmd_i40e/i40e_fdir.c   | 208 ++++++++++++++++++++++++++++++++++++++\n lib/librte_pmd_i40e/i40e_rxtx.c   | 127 +++++++++++++++++++++++\n 5 files changed, 426 insertions(+), 13 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..6537654 100644\n--- a/lib/librte_pmd_i40e/Makefile\n+++ b/lib/librte_pmd_i40e/Makefile\n@@ -87,6 +87,7 @@ 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 # 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 4e65ca4..a08b43c 100644\n--- a/lib/librte_pmd_i40e/i40e_ethdev.c\n+++ b/lib/librte_pmd_i40e/i40e_ethdev.c\n@@ -523,7 +523,8 @@ eth_i40e_dev_init(__rte_unused struct eth_driver *eth_drv,\n \treturn 0;\n \n err_setup_pf_switch:\n-\trte_free(pf->main_vsi);\n+\ti40e_fdir_teardown(pf);\n+\ti40e_vsi_release(pf->main_vsi);\n err_get_mac_addr:\n err_configure_lan_hmc:\n \t(void)i40e_shutdown_lan_hmc(hw);\n@@ -780,6 +781,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@@ -845,6 +852,7 @@ i40e_dev_close(struct rte_eth_dev *dev)\n \ti40e_shutdown_lan_hmc(hw);\n \n \t/* release all the existing VSIs and VEBs */\n+\ti40e_fdir_teardown(pf);\n \ti40e_vsi_release(pf->main_vsi);\n \n \t/* shutdown the adminq */\n@@ -2584,16 +2592,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@@ -2725,8 +2747,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\");\n \t\tgoto fail_msix_alloc;\n \t}\n@@ -2912,8 +2950,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@@ -2923,9 +2969,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..c2c7fa9 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,16 @@ 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+};\n+\n+/*\n  * Structure to store private data specific for PF instance.\n  */\n struct i40e_pf {\n@@ -216,6 +227,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 +324,14 @@ 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\n+i40e_fdir_setup_tx_resources(struct i40e_pf *pf,\n+\t\t\t\t    unsigned int socket_id);\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+int i40e_fdir_setup(struct i40e_pf *pf);\n+void i40e_fdir_teardown(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..f6297a8\n--- /dev/null\n+++ b/lib/librte_pmd_i40e/i40e_fdir.c\n@@ -0,0 +1,208 @@\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_mbuf.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_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\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\");\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\");\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+\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\");\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\");\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\");\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\");\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\");\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\");\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\");\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\");\n+\t\tgoto fail_mem;\n+\t}\n+\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+fail_setup_rx:\n+\ti40e_dev_tx_queue_release(pf->fdir.txq);\n+fail_setup_tx:\n+\ti40e_vsi_release(vsi);\n+\treturn err;\n+}\n+\n+/*\n+ * i40e_fdir_teardown - release the Flow Director resources\n+ * @pf: board private structure\n+ */\n+void\n+i40e_fdir_teardown(struct i40e_pf *pf)\n+{\n+\tstruct i40e_vsi *vsi;\n+\n+\tvsi = pf->fdir.fdir_vsi;\n+\ti40e_dev_rx_queue_release(pf->fdir.rxq);\n+\tpf->fdir.rxq = NULL;\n+\ti40e_dev_tx_queue_release(pf->fdir.txq);\n+\tpf->fdir.txq = NULL;\n+\ti40e_vsi_release(vsi);\n+\tpf->fdir.fdir_vsi = NULL;\n+\treturn;\n+}\ndiff --git a/lib/librte_pmd_i40e/i40e_rxtx.c b/lib/librte_pmd_i40e/i40e_rxtx.c\nindex f153844..8bfbc8c 100644\n--- a/lib/librte_pmd_i40e/i40e_rxtx.c\n+++ b/lib/librte_pmd_i40e/i40e_rxtx.c\n@@ -2089,6 +2089,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@@ -2306,3 +2308,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",
        "v2",
        "1/7"
    ]
}