get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2462,
    "url": "https://patches.dpdk.org/api/patches/2462/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1421912305-2022-3-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": "<1421912305-2022-3-git-send-email-jingjing.wu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1421912305-2022-3-git-send-email-jingjing.wu@intel.com",
    "date": "2015-01-22T07:38:21",
    "name": "[dpdk-dev,v2,2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1471204c61236f2e2b4bc77d27d1788a2d1f2c25",
    "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/1421912305-2022-3-git-send-email-jingjing.wu@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/2462/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/2462/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 38A435A99;\n\tThu, 22 Jan 2015 08:38:47 +0100 (CET)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id 759895A99\n\tfor <dev@dpdk.org>; Thu, 22 Jan 2015 08:38:38 +0100 (CET)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby fmsmga102.fm.intel.com with ESMTP; 21 Jan 2015 23:38:36 -0800",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby fmsmga001.fm.intel.com with ESMTP; 21 Jan 2015 23:38:36 -0800",
            "from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com\n\t[10.239.29.89])\n\tby shvmail01.sh.intel.com with ESMTP id t0M7cXLH012787;\n\tThu, 22 Jan 2015 15:38:33 +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 t0M7cVxI002070; Thu, 22 Jan 2015 15:38:33 +0800",
            "(from wujingji@localhost)\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t0M7cVHI002066; \n\tThu, 22 Jan 2015 15:38:31 +0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.09,447,1418112000\"; d=\"scan'208\";a=\"654697510\"",
        "From": "Jingjing Wu <jingjing.wu@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Thu, 22 Jan 2015 15:38:21 +0800",
        "Message-Id": "<1421912305-2022-3-git-send-email-jingjing.wu@intel.com>",
        "X-Mailer": "git-send-email 1.7.4.1",
        "In-Reply-To": "<1421912305-2022-1-git-send-email-jingjing.wu@intel.com>",
        "References": "<1421286361-11504-1-git-send-email-jingjing.wu@intel.com>\n\t<1421912305-2022-1-git-send-email-jingjing.wu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 2/6] ixgbe: ntuple filter functions replace\n\told ones for 5tuple filter",
        "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": "This patch defines new functions dealing with ntuple filters which is\ncorresponding to 5tuple in HW.\nIt removes old functions which deal with 5tuple filters.\nNtuple filter ie dealt with through entrance ixgbe_dev_filter_ctrl.\n\nSigned-off-by: Jingjing Wu <jingjing.wu@intel.com>\n---\n lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 468 ++++++++++++++++++++++++++----------\n lib/librte_pmd_ixgbe/ixgbe_ethdev.h |  52 +++-\n 2 files changed, 389 insertions(+), 131 deletions(-)",
    "diff": "diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\nindex b58ec45..9f1ad5b 100644\n--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\n+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\n@@ -231,14 +231,18 @@ static int ixgbe_add_syn_filter(struct rte_eth_dev *dev,\n static int ixgbe_remove_syn_filter(struct rte_eth_dev *dev);\n static int ixgbe_get_syn_filter(struct rte_eth_dev *dev,\n \t\t\tstruct rte_syn_filter *filter, uint16_t *rx_queue);\n-static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,\n-\t\t\tstruct rte_5tuple_filter *filter, uint16_t rx_queue);\n-static int ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,\n-\t\t\tuint16_t index);\n-static int ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,\n-\t\t\tstruct rte_5tuple_filter *filter, uint16_t *rx_queue);\n-\n-static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);\n+static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,\n+\t\t\tstruct ixgbe_5tuple_filter *filter);\n+static void ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,\n+\t\t\tstruct ixgbe_5tuple_filter *filter);\n+static int ixgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,\n+\t\t\tstruct rte_eth_ntuple_filter *filter,\n+\t\t\tbool add);\n+static int ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,\n+\t\t\t\tenum rte_filter_op filter_op,\n+\t\t\t\tvoid *arg);\n+static int ixgbe_get_ntuple_filter(struct rte_eth_dev *dev,\n+\t\t\tstruct rte_eth_ntuple_filter *filter);\n static int ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,\n \t\t\tstruct rte_eth_ethertype_filter *filter,\n \t\t\tbool add);\n@@ -251,6 +255,7 @@ static int ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,\n \t\t     enum rte_filter_type filter_type,\n \t\t     enum rte_filter_op filter_op,\n \t\t     void *arg);\n+static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);\n \n /*\n  * Define VF Stats MACRO for Non \"cleared on read\" register\n@@ -386,9 +391,6 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {\n \t.add_syn_filter\t         = ixgbe_add_syn_filter,\n \t.remove_syn_filter       = ixgbe_remove_syn_filter,\n \t.get_syn_filter          = ixgbe_get_syn_filter,\n-\t.add_5tuple_filter       = ixgbe_add_5tuple_filter,\n-\t.remove_5tuple_filter    = ixgbe_remove_5tuple_filter,\n-\t.get_5tuple_filter       = ixgbe_get_5tuple_filter,\n \t.filter_ctrl             = ixgbe_dev_filter_ctrl,\n };\n \n@@ -736,6 +738,8 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,\n \t\tIXGBE_DEV_PRIVATE_TO_HWSTRIP_BITMAP(eth_dev->data->dev_private);\n \tstruct ixgbe_dcb_config *dcb_config =\n \t\tIXGBE_DEV_PRIVATE_TO_DCB_CFG(eth_dev->data->dev_private);\n+\tstruct ixgbe_filter_info *filter_info =\n+\t\tIXGBE_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);\n \tuint32_t ctrl_ext;\n \tuint16_t csum;\n \tint diag, i;\n@@ -917,6 +921,11 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,\n \t/* enable support intr */\n \tixgbe_enable_intr(eth_dev);\n \n+\t/* initialize 5tuple filter list */\n+\tTAILQ_INIT(&filter_info->fivetuple_list);\n+\tmemset(filter_info->fivetuple_mask, 0,\n+\t\tsizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);\n+\n \treturn 0;\n }\n \n@@ -1606,6 +1615,9 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)\n \t\tIXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \tstruct ixgbe_vf_info *vfinfo =\n \t\t*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);\n+\tstruct ixgbe_filter_info *filter_info =\n+\t\tIXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);\n+\tstruct ixgbe_5tuple_filter *p_5tuple, *p_5tuple_next;\n \tint vf;\n \n \tPMD_INIT_FUNC_TRACE();\n@@ -1635,6 +1647,18 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)\n \t/* Clear recorded link status */\n \tmemset(&link, 0, sizeof(link));\n \trte_ixgbe_dev_atomic_write_link_status(dev, &link);\n+\n+\t/* Remove all ntuple filters of the device */\n+\tfor (p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list);\n+\t     p_5tuple != NULL; p_5tuple = p_5tuple_next) {\n+\t\tp_5tuple_next = TAILQ_NEXT(p_5tuple, entries);\n+\t\tTAILQ_REMOVE(&filter_info->fivetuple_list,\n+\t\t\t     p_5tuple, entries);\n+\t\trte_free(p_5tuple);\n+\t}\n+\tmemset(filter_info->fivetuple_mask, 0,\n+\t\tsizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);\n+\n }\n \n /*\n@@ -3818,62 +3842,69 @@ revert_protocol_type(enum ixgbe_5tuple_protocol protocol)\n  *    - On failure, a negative value.\n  */\n static int\n-ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,\n-\t\t\tstruct rte_5tuple_filter *filter, uint16_t rx_queue)\n+ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,\n+\t\t\tstruct ixgbe_5tuple_filter *filter)\n {\n \tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\tuint32_t ftqf, sdpqf = 0;\n+\tstruct ixgbe_filter_info *filter_info =\n+\t\tIXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);\n+\tint i, idx, shift;\n+\tuint32_t ftqf, sdpqf;\n \tuint32_t l34timir = 0;\n \tuint8_t mask = 0xff;\n \n-\tif (hw->mac.type != ixgbe_mac_82599EB)\n+\t/*\n+\t * look for an unused 5tuple filter index,\n+\t * and insert the filter to list.\n+\t */\n+\tfor (i = 0; i < IXGBE_MAX_FTQF_FILTERS; i++) {\n+\t\tidx = i / UINT32_BIT;\n+\t\tshift = i % UINT32_BIT;\n+\t\tif (!(filter_info->fivetuple_mask[idx] & (1 << shift))) {\n+\t\t\tfilter_info->fivetuple_mask[idx] |= 1 << shift;\n+\t\t\tfilter->index = i;\n+\t\t\tTAILQ_INSERT_TAIL(&filter_info->fivetuple_list,\n+\t\t\t\t\t  filter,\n+\t\t\t\t\t  entries);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tif (i >= IXGBE_MAX_FTQF_FILTERS) {\n+\t\tPMD_DRV_LOG(ERR, \"5tuple filters are full.\");\n \t\treturn -ENOSYS;\n-\n-\tif (index >= IXGBE_MAX_FTQF_FILTERS ||\n-\t\trx_queue >= IXGBE_MAX_RX_QUEUE_NUM ||\n-\t\tfilter->priority > IXGBE_5TUPLE_MAX_PRI ||\n-\t\tfilter->priority < IXGBE_5TUPLE_MIN_PRI)\n-\t\treturn -EINVAL;  /* filter index is out of range. */\n-\n-\tif (filter->tcp_flags) {\n-\t\tPMD_INIT_LOG(INFO, \"82599EB not tcp flags in 5tuple\");\n-\t\treturn -EINVAL;\n \t}\n \n-\tftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));\n-\tif (ftqf & IXGBE_FTQF_QUEUE_ENABLE)\n-\t\treturn -EINVAL;  /* filter index is in use. */\n-\n-\tftqf = 0;\n-\tsdpqf = (uint32_t)(filter->dst_port << IXGBE_SDPQF_DSTPORT_SHIFT);\n-\tsdpqf = sdpqf | (filter->src_port & IXGBE_SDPQF_SRCPORT);\n+\tsdpqf = (uint32_t)(filter->filter_info.dst_port <<\n+\t\t\t\tIXGBE_SDPQF_DSTPORT_SHIFT);\n+\tsdpqf = sdpqf | (filter->filter_info.src_port & IXGBE_SDPQF_SRCPORT);\n \n-\tftqf |= (uint32_t)(convert_protocol_type(filter->protocol) &\n+\tftqf = (uint32_t)(filter->filter_info.proto &\n \t\tIXGBE_FTQF_PROTOCOL_MASK);\n-\tftqf |= (uint32_t)((filter->priority & IXGBE_FTQF_PRIORITY_MASK) <<\n-\t\tIXGBE_FTQF_PRIORITY_SHIFT);\n-\tif (filter->src_ip_mask == 0) /* 0 means compare. */\n+\tftqf |= (uint32_t)((filter->filter_info.priority &\n+\t\tIXGBE_FTQF_PRIORITY_MASK) << IXGBE_FTQF_PRIORITY_SHIFT);\n+\tif (filter->filter_info.src_ip_mask == 0) /* 0 means compare. */\n \t\tmask &= IXGBE_FTQF_SOURCE_ADDR_MASK;\n-\tif (filter->dst_ip_mask == 0)\n+\tif (filter->filter_info.dst_ip_mask == 0)\n \t\tmask &= IXGBE_FTQF_DEST_ADDR_MASK;\n-\tif (filter->src_port_mask == 0)\n+\tif (filter->filter_info.src_port_mask == 0)\n \t\tmask &= IXGBE_FTQF_SOURCE_PORT_MASK;\n-\tif (filter->dst_port_mask == 0)\n+\tif (filter->filter_info.dst_port_mask == 0)\n \t\tmask &= IXGBE_FTQF_DEST_PORT_MASK;\n-\tif (filter->protocol_mask == 0)\n+\tif (filter->filter_info.proto_mask == 0)\n \t\tmask &= IXGBE_FTQF_PROTOCOL_COMP_MASK;\n \tftqf |= mask << IXGBE_FTQF_5TUPLE_MASK_SHIFT;\n \tftqf |= IXGBE_FTQF_POOL_MASK_EN;\n \tftqf |= IXGBE_FTQF_QUEUE_ENABLE;\n \n-\tIXGBE_WRITE_REG(hw, IXGBE_DAQF(index), filter->dst_ip);\n-\tIXGBE_WRITE_REG(hw, IXGBE_SAQF(index), filter->src_ip);\n-\tIXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), sdpqf);\n-\tIXGBE_WRITE_REG(hw, IXGBE_FTQF(index), ftqf);\n+\tIXGBE_WRITE_REG(hw, IXGBE_DAQF(idx), filter->filter_info.dst_ip);\n+\tIXGBE_WRITE_REG(hw, IXGBE_SAQF(idx), filter->filter_info.src_ip);\n+\tIXGBE_WRITE_REG(hw, IXGBE_SDPQF(idx), sdpqf);\n+\tIXGBE_WRITE_REG(hw, IXGBE_FTQF(idx), ftqf);\n \n \tl34timir |= IXGBE_L34T_IMIR_RESERVE;\n-\tl34timir |= (uint32_t)(rx_queue << IXGBE_L34T_IMIR_QUEUE_SHIFT);\n-\tIXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), l34timir);\n+\tl34timir |= (uint32_t)(filter->queue <<\n+\t\t\t\tIXGBE_L34T_IMIR_QUEUE_SHIFT);\n+\tIXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(i), l34timir);\n \treturn 0;\n }\n \n@@ -3882,92 +3913,27 @@ ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,\n  *\n  * @param\n  * dev: Pointer to struct rte_eth_dev.\n- * index: the index the filter allocates.\n- *\n- * @return\n- *    - On success, zero.\n- *    - On failure, a negative value.\n+ * filter: the pointer of the filter will be removed.\n  */\n-static int\n+static void\n ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,\n-\t\t\tuint16_t index)\n+\t\t\tstruct ixgbe_5tuple_filter *filter)\n {\n \tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct ixgbe_filter_info *filter_info =\n+\t\tIXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);\n+\tuint16_t index = filter->index;\n \n-\tif (hw->mac.type != ixgbe_mac_82599EB)\n-\t\treturn -ENOSYS;\n-\n-\tif (index >= IXGBE_MAX_FTQF_FILTERS)\n-\t\treturn -EINVAL;  /* filter index is out of range. */\n+\tfilter_info->fivetuple_mask[index / UINT32_BIT] &=\n+\t\t\t\t\t~(1 << (index % UINT32_BIT));\n+\tTAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);\n+\trte_free(filter);\n \n \tIXGBE_WRITE_REG(hw, IXGBE_DAQF(index), 0);\n \tIXGBE_WRITE_REG(hw, IXGBE_SAQF(index), 0);\n \tIXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), 0);\n \tIXGBE_WRITE_REG(hw, IXGBE_FTQF(index), 0);\n \tIXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), 0);\n-\treturn 0;\n-}\n-\n-/*\n- * get a 5tuple filter\n- *\n- * @param\n- * dev: Pointer to struct rte_eth_dev.\n- * index: the index the filter allocates\n- * filter: ponter to the filter that returns.\n- * *rx_queue: pointer of the queue id the filter assigned to.\n- *\n- * @return\n- *    - On success, zero.\n- *    - On failure, a negative value.\n- */\n-static int\n-ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,\n-\t\t\tstruct rte_5tuple_filter *filter, uint16_t *rx_queue)\n-{\n-\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\tuint32_t sdpqf, ftqf, l34timir;\n-\tuint8_t mask;\n-\tenum ixgbe_5tuple_protocol proto;\n-\n-\tif (hw->mac.type != ixgbe_mac_82599EB)\n-\t\treturn -ENOSYS;\n-\n-\tif (index >= IXGBE_MAX_FTQF_FILTERS)\n-\t\treturn -EINVAL;  /* filter index is out of range. */\n-\n-\tftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));\n-\tif (ftqf & IXGBE_FTQF_QUEUE_ENABLE) {\n-\t\tproto = (enum ixgbe_5tuple_protocol)(ftqf & IXGBE_FTQF_PROTOCOL_MASK);\n-\t\tfilter->protocol = revert_protocol_type(proto);\n-\t\tfilter->priority = (ftqf >> IXGBE_FTQF_PRIORITY_SHIFT) &\n-\t\t\t\t\tIXGBE_FTQF_PRIORITY_MASK;\n-\t\tmask = (uint8_t)((ftqf >> IXGBE_FTQF_5TUPLE_MASK_SHIFT) &\n-\t\t\t\t\tIXGBE_FTQF_5TUPLE_MASK_MASK);\n-\t\tfilter->src_ip_mask =\n-\t\t\t(mask & IXGBE_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;\n-\t\tfilter->dst_ip_mask =\n-\t\t\t(mask & IXGBE_FTQF_DEST_ADDR_MASK) ? 1 : 0;\n-\t\tfilter->src_port_mask =\n-\t\t\t(mask & IXGBE_FTQF_SOURCE_PORT_MASK) ? 1 : 0;\n-\t\tfilter->dst_port_mask =\n-\t\t\t(mask & IXGBE_FTQF_DEST_PORT_MASK) ? 1 : 0;\n-\t\tfilter->protocol_mask =\n-\t\t\t(mask & IXGBE_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;\n-\n-\t\tsdpqf = IXGBE_READ_REG(hw, IXGBE_SDPQF(index));\n-\t\tfilter->dst_port = (sdpqf & IXGBE_SDPQF_DSTPORT) >>\n-\t\t\t\t\tIXGBE_SDPQF_DSTPORT_SHIFT;\n-\t\tfilter->src_port = sdpqf & IXGBE_SDPQF_SRCPORT;\n-\t\tfilter->dst_ip = IXGBE_READ_REG(hw, IXGBE_DAQF(index));\n-\t\tfilter->src_ip = IXGBE_READ_REG(hw, IXGBE_SAQF(index));\n-\n-\t\tl34timir = IXGBE_READ_REG(hw, IXGBE_L34T_IMIR(index));\n-\t\t*rx_queue = (l34timir & IXGBE_L34T_IMIR_QUEUE) >>\n-\t\t\t\t\tIXGBE_L34T_IMIR_QUEUE_SHIFT;\n-\t\treturn 0;\n-\t}\n-\treturn -ENOENT;\n }\n \n static int\n@@ -4004,6 +3970,263 @@ ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)\n \treturn 0;\n }\n \n+#define MAC_TYPE_FILTER_SUP_EXT(type)    do {\\\n+\tif ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540)\\\n+\t\treturn -ENOTSUP;\\\n+} while (0)\n+\n+static inline struct ixgbe_5tuple_filter *\n+ixgbe_5tuple_filter_lookup(struct ixgbe_5tuple_filter_list *filter_list,\n+\t\t\tstruct ixgbe_5tuple_filter_info *key)\n+{\n+\tstruct ixgbe_5tuple_filter *it;\n+\n+\tTAILQ_FOREACH(it, filter_list, entries) {\n+\t\tif (memcmp(key, &it->filter_info,\n+\t\t\tsizeof(struct ixgbe_5tuple_filter_info)) == 0) {\n+\t\t\treturn it;\n+\t\t}\n+\t}\n+\treturn NULL;\n+}\n+\n+/* translate elements in struct rte_eth_ntuple_filter to struct ixgbe_5tuple_filter_info*/\n+static inline int\n+ntuple_filter_to_5tuple(struct rte_eth_ntuple_filter *filter,\n+\t\t\tstruct ixgbe_5tuple_filter_info *filter_info)\n+{\n+\tif (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM ||\n+\t\tfilter->priority > IXGBE_5TUPLE_MAX_PRI ||\n+\t\tfilter->priority < IXGBE_5TUPLE_MIN_PRI)\n+\t\treturn -EINVAL;\n+\n+\tswitch (filter->dst_ip_mask) {\n+\tcase UINT32_MAX:\n+\t\tfilter_info->dst_ip_mask = 0;\n+\t\tfilter_info->dst_ip = filter->dst_ip;\n+\t\tbreak;\n+\tcase 0:\n+\t\tfilter_info->dst_ip_mask = 1;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"invalid dst_ip mask.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tswitch (filter->src_ip_mask) {\n+\tcase UINT32_MAX:\n+\t\tfilter_info->src_ip_mask = 0;\n+\t\tfilter_info->src_ip = filter->src_ip;\n+\t\tbreak;\n+\tcase 0:\n+\t\tfilter_info->src_ip_mask = 1;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"invalid src_ip mask.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tswitch (filter->dst_port_mask) {\n+\tcase UINT16_MAX:\n+\t\tfilter_info->dst_port_mask = 0;\n+\t\tfilter_info->dst_port = filter->dst_port;\n+\t\tbreak;\n+\tcase 0:\n+\t\tfilter_info->dst_port_mask = 1;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"invalid dst_port mask.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tswitch (filter->src_port_mask) {\n+\tcase UINT16_MAX:\n+\t\tfilter_info->src_port_mask = 0;\n+\t\tfilter_info->src_port = filter->src_port;\n+\t\tbreak;\n+\tcase 0:\n+\t\tfilter_info->src_port_mask = 1;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"invalid src_port mask.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tswitch (filter->proto_mask) {\n+\tcase UINT8_MAX:\n+\t\tfilter_info->proto_mask = 0;\n+\t\tfilter_info->proto =\n+\t\t\tconvert_protocol_type(filter->proto);\n+\t\tbreak;\n+\tcase 0:\n+\t\tfilter_info->proto_mask = 1;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"invalid protocol mask.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfilter_info->priority = (uint8_t)filter->priority;\n+\treturn 0;\n+}\n+\n+/*\n+ * add or delete a ntuple filter\n+ *\n+ * @param\n+ * dev: Pointer to struct rte_eth_dev.\n+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter\n+ * add: if true, add filter, if false, remove filter\n+ *\n+ * @return\n+ *    - On success, zero.\n+ *    - On failure, a negative value.\n+ */\n+static int\n+ixgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,\n+\t\t\tstruct rte_eth_ntuple_filter *ntuple_filter,\n+\t\t\tbool add)\n+{\n+\tstruct ixgbe_filter_info *filter_info =\n+\t\tIXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);\n+\tstruct ixgbe_5tuple_filter_info filter_5tuple;\n+\tstruct ixgbe_5tuple_filter *filter;\n+\tint ret;\n+\n+\tif (ntuple_filter->flags != RTE_5TUPLE_FLAGS) {\n+\t\tPMD_DRV_LOG(ERR, \"only 5tuple is supported.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(&filter_5tuple, 0, sizeof(struct ixgbe_5tuple_filter_info));\n+\tret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tfilter = ixgbe_5tuple_filter_lookup(&filter_info->fivetuple_list,\n+\t\t\t\t\t &filter_5tuple);\n+\tif (filter != NULL && add) {\n+\t\tPMD_DRV_LOG(ERR, \"filter exists.\");\n+\t\treturn -EEXIST;\n+\t}\n+\tif (filter == NULL && !add) {\n+\t\tPMD_DRV_LOG(ERR, \"filter doesn't exist.\");\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tif (add) {\n+\t\tfilter = rte_zmalloc(\"ixgbe_5tuple_filter\",\n+\t\t\t\tsizeof(struct ixgbe_5tuple_filter), 0);\n+\t\tif (filter == NULL)\n+\t\t\treturn -ENOMEM;\n+\t\t(void)rte_memcpy(&filter->filter_info,\n+\t\t\t\t &filter_5tuple,\n+\t\t\t\t sizeof(struct ixgbe_5tuple_filter_info));\n+\t\tfilter->queue = ntuple_filter->queue;\n+\t\tret = ixgbe_add_5tuple_filter(dev, filter);\n+\t\tif (ret < 0) {\n+\t\t\trte_free(filter);\n+\t\t\treturn ret;\n+\t\t}\n+\t} else\n+\t\tixgbe_remove_5tuple_filter(dev, filter);\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * get a ntuple filter\n+ *\n+ * @param\n+ * dev: Pointer to struct rte_eth_dev.\n+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter\n+ *\n+ * @return\n+ *    - On success, zero.\n+ *    - On failure, a negative value.\n+ */\n+static int\n+ixgbe_get_ntuple_filter(struct rte_eth_dev *dev,\n+\t\t\tstruct rte_eth_ntuple_filter *ntuple_filter)\n+{\n+\tstruct ixgbe_filter_info *filter_info =\n+\t\tIXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);\n+\tstruct ixgbe_5tuple_filter_info filter_5tuple;\n+\tstruct ixgbe_5tuple_filter *filter;\n+\tint ret;\n+\n+\tif (ntuple_filter->flags != RTE_5TUPLE_FLAGS) {\n+\t\tPMD_DRV_LOG(ERR, \"only 5tuple is supported.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(&filter_5tuple, 0, sizeof(struct ixgbe_5tuple_filter_info));\n+\tret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tfilter = ixgbe_5tuple_filter_lookup(&filter_info->fivetuple_list,\n+\t\t\t\t\t &filter_5tuple);\n+\tif (filter == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"filter doesn't exist.\");\n+\t\treturn -ENOENT;\n+\t}\n+\tntuple_filter->queue = filter->queue;\n+\treturn 0;\n+}\n+\n+/*\n+ * ixgbe_ntuple_filter_handle - Handle operations for ntuple filter.\n+ * @dev: pointer to rte_eth_dev structure\n+ * @filter_op:operation will be taken.\n+ * @arg: a pointer to specific structure corresponding to the filter_op\n+ *\n+ * @return\n+ *    - On success, zero.\n+ *    - On failure, a negative value.\n+ */\n+static int\n+ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,\n+\t\t\t\tenum rte_filter_op filter_op,\n+\t\t\t\tvoid *arg)\n+{\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tint ret;\n+\n+\tMAC_TYPE_FILTER_SUP_EXT(hw->mac.type);\n+\n+\tif (filter_op == RTE_ETH_FILTER_NOP)\n+\t\treturn 0;\n+\n+\tif (arg == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"arg shouldn't be NULL for operation %u.\",\n+\t\t\t    filter_op);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tswitch (filter_op) {\n+\tcase RTE_ETH_FILTER_ADD:\n+\t\tret = ixgbe_add_del_ntuple_filter(dev,\n+\t\t\t(struct rte_eth_ntuple_filter *)arg,\n+\t\t\tTRUE);\n+\t\tbreak;\n+\tcase RTE_ETH_FILTER_DELETE:\n+\t\tret = ixgbe_add_del_ntuple_filter(dev,\n+\t\t\t(struct rte_eth_ntuple_filter *)arg,\n+\t\t\tFALSE);\n+\t\tbreak;\n+\tcase RTE_ETH_FILTER_GET:\n+\t\tret = ixgbe_get_ntuple_filter(dev,\n+\t\t\t(struct rte_eth_ntuple_filter *)arg);\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"unsupported operation %u.\", filter_op);\n+\t\tret = -EINVAL;\n+\t\tbreak;\n+\t}\n+\treturn ret;\n+}\n+\n #define MAC_TYPE_FILTER_SUP(type)    do {\\\n \tif ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540 &&\\\n \t\t(type) != ixgbe_mac_X550)\\\n@@ -4205,6 +4428,9 @@ ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,\n \tint ret = -EINVAL;\n \n \tswitch (filter_type) {\n+\tcase RTE_ETH_FILTER_NTUPLE:\n+\t\tret = ixgbe_ntuple_filter_handle(dev, filter_op, arg);\n+\t\tbreak;\n \tcase RTE_ETH_FILTER_ETHERTYPE:\n \t\tret = ixgbe_ethertype_filter_handle(dev, filter_op, arg);\n \t\tbreak;\ndiff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h\nindex 677c257..2b3baef 100644\n--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h\n+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h\n@@ -163,12 +163,54 @@ struct ixgbe_vf_info {\n };\n \n /*\n+ *  Possible l4type of 5tuple filters.\n+ */\n+enum ixgbe_5tuple_protocol {\n+\tIXGBE_FILTER_PROTOCOL_TCP = 0,\n+\tIXGBE_FILTER_PROTOCOL_UDP,\n+\tIXGBE_FILTER_PROTOCOL_SCTP,\n+\tIXGBE_FILTER_PROTOCOL_NONE,\n+};\n+\n+TAILQ_HEAD(ixgbe_5tuple_filter_list, ixgbe_5tuple_filter);\n+\n+struct ixgbe_5tuple_filter_info {\n+\tuint32_t dst_ip;\n+\tuint32_t src_ip;\n+\tuint16_t dst_port;\n+\tuint16_t src_port;\n+\tenum ixgbe_5tuple_protocol proto;        /* l4 protocol. */\n+\tuint8_t priority;        /* seven levels (001b-111b), 111b is highest,\n+\t\t\t\t      used when more than one filter matches. */\n+\tuint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */\n+\t\tsrc_ip_mask:1,   /* if mask is 1b, do not compare src ip. */\n+\t\tdst_port_mask:1, /* if mask is 1b, do not compare dst port. */\n+\t\tsrc_port_mask:1, /* if mask is 1b, do not compare src port. */\n+\t\tproto_mask:1;    /* if mask is 1b, do not compare protocol. */\n+};\n+\n+/* 5tuple filter structure */\n+struct ixgbe_5tuple_filter {\n+\tTAILQ_ENTRY(ixgbe_5tuple_filter) entries;\n+\tuint16_t index;       /* the index of 5tuple filter */\n+\tstruct ixgbe_5tuple_filter_info filter_info;\n+\tuint16_t queue;       /* rx queue assigned to */\n+};\n+\n+#define UINT32_BIT 32\n+#define IXGBE_5TUPLE_ARRAY_SIZE \\\n+\t(RTE_ALIGN(IXGBE_MAX_FTQF_FILTERS, UINT32_BIT) / (UINT32_BIT))\n+\n+/*\n  * Structure to store filters' info.\n  */\n struct ixgbe_filter_info {\n \tuint8_t ethertype_mask;  /* Bit mask for every used ethertype filter */\n \t/* store used ethertype filters*/\n \tuint16_t ethertype_filters[IXGBE_MAX_ETQF_FILTERS];\n+\t/* Bit mask for every used 5tuple filter */\n+\tuint32_t fivetuple_mask[IXGBE_5TUPLE_ARRAY_SIZE];\n+\tstruct ixgbe_5tuple_filter_list fivetuple_list;\n };\n \n /*\n@@ -192,16 +234,6 @@ struct ixgbe_adapter {\n \tstruct ixgbe_filter_info    filter;\n };\n \n-/*\n- *  Possible l4type of 5tuple filters.\n- */\n-enum ixgbe_5tuple_protocol {\n-\tIXGBE_FILTER_PROTOCOL_TCP = 0,\n-\tIXGBE_FILTER_PROTOCOL_UDP,\n-\tIXGBE_FILTER_PROTOCOL_SCTP,\n-\tIXGBE_FILTER_PROTOCOL_NONE,\n-};\n-\n #define IXGBE_DEV_PRIVATE_TO_HW(adapter)\\\n \t(&((struct ixgbe_adapter *)adapter)->hw)\n \n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "2/6"
    ]
}