get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 28275,
    "url": "http://patches.dpdk.org/api/patches/28275/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1504275141-35448-5-git-send-email-alejandro.lucero@netronome.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<1504275141-35448-5-git-send-email-alejandro.lucero@netronome.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1504275141-35448-5-git-send-email-alejandro.lucero@netronome.com",
    "date": "2017-09-01T14:12:07",
    "name": "[dpdk-dev,v2,04/18] net/nfp: add NSP support for commands",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "75e7a6b5108862d06e7f46ff6d600de4ba531d21",
    "submitter": {
        "id": 270,
        "url": "http://patches.dpdk.org/api/people/270/?format=api",
        "name": "Alejandro Lucero",
        "email": "alejandro.lucero@netronome.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1504275141-35448-5-git-send-email-alejandro.lucero@netronome.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/28275/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/28275/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 B556E7CF0;\n\tFri,  1 Sep 2017 16:12:43 +0200 (CEST)",
            "from netronome.com (host-79-78-33-110.static.as9105.net\n\t[79.78.33.110]) by dpdk.org (Postfix) with ESMTP id 2DB357CAF\n\tfor <dev@dpdk.org>; Fri,  1 Sep 2017 16:12:36 +0200 (CEST)",
            "from netronome.com (localhost [127.0.0.1])\n\tby netronome.com (8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id\n\tv81ECMrH035515 for <dev@dpdk.org>; Fri, 1 Sep 2017 15:12:22 +0100",
            "(from alucero@localhost)\n\tby netronome.com (8.14.4/8.14.4/Submit) id v81ECMjN035514\n\tfor dev@dpdk.org; Fri, 1 Sep 2017 15:12:22 +0100"
        ],
        "From": "Alejandro Lucero <alejandro.lucero@netronome.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri,  1 Sep 2017 15:12:07 +0100",
        "Message-Id": "<1504275141-35448-5-git-send-email-alejandro.lucero@netronome.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1504275141-35448-1-git-send-email-alejandro.lucero@netronome.com>",
        "References": "<1504275141-35448-1-git-send-email-alejandro.lucero@netronome.com>",
        "Subject": "[dpdk-dev] [PATCH v2 04/18] net/nfp: add NSP support for commands",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <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": "NSPU interface declares a buffer controlled by the NFP NSP service\nprocessor. It is possible to send commands to the NSP using the NSPU\nand this buffer for data related to the command. A command can imply\nbuffer read, buffer write, both or none.\n\nInitial command for resetting the firmware is added as well which\ndoes not require the buffer at all.\n\nCommands will allow firmware upload, symbol resolution and ethernet\nlink configuration. Future commands will allow specific offloads like\nflow offloads and eBPF offload.\n\nSigned-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>\n---\n drivers/net/nfp/nfp_nspu.c | 181 ++++++++++++++++++++++++++++++++++++++++++++-\n drivers/net/nfp/nfp_nspu.h |   4 +\n 2 files changed, 183 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/drivers/net/nfp/nfp_nspu.c b/drivers/net/nfp/nfp_nspu.c\nindex a157915..dbb5305 100644\n--- a/drivers/net/nfp/nfp_nspu.c\n+++ b/drivers/net/nfp/nfp_nspu.c\n@@ -29,14 +29,19 @@\n #define NSP_STATUS              0x00\n #define NSP_COMMAND             0x08\n #define NSP_BUFFER\t\t0x10\n-#define NSP_DEFAULT_BUFFER      0x18\n-#define NSP_DEFAULT_BUFFER_CFG  0x20\n+#define NSP_DEFAULT_BUF         0x18\n+#define NSP_DEFAULT_BUF_CFG  0x20\n \n #define NSP_MAGIC                0xab10\n #define NSP_STATUS_MAGIC(x)      (((x) >> 48) & 0xffff)\n #define NSP_STATUS_MAJOR(x)      (int)(((x) >> 44) & 0xf)\n #define NSP_STATUS_MINOR(x)      (int)(((x) >> 32) & 0xfff)\n \n+/* NSP commands */\n+#define NSP_CMD_RESET\t\t\t1\n+\n+#define NSP_BUFFER_CFG_SIZE_MASK\t(0xff)\n+\n #define NSP_REG_ADDR(d, off, reg) ((uint8_t *)(d)->mem_base + (off) + (reg))\n #define NSP_REG_VAL(p) (*(uint64_t *)(p))\n \n@@ -118,12 +123,184 @@\n nfp_nspu_init(nspu_desc_t *desc, int nfp, int pcie_bar, size_t pcie_barsz,\n \t      int exp_bar, void *exp_bar_cfg_base, void *exp_bar_mmap)\n {\n+\tuint64_t offset, buffaddr;\n+\tuint64_t nsp_reg;\n+\n \tdesc->nfp = nfp;\n \tdesc->pcie_bar = pcie_bar;\n \tdesc->exp_bar = exp_bar;\n \tdesc->barsz = pcie_barsz;\n+\tdesc->windowsz = 1 << (desc->barsz - 3);\n \tdesc->cfg_base = exp_bar_cfg_base;\n \tdesc->mem_base = exp_bar_mmap;\n \n+\tnspu_xlate(desc, NSP_BASE, &offset);\n+\n+\t/*\n+\t * Other NSPU clients can use other buffers. Let's tell NSPU we use the\n+\t * default buffer.\n+\t */\n+\tbuffaddr = NSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_DEFAULT_BUF));\n+\tNSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_BUFFER)) = buffaddr;\n+\n+\t/* NFP internal addresses are 40 bits. Clean all other bits here */\n+\tbuffaddr = buffaddr & (((uint64_t)1 << 40) - 1);\n+\tdesc->bufaddr = buffaddr;\n+\n+\t/* Lets get information about the buffer */\n+\tnsp_reg = NSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_DEFAULT_BUF_CFG));\n+\n+\t/* Buffer size comes in MBs. Coversion to bytes */\n+\tdesc->buf_size = ((size_t)nsp_reg & NSP_BUFFER_CFG_SIZE_MASK) << 20;\n+\n \treturn 0;\n }\n+\n+#define NSPU_NFP_BUF(addr, base, off) \\\n+\t(*(uint64_t *)((uint8_t *)(addr)->mem_base + ((base) | (off))))\n+\n+#define NSPU_HOST_BUF(base, off) (*(uint64_t *)((uint8_t *)(base) + (off)))\n+\n+static int\n+nspu_buff_write(nspu_desc_t *desc, void *buffer, size_t size)\n+{\n+\tuint64_t pcie_offset, pcie_window_base, pcie_window_offset;\n+\tuint64_t windowsz = desc->windowsz;\n+\tuint64_t buffaddr, j, i = 0;\n+\tint ret = 0;\n+\n+\tif (size > desc->buf_size)\n+\t\treturn -1;\n+\n+\tbuffaddr = desc->bufaddr;\n+\twindowsz = desc->windowsz;\n+\n+\twhile (i < size) {\n+\t\t/* Expansion bar reconfiguration per window size */\n+\t\tnspu_xlate(desc, buffaddr + i, &pcie_offset);\n+\t\tpcie_window_base = pcie_offset & (~(windowsz - 1));\n+\t\tpcie_window_offset = pcie_offset & (windowsz - 1);\n+\t\tfor (j = pcie_window_offset; ((j < windowsz) && (i < size));\n+\t\t     j += 8) {\n+\t\t\tNSPU_NFP_BUF(desc, pcie_window_base, j) =\n+\t\t\t\tNSPU_HOST_BUF(buffer, i);\n+\t\t\ti += 8;\n+\t\t}\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+nspu_buff_read(nspu_desc_t *desc, void *buffer, size_t size)\n+{\n+\tuint64_t pcie_offset, pcie_window_base, pcie_window_offset;\n+\tuint64_t windowsz, i = 0, j;\n+\tuint64_t buffaddr;\n+\tint ret = 0;\n+\n+\tif (size > desc->buf_size)\n+\t\treturn -1;\n+\n+\tbuffaddr = desc->bufaddr;\n+\twindowsz = desc->windowsz;\n+\n+\twhile (i < size) {\n+\t\t/* Expansion bar reconfiguration per window size */\n+\t\tnspu_xlate(desc, buffaddr + i, &pcie_offset);\n+\t\tpcie_window_base = pcie_offset & (~(windowsz - 1));\n+\t\tpcie_window_offset = pcie_offset & (windowsz - 1);\n+\t\tfor (j = pcie_window_offset; ((j < windowsz) && (i < size));\n+\t\t     j += 8) {\n+\t\t\tNSPU_HOST_BUF(buffer, i) =\n+\t\t\t\tNSPU_NFP_BUF(desc, pcie_window_base, j);\n+\t\t\ti += 8;\n+\t\t}\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+nspu_command(nspu_desc_t *desc, uint16_t cmd, int read, int write,\n+\t\t void *buffer, size_t rsize, size_t wsize)\n+{\n+\tuint64_t status, cmd_reg;\n+\tuint64_t offset;\n+\tint retry = 0;\n+\tint retries = 120;\n+\tint ret = 0;\n+\n+\t/* Same expansion BAR is used for different things */\n+\tnspu_xlate(desc, NSP_BASE, &offset);\n+\n+\tstatus = NSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_STATUS));\n+\n+\twhile ((status & 0x1) && (retry < retries)) {\n+\t\tstatus = NSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_STATUS));\n+\t\tretry++;\n+\t\tsleep(1);\n+\t}\n+\n+\tif (retry == retries)\n+\t\treturn -1;\n+\n+\tif (write) {\n+\t\tret = nspu_buff_write(desc, buffer, wsize);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\t/* Expansion BAR changes when writing the buffer */\n+\t\tnspu_xlate(desc, NSP_BASE, &offset);\n+\t}\n+\n+\tNSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_COMMAND)) =\n+\t\t(uint64_t)wsize << 32 | (uint64_t)cmd << 16 | 1;\n+\n+\tretry = 0;\n+\n+\tcmd_reg = NSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_COMMAND));\n+\twhile ((cmd_reg & 0x1) && (retry < retries)) {\n+\t\tcmd_reg = NSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_COMMAND));\n+\t\tretry++;\n+\t\tsleep(1);\n+\t}\n+\tif (retry == retries)\n+\t\treturn -1;\n+\n+\tretry = 0;\n+\tstatus = NSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_STATUS));\n+\twhile ((status & 0x1) && (retry < retries)) {\n+\t\tstatus = NSP_REG_VAL(NSP_REG_ADDR(desc, offset, NSP_STATUS));\n+\t\tretry++;\n+\t\tsleep(1);\n+\t}\n+\n+\tif (retry == retries)\n+\t\treturn -1;\n+\n+\tret = status & (0xff << 8);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (read) {\n+\t\tret = nspu_buff_read(desc, buffer, rsize);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+int\n+nfp_fw_reset(nspu_desc_t *nspu_desc)\n+{\n+\tint res;\n+\n+\tres = nspu_command(nspu_desc, NSP_CMD_RESET, 0, 0, 0, 0, 0);\n+\n+\tif (res < 0)\n+\t\tRTE_LOG(INFO, PMD, \"fw reset failed: error %d\", res);\n+\n+\treturn res;\n+}\ndiff --git a/drivers/net/nfp/nfp_nspu.h b/drivers/net/nfp/nfp_nspu.h\nindex 7a1ac91..a142eb3 100644\n--- a/drivers/net/nfp/nfp_nspu.h\n+++ b/drivers/net/nfp/nfp_nspu.h\n@@ -62,6 +62,9 @@\n \tint pcie_bar;   /* PF PCI BAR to work with */\n \tint exp_bar;    /* Expansion BAR number used by NSPU */\n \tint barsz;      /* PCIE BAR log2 size */\n+\tuint64_t bufaddr;  /* commands buffer address */\n+\tsize_t buf_size;   /* commands buffer size */\n+\tuint64_t windowsz; /* NSPU BAR window size */\n \tvoid *cfg_base; /* Expansion BARs address */\n \tvoid *mem_base; /* NSP interface */\n } nspu_desc_t;\n@@ -69,3 +72,4 @@\n int nfp_nspu_init(nspu_desc_t *desc, int nfp, int pcie_bar, size_t pcie_barsz,\n \t\t  int exp_bar, void *exp_bar_cfg_base, void *exp_bar_mmap);\n int nfp_nsp_get_abi_version(nspu_desc_t *desc, int *major, int *minor);\n+int nfp_fw_reset(nspu_desc_t *nspu_desc);\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "04/18"
    ]
}