get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 40931,
    "url": "https://patches.dpdk.org/api/patches/40931/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/cac38d5add2eda08f19c4f124b2849013dd89b53.1528469677.git.rahul.lakkireddy@chelsio.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": "<cac38d5add2eda08f19c4f124b2849013dd89b53.1528469677.git.rahul.lakkireddy@chelsio.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/cac38d5add2eda08f19c4f124b2849013dd89b53.1528469677.git.rahul.lakkireddy@chelsio.com",
    "date": "2018-06-08T17:58:16",
    "name": "[dpdk-dev,6/7] net/cxgbe: implement flow query operation",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "05f581cc25a9727ff7d69e6330733d5e3f69dc51",
    "submitter": {
        "id": 241,
        "url": "https://patches.dpdk.org/api/people/241/?format=api",
        "name": "Rahul Lakkireddy",
        "email": "rahul.lakkireddy@chelsio.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/cac38d5add2eda08f19c4f124b2849013dd89b53.1528469677.git.rahul.lakkireddy@chelsio.com/mbox/",
    "series": [
        {
            "id": 63,
            "url": "https://patches.dpdk.org/api/series/63/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=63",
            "date": "2018-06-08T17:58:10",
            "name": "cxgbe: add support to offload flows via rte_flow",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/63/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/40931/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/40931/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 [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 60F0C1D013;\n\tFri,  8 Jun 2018 19:59:38 +0200 (CEST)",
            "from stargate.chelsio.com (stargate.chelsio.com [12.32.117.8])\n\tby dpdk.org (Postfix) with ESMTP id 7840E1BB89\n\tfor <dev@dpdk.org>; Fri,  8 Jun 2018 19:59:36 +0200 (CEST)",
            "from localhost (scalar.blr.asicdesigners.com [10.193.185.94])\n\tby stargate.chelsio.com (8.13.8/8.13.8) with ESMTP id w58HxXwU017303; \n\tFri, 8 Jun 2018 10:59:34 -0700"
        ],
        "From": "Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>",
        "To": "dev@dpdk.org",
        "Cc": "shaguna@chelsio.com, kumaras@chelsio.com, indranil@chelsio.com,\n\tnirranjan@chelsio.com",
        "Date": "Fri,  8 Jun 2018 23:28:16 +0530",
        "Message-Id": "<cac38d5add2eda08f19c4f124b2849013dd89b53.1528469677.git.rahul.lakkireddy@chelsio.com>",
        "X-Mailer": "git-send-email 2.5.3",
        "In-Reply-To": [
            "<cover.1528469677.git.rahul.lakkireddy@chelsio.com>",
            "<cover.1528469677.git.rahul.lakkireddy@chelsio.com>"
        ],
        "References": [
            "<cover.1528469677.git.rahul.lakkireddy@chelsio.com>",
            "<cover.1528469677.git.rahul.lakkireddy@chelsio.com>"
        ],
        "Subject": "[dpdk-dev] [PATCH 6/7] net/cxgbe: implement flow query operation",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://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": "<https://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": "From: Shagun Agrawal <shaguna@chelsio.com>\n\nAdd API to query filter hit and byte counts from hardware.\n\nSigned-off-by: Shagun Agrawal <shaguna@chelsio.com>\nSigned-off-by: Kumar Sanghvi <kumaras@chelsio.com>\nSigned-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>\n---\n drivers/net/cxgbe/base/adapter.h |   1 +\n drivers/net/cxgbe/base/common.h  |  15 +++\n drivers/net/cxgbe/base/t4_hw.c   | 209 +++++++++++++++++++++++++++++++++++++++\n drivers/net/cxgbe/base/t4_hw.h   |   4 +\n drivers/net/cxgbe/base/t4_regs.h |  16 +++\n drivers/net/cxgbe/cxgbe_filter.c |  62 ++++++++++++\n drivers/net/cxgbe/cxgbe_filter.h |   2 +\n drivers/net/cxgbe/cxgbe_flow.c   |  62 +++++++++++-\n drivers/net/cxgbe/cxgbe_main.c   |   1 +\n 9 files changed, 371 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h\nindex 7f9ddae01..de46ecfe3 100644\n--- a/drivers/net/cxgbe/base/adapter.h\n+++ b/drivers/net/cxgbe/base/adapter.h\n@@ -319,6 +319,7 @@ struct adapter {\n \tunsigned int vpd_flag;\n \n \tint use_unpacked_mode; /* unpacked rx mode state */\n+\trte_spinlock_t win0_lock;\n \n \tstruct tid_info tids;     /* Info used to access TID related tables */\n };\ndiff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h\nindex c80304b24..e524f7931 100644\n--- a/drivers/net/cxgbe/base/common.h\n+++ b/drivers/net/cxgbe/base/common.h\n@@ -18,6 +18,9 @@ extern \"C\" {\n \n #define CXGBE_PAGE_SIZE RTE_PGSIZE_4K\n \n+#define T4_MEMORY_WRITE 0\n+#define T4_MEMORY_READ  1\n+\n enum {\n \tMAX_NPORTS     = 4,     /* max # of ports */\n };\n@@ -47,6 +50,8 @@ enum cc_fec {\n \tFEC_BASER_RS = 1 << 2,    /* BaseR/Reed-Solomon */\n };\n \n+enum { MEM_EDC0, MEM_EDC1, MEM_MC, MEM_MC0 = MEM_MC, MEM_MC1 };\n+\n struct port_stats {\n \tu64 tx_octets;            /* total # of octets in good frames */\n \tu64 tx_frames;            /* all good frames */\n@@ -502,5 +507,15 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size);\n int t4_seeprom_read(struct adapter *adapter, u32 addr, u32 *data);\n int t4_seeprom_write(struct adapter *adapter, u32 addr, u32 data);\n int t4_seeprom_wp(struct adapter *adapter, int enable);\n+int t4_memory_rw_addr(struct adapter *adap, int win,\n+\t\t      u32 addr, u32 len, void *hbuf, int dir);\n+int t4_memory_rw_mtype(struct adapter *adap, int win, int mtype, u32 maddr,\n+\t\t       u32 len, void *hbuf, int dir);\n+static inline int t4_memory_rw(struct adapter *adap, int win,\n+\t\t\t       int mtype, u32 maddr, u32 len,\n+\t\t\t       void *hbuf, int dir)\n+{\n+\treturn t4_memory_rw_mtype(adap, win, mtype, maddr, len, hbuf, dir);\n+}\n fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16);\n #endif /* __CHELSIO_COMMON_H */\ndiff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c\nindex c146c911e..66d080476 100644\n--- a/drivers/net/cxgbe/base/t4_hw.c\n+++ b/drivers/net/cxgbe/base/t4_hw.c\n@@ -5215,3 +5215,212 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)\n \t}\n \treturn 0;\n }\n+\n+/**\n+ * t4_memory_rw_addr - read/write adapter memory via PCIE memory window\n+ * @adap: the adapter\n+ * @win: PCI-E Memory Window to use\n+ * @addr: address within adapter memory\n+ * @len: amount of memory to transfer\n+ * @hbuf: host memory buffer\n+ * @dir: direction of transfer T4_MEMORY_READ (1) or T4_MEMORY_WRITE (0)\n+ *\n+ * Reads/writes an [almost] arbitrary memory region in the firmware: the\n+ * firmware memory address and host buffer must be aligned on 32-bit\n+ * boudaries; the length may be arbitrary.\n+ *\n+ * NOTES:\n+ *  1. The memory is transferred as a raw byte sequence from/to the\n+ *     firmware's memory.  If this memory contains data structures which\n+ *     contain multi-byte integers, it's the caller's responsibility to\n+ *     perform appropriate byte order conversions.\n+ *\n+ *  2. It is the Caller's responsibility to ensure that no other code\n+ *     uses the specified PCI-E Memory Window while this routine is\n+ *     using it.  This is typically done via the use of OS-specific\n+ *     locks, etc.\n+ */\n+int t4_memory_rw_addr(struct adapter *adap, int win, u32 addr,\n+\t\t      u32 len, void *hbuf, int dir)\n+{\n+\tu32 pos, offset, resid;\n+\tu32 win_pf, mem_reg, mem_aperture, mem_base;\n+\tu32 *buf;\n+\n+\t/* Argument sanity checks ...*/\n+\tif (addr & 0x3 || (uintptr_t)hbuf & 0x3)\n+\t\treturn -EINVAL;\n+\tbuf = (u32 *)hbuf;\n+\n+\t/* It's convenient to be able to handle lengths which aren't a\n+\t * multiple of 32-bits because we often end up transferring files to\n+\t * the firmware.  So we'll handle that by normalizing the length here\n+\t * and then handling any residual transfer at the end.\n+\t */\n+\tresid = len & 0x3;\n+\tlen -= resid;\n+\n+\t/* Each PCI-E Memory Window is programmed with a window size -- or\n+\t * \"aperture\" -- which controls the granularity of its mapping onto\n+\t * adapter memory.  We need to grab that aperture in order to know\n+\t * how to use the specified window.  The window is also programmed\n+\t * with the base address of the Memory Window in BAR0's address\n+\t * space.  For T4 this is an absolute PCI-E Bus Address.  For T5\n+\t * the address is relative to BAR0.\n+\t */\n+\tmem_reg = t4_read_reg(adap,\n+\t\t\t      PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_BASE_WIN,\n+\t\t\t\t\t\t  win));\n+\tmem_aperture = 1 << (G_WINDOW(mem_reg) + X_WINDOW_SHIFT);\n+\tmem_base = G_PCIEOFST(mem_reg) << X_PCIEOFST_SHIFT;\n+\n+\twin_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->pf);\n+\n+\t/* Calculate our initial PCI-E Memory Window Position and Offset into\n+\t * that Window.\n+\t */\n+\tpos = addr & ~(mem_aperture - 1);\n+\toffset = addr - pos;\n+\n+\t/* Set up initial PCI-E Memory Window to cover the start of our\n+\t * transfer.  (Read it back to ensure that changes propagate before we\n+\t * attempt to use the new value.)\n+\t */\n+\tt4_write_reg(adap,\n+\t\t     PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET, win),\n+\t\t     pos | win_pf);\n+\tt4_read_reg(adap,\n+\t\t    PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET, win));\n+\n+\t/* Transfer data to/from the adapter as long as there's an integral\n+\t * number of 32-bit transfers to complete.\n+\t *\n+\t * A note on Endianness issues:\n+\t *\n+\t * The \"register\" reads and writes below from/to the PCI-E Memory\n+\t * Window invoke the standard adapter Big-Endian to PCI-E Link\n+\t * Little-Endian \"swizzel.\"  As a result, if we have the following\n+\t * data in adapter memory:\n+\t *\n+\t *     Memory:  ... | b0 | b1 | b2 | b3 | ...\n+\t *     Address:      i+0  i+1  i+2  i+3\n+\t *\n+\t * Then a read of the adapter memory via the PCI-E Memory Window\n+\t * will yield:\n+\t *\n+\t *     x = readl(i)\n+\t *         31                  0\n+\t *         [ b3 | b2 | b1 | b0 ]\n+\t *\n+\t * If this value is stored into local memory on a Little-Endian system\n+\t * it will show up correctly in local memory as:\n+\t *\n+\t *     ( ..., b0, b1, b2, b3, ... )\n+\t *\n+\t * But on a Big-Endian system, the store will show up in memory\n+\t * incorrectly swizzled as:\n+\t *\n+\t *     ( ..., b3, b2, b1, b0, ... )\n+\t *\n+\t * So we need to account for this in the reads and writes to the\n+\t * PCI-E Memory Window below by undoing the register read/write\n+\t * swizzels.\n+\t */\n+\twhile (len > 0) {\n+\t\tif (dir == T4_MEMORY_READ)\n+\t\t\t*buf++ = le32_to_cpu((__le32)t4_read_reg(adap,\n+\t\t\t\t\t\t\t\t mem_base +\n+\t\t\t\t\t\t\t\t offset));\n+\t\telse\n+\t\t\tt4_write_reg(adap, mem_base + offset,\n+\t\t\t\t     (u32)cpu_to_le32(*buf++));\n+\t\toffset += sizeof(__be32);\n+\t\tlen -= sizeof(__be32);\n+\n+\t\t/* If we've reached the end of our current window aperture,\n+\t\t * move the PCI-E Memory Window on to the next.  Note that\n+\t\t * doing this here after \"len\" may be 0 allows us to set up\n+\t\t * the PCI-E Memory Window for a possible final residual\n+\t\t * transfer below ...\n+\t\t */\n+\t\tif (offset == mem_aperture) {\n+\t\t\tpos += mem_aperture;\n+\t\t\toffset = 0;\n+\t\t\tt4_write_reg(adap,\n+\t\t\t\tPCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET,\n+\t\t\t\t\t\t    win), pos | win_pf);\n+\t\t\tt4_read_reg(adap,\n+\t\t\t\tPCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET,\n+\t\t\t\t\t\t    win));\n+\t\t}\n+\t}\n+\n+\t/* If the original transfer had a length which wasn't a multiple of\n+\t * 32-bits, now's where we need to finish off the transfer of the\n+\t * residual amount.  The PCI-E Memory Window has already been moved\n+\t * above (if necessary) to cover this final transfer.\n+\t */\n+\tif (resid) {\n+\t\tunion {\n+\t\t\tu32 word;\n+\t\t\tchar byte[4];\n+\t\t} last;\n+\t\tunsigned char *bp;\n+\t\tint i;\n+\n+\t\tif (dir == T4_MEMORY_READ) {\n+\t\t\tlast.word = le32_to_cpu((__le32)t4_read_reg(adap,\n+\t\t\t\t\t\t\t\t    mem_base +\n+\t\t\t\t\t\t\t\t    offset));\n+\t\t\tfor (bp = (unsigned char *)buf, i = resid; i < 4; i++)\n+\t\t\t\tbp[i] = last.byte[i];\n+\t\t} else {\n+\t\t\tlast.word = *buf;\n+\t\t\tfor (i = resid; i < 4; i++)\n+\t\t\t\tlast.byte[i] = 0;\n+\t\t\tt4_write_reg(adap, mem_base + offset,\n+\t\t\t\t     (u32)cpu_to_le32(last.word));\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * t4_memory_rw_mtype -read/write EDC 0, EDC 1 or MC via PCIE memory window\n+ * @adap: the adapter\n+ * @win: PCI-E Memory Window to use\n+ * @mtype: memory type: MEM_EDC0, MEM_EDC1 or MEM_MC\n+ * @maddr: address within indicated memory type\n+ * @len: amount of memory to transfer\n+ * @hbuf: host memory buffer\n+ * @dir: direction of transfer T4_MEMORY_READ (1) or T4_MEMORY_WRITE (0)\n+ *\n+ * Reads/writes adapter memory using t4_memory_rw_addr().  This routine\n+ * provides an (memory type, address within memory type) interface.\n+ */\n+int t4_memory_rw_mtype(struct adapter *adap, int win, int mtype, u32 maddr,\n+\t\t       u32 len, void *hbuf, int dir)\n+{\n+\tu32 mtype_offset;\n+\tu32 edc_size, mc_size;\n+\n+\t/* Offset into the region of memory which is being accessed\n+\t * MEM_EDC0 = 0\n+\t * MEM_EDC1 = 1\n+\t * MEM_MC   = 2 -- MEM_MC for chips with only 1 memory controller\n+\t * MEM_MC1  = 3 -- for chips with 2 memory controllers (e.g. T5)\n+\t */\n+\tedc_size  = G_EDRAM0_SIZE(t4_read_reg(adap, A_MA_EDRAM0_BAR));\n+\tif (mtype != MEM_MC1) {\n+\t\tmtype_offset = (mtype * (edc_size * 1024 * 1024));\n+\t} else {\n+\t\tmc_size = G_EXT_MEM0_SIZE(t4_read_reg(adap,\n+\t\t\t\t\t\t      A_MA_EXT_MEMORY0_BAR));\n+\t\tmtype_offset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;\n+\t}\n+\n+\treturn t4_memory_rw_addr(adap, win,\n+\t\t\t\t mtype_offset + maddr, len,\n+\t\t\t\t hbuf, dir);\n+}\ndiff --git a/drivers/net/cxgbe/base/t4_hw.h b/drivers/net/cxgbe/base/t4_hw.h\nindex ac12afc04..e77563dfa 100644\n--- a/drivers/net/cxgbe/base/t4_hw.h\n+++ b/drivers/net/cxgbe/base/t4_hw.h\n@@ -42,6 +42,10 @@ enum {\n \tSGE_MAX_WR_NDESC = SGE_MAX_WR_LEN / SGE_EQ_IDXSIZE,\n };\n \n+enum {\n+\tTCB_SIZE        = 128,   /* TCB size */\n+};\n+\n struct sge_qstat {                /* data written to SGE queue status entries */\n \t__be32 qid;\n \t__be16 cidx;\ndiff --git a/drivers/net/cxgbe/base/t4_regs.h b/drivers/net/cxgbe/base/t4_regs.h\nindex c0d6ddcac..fd8f9cf27 100644\n--- a/drivers/net/cxgbe/base/t4_regs.h\n+++ b/drivers/net/cxgbe/base/t4_regs.h\n@@ -458,6 +458,7 @@\n #define F_CRXPKTENC    V_CRXPKTENC(1U)\n \n #define TP_BASE_ADDR 0x7d00\n+#define A_TP_CMM_TCB_BASE 0x7d10\n \n #define A_TP_TIMER_RESOLUTION 0x7d90\n \n@@ -574,6 +575,21 @@\n #define S_RM_OVLAN\t9\n #define V_RM_OVLAN(x)\t((x) << S_RM_OVLAN)\n \n+/* registers for module MA */\n+#define A_MA_EDRAM0_BAR 0x77c0\n+\n+#define S_EDRAM0_SIZE    0\n+#define M_EDRAM0_SIZE    0xfffU\n+#define V_EDRAM0_SIZE(x) ((x) << S_EDRAM0_SIZE)\n+#define G_EDRAM0_SIZE(x) (((x) >> S_EDRAM0_SIZE) & M_EDRAM0_SIZE)\n+\n+#define A_MA_EXT_MEMORY0_BAR 0x77c8\n+\n+#define S_EXT_MEM0_SIZE    0\n+#define M_EXT_MEM0_SIZE    0xfffU\n+#define V_EXT_MEM0_SIZE(x) ((x) << S_EXT_MEM0_SIZE)\n+#define G_EXT_MEM0_SIZE(x) (((x) >> S_EXT_MEM0_SIZE) & M_EXT_MEM0_SIZE)\n+\n /* registers for module MPS */\n #define MPS_BASE_ADDR 0x9000\n #define T4VF_MPS_BASE_ADDR 0x0100\ndiff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c\nindex 8129ed01f..2fc580e61 100644\n--- a/drivers/net/cxgbe/cxgbe_filter.c\n+++ b/drivers/net/cxgbe/cxgbe_filter.c\n@@ -545,3 +545,65 @@ void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)\n \t\t\tt4_complete(&ctx->completion);\n \t}\n }\n+\n+/*\n+ * Retrieve the packet count for the specified filter.\n+ */\n+int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,\n+\t\t\t   u64 *c, bool get_byte)\n+{\n+\tstruct filter_entry *f;\n+\tunsigned int tcb_base, tcbaddr;\n+\tint ret;\n+\n+\ttcb_base = t4_read_reg(adapter, A_TP_CMM_TCB_BASE);\n+\tif (fidx >= adapter->tids.nftids)\n+\t\treturn -ERANGE;\n+\n+\tf = &adapter->tids.ftid_tab[fidx];\n+\tif (!f->valid)\n+\t\treturn -EINVAL;\n+\n+\ttcbaddr = tcb_base + f->tid * TCB_SIZE;\n+\n+\tif (is_t5(adapter->params.chip) || is_t6(adapter->params.chip)) {\n+\t\t/*\n+\t\t * For T5, the Filter Packet Hit Count is maintained as a\n+\t\t * 32-bit Big Endian value in the TCB field {timestamp}.\n+\t\t * Similar to the craziness above, instead of the filter hit\n+\t\t * count showing up at offset 20 ((W_TCB_TIMESTAMP == 5) *\n+\t\t * sizeof(u32)), it actually shows up at offset 24.  Whacky.\n+\t\t */\n+\t\tif (get_byte) {\n+\t\t\tunsigned int word_offset = 4;\n+\t\t\t__be64 be64_byte_count;\n+\n+\t\t\tt4_os_lock(&adapter->win0_lock);\n+\t\t\tret = t4_memory_rw(adapter, MEMWIN_NIC, MEM_EDC0,\n+\t\t\t\t\t   tcbaddr +\n+\t\t\t\t\t   (word_offset * sizeof(__be32)),\n+\t\t\t\t\t   sizeof(be64_byte_count),\n+\t\t\t\t\t   &be64_byte_count,\n+\t\t\t\t\t   T4_MEMORY_READ);\n+\t\t\tt4_os_unlock(&adapter->win0_lock);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\t*c = be64_to_cpu(be64_byte_count);\n+\t\t} else {\n+\t\t\tunsigned int word_offset = 6;\n+\t\t\t__be32 be32_count;\n+\n+\t\t\tt4_os_lock(&adapter->win0_lock);\n+\t\t\tret = t4_memory_rw(adapter, MEMWIN_NIC, MEM_EDC0,\n+\t\t\t\t\t   tcbaddr +\n+\t\t\t\t\t   (word_offset * sizeof(__be32)),\n+\t\t\t\t\t   sizeof(be32_count), &be32_count,\n+\t\t\t\t\t   T4_MEMORY_READ);\n+\t\t\tt4_os_unlock(&adapter->win0_lock);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\t*c = (u64)be32_to_cpu(be32_count);\n+\t\t}\n+\t}\n+\treturn 0;\n+}\ndiff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h\nindex e0ba6a4d3..3c81c1a64 100644\n--- a/drivers/net/cxgbe/cxgbe_filter.h\n+++ b/drivers/net/cxgbe/cxgbe_filter.h\n@@ -220,4 +220,6 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,\n \t\t     struct filter_ctx *ctx);\n int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family);\n int validate_filter(struct adapter *adap, struct ch_filter_specification *fs);\n+int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,\n+\t\t\t   u64 *c, bool get_byte);\n #endif /* _CXGBE_FILTER_H_ */\ndiff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c\nindex 1584df392..89490ecc2 100644\n--- a/drivers/net/cxgbe/cxgbe_flow.c\n+++ b/drivers/net/cxgbe/cxgbe_flow.c\n@@ -522,6 +522,66 @@ cxgbe_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,\n \treturn 0;\n }\n \n+static int __cxgbe_flow_query(struct rte_flow *flow, u64 *count,\n+\t\t\t      u64 *byte_count)\n+{\n+\tstruct adapter *adap = ethdev2adap(flow->dev);\n+\tunsigned int fidx = flow->fidx;\n+\tint ret = 0;\n+\n+\tret = cxgbe_get_filter_count(adap, fidx, count, 0);\n+\tif (ret)\n+\t\treturn ret;\n+\treturn cxgbe_get_filter_count(adap, fidx, byte_count, 1);\n+}\n+\n+static int\n+cxgbe_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow,\n+\t\t const struct rte_flow_action *action, void *data,\n+\t\t struct rte_flow_error *e)\n+{\n+\tstruct ch_filter_specification fs;\n+\tstruct rte_flow_query_count *c;\n+\tstruct filter_entry *f;\n+\tint ret;\n+\n+\tRTE_SET_USED(dev);\n+\n+\tf = flow->f;\n+\tfs = f->fs;\n+\n+\tif (action->type != RTE_FLOW_ACTION_TYPE_COUNT)\n+\t\treturn rte_flow_error_set(e, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, NULL,\n+\t\t\t\t\t  \"only count supported for query\");\n+\n+\t/*\n+\t * This is a valid operation, Since we are allowed to do chelsio\n+\t * specific operations in rte side of our code but not vise-versa\n+\t *\n+\t * So, fs can be queried/modified here BUT rte_flow_query_count\n+\t * cannot be worked on by the lower layer since we want to maintain\n+\t * it as rte_flow agnostic.\n+\t */\n+\tif (!fs.hitcnts)\n+\t\treturn rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t  &fs, \"filter hit counters were not\"\n+\t\t\t\t\t  \" enabled during filter creation\");\n+\n+\tc = (struct rte_flow_query_count *)data;\n+\tret = __cxgbe_flow_query(flow, &c->hits, &c->bytes);\n+\tif (ret)\n+\t\treturn rte_flow_error_set(e, -ret, RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t  f, \"cxgbe pmd failed to\"\n+\t\t\t\t\t  \" perform query\");\n+\n+\t/* Query was successful */\n+\tc->bytes_set = 1;\n+\tc->hits_set = 1;\n+\n+\treturn 0; /* success / partial_success */\n+}\n+\n static int\n cxgbe_flow_validate(struct rte_eth_dev *dev,\n \t\t    const struct rte_flow_attr *attr,\n@@ -577,7 +637,7 @@ static const struct rte_flow_ops cxgbe_flow_ops = {\n \t.create\t\t= cxgbe_flow_create,\n \t.destroy\t= cxgbe_flow_destroy,\n \t.flush\t\t= NULL,\n-\t.query\t\t= NULL,\n+\t.query\t\t= cxgbe_flow_query,\n \t.isolate\t= NULL,\n };\n \ndiff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c\nindex a00e0700d..21ad380ae 100644\n--- a/drivers/net/cxgbe/cxgbe_main.c\n+++ b/drivers/net/cxgbe/cxgbe_main.c\n@@ -1527,6 +1527,7 @@ int cxgbe_probe(struct adapter *adapter)\n \n \tt4_os_lock_init(&adapter->mbox_lock);\n \tTAILQ_INIT(&adapter->mbox_list);\n+\tt4_os_lock_init(&adapter->win0_lock);\n \n \terr = t4_prep_adapter(adapter);\n \tif (err)\n",
    "prefixes": [
        "dpdk-dev",
        "6/7"
    ]
}