linux/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
   2/* Copyright (C) 2015-2018 Netronome Systems, Inc. */
   3
   4/*
   5 * nfp_nsp.c
   6 * Author: Jakub Kicinski <jakub.kicinski@netronome.com>
   7 *         Jason McMullan <jason.mcmullan@netronome.com>
   8 */
   9
  10#include <asm/unaligned.h>
  11#include <linux/bitfield.h>
  12#include <linux/delay.h>
  13#include <linux/firmware.h>
  14#include <linux/kernel.h>
  15#include <linux/kthread.h>
  16#include <linux/overflow.h>
  17#include <linux/sizes.h>
  18#include <linux/slab.h>
  19
  20#define NFP_SUBSYS "nfp_nsp"
  21
  22#include "nfp.h"
  23#include "nfp_cpp.h"
  24#include "nfp_nsp.h"
  25
  26#define NFP_NSP_TIMEOUT_DEFAULT 30
  27#define NFP_NSP_TIMEOUT_BOOT    30
  28
  29/* Offsets relative to the CSR base */
  30#define NSP_STATUS              0x00
  31#define   NSP_STATUS_MAGIC      GENMASK_ULL(63, 48)
  32#define   NSP_STATUS_MAJOR      GENMASK_ULL(47, 44)
  33#define   NSP_STATUS_MINOR      GENMASK_ULL(43, 32)
  34#define   NSP_STATUS_CODE       GENMASK_ULL(31, 16)
  35#define   NSP_STATUS_RESULT     GENMASK_ULL(15, 8)
  36#define   NSP_STATUS_BUSY       BIT_ULL(0)
  37
  38#define NSP_COMMAND             0x08
  39#define   NSP_COMMAND_OPTION    GENMASK_ULL(63, 32)
  40#define   NSP_COMMAND_CODE      GENMASK_ULL(31, 16)
  41#define   NSP_COMMAND_DMA_BUF   BIT_ULL(1)
  42#define   NSP_COMMAND_START     BIT_ULL(0)
  43
  44/* CPP address to retrieve the data from */
  45#define NSP_BUFFER              0x10
  46#define   NSP_BUFFER_CPP        GENMASK_ULL(63, 40)
  47#define   NSP_BUFFER_ADDRESS    GENMASK_ULL(39, 0)
  48
  49#define NSP_DFLT_BUFFER         0x18
  50#define   NSP_DFLT_BUFFER_CPP   GENMASK_ULL(63, 40)
  51#define   NSP_DFLT_BUFFER_ADDRESS       GENMASK_ULL(39, 0)
  52
  53#define NSP_DFLT_BUFFER_CONFIG  0x20
  54#define   NSP_DFLT_BUFFER_DMA_CHUNK_ORDER       GENMASK_ULL(63, 58)
  55#define   NSP_DFLT_BUFFER_SIZE_4KB      GENMASK_ULL(15, 8)
  56#define   NSP_DFLT_BUFFER_SIZE_MB       GENMASK_ULL(7, 0)
  57
  58#define NFP_CAP_CMD_DMA_SG      0x28
  59
  60#define NSP_MAGIC               0xab10
  61#define NSP_MAJOR               0
  62#define NSP_MINOR               8
  63
  64#define NSP_CODE_MAJOR          GENMASK(15, 12)
  65#define NSP_CODE_MINOR          GENMASK(11, 0)
  66
  67#define NFP_FW_LOAD_RET_MAJOR   GENMASK(15, 8)
  68#define NFP_FW_LOAD_RET_MINOR   GENMASK(23, 16)
  69
  70#define NFP_HWINFO_LOOKUP_SIZE  GENMASK(11, 0)
  71
  72#define NFP_VERSIONS_SIZE       GENMASK(11, 0)
  73#define NFP_VERSIONS_CNT_OFF    0
  74#define NFP_VERSIONS_BSP_OFF    2
  75#define NFP_VERSIONS_CPLD_OFF   6
  76#define NFP_VERSIONS_APP_OFF    10
  77#define NFP_VERSIONS_BUNDLE_OFF 14
  78#define NFP_VERSIONS_UNDI_OFF   18
  79#define NFP_VERSIONS_NCSI_OFF   22
  80#define NFP_VERSIONS_CFGR_OFF   26
  81
  82#define NSP_SFF_EEPROM_BLOCK_LEN        8
  83
  84enum nfp_nsp_cmd {
  85        SPCODE_NOOP             = 0, /* No operation */
  86        SPCODE_SOFT_RESET       = 1, /* Soft reset the NFP */
  87        SPCODE_FW_DEFAULT       = 2, /* Load default (UNDI) FW */
  88        SPCODE_PHY_INIT         = 3, /* Initialize the PHY */
  89        SPCODE_MAC_INIT         = 4, /* Initialize the MAC */
  90        SPCODE_PHY_RXADAPT      = 5, /* Re-run PHY RX Adaptation */
  91        SPCODE_FW_LOAD          = 6, /* Load fw from buffer, len in option */
  92        SPCODE_ETH_RESCAN       = 7, /* Rescan ETHs, write ETH_TABLE to buf */
  93        SPCODE_ETH_CONTROL      = 8, /* Update media config from buffer */
  94        SPCODE_NSP_WRITE_FLASH  = 11, /* Load and flash image from buffer */
  95        SPCODE_NSP_SENSORS      = 12, /* Read NSP sensor(s) */
  96        SPCODE_NSP_IDENTIFY     = 13, /* Read NSP version */
  97        SPCODE_FW_STORED        = 16, /* If no FW loaded, load flash app FW */
  98        SPCODE_HWINFO_LOOKUP    = 17, /* Lookup HWinfo with overwrites etc. */
  99        SPCODE_HWINFO_SET       = 18, /* Set HWinfo entry */
 100        SPCODE_FW_LOADED        = 19, /* Is application firmware loaded */
 101        SPCODE_VERSIONS         = 21, /* Report FW versions */
 102        SPCODE_READ_SFF_EEPROM  = 22, /* Read module EEPROM */
 103};
 104
 105struct nfp_nsp_dma_buf {
 106        __le32 chunk_cnt;
 107        __le32 reserved[3];
 108        struct {
 109                __le32 size;
 110                __le32 reserved;
 111                __le64 addr;
 112        } descs[];
 113};
 114
 115static const struct {
 116        int code;
 117        const char *msg;
 118} nsp_errors[] = {
 119        { 6010, "could not map to phy for port" },
 120        { 6011, "not an allowed rate/lanes for port" },
 121        { 6012, "not an allowed rate/lanes for port" },
 122        { 6013, "high/low error, change other port first" },
 123        { 6014, "config not found in flash" },
 124};
 125
 126struct nfp_nsp {
 127        struct nfp_cpp *cpp;
 128        struct nfp_resource *res;
 129        struct {
 130                u16 major;
 131                u16 minor;
 132        } ver;
 133
 134        /* Eth table config state */
 135        bool modified;
 136        unsigned int idx;
 137        void *entries;
 138};
 139
 140/**
 141 * struct nfp_nsp_command_arg - NFP command argument structure
 142 * @code:       NFP SP Command Code
 143 * @dma:        @buf points to a host buffer, not NSP buffer
 144 * @timeout_sec:Timeout value to wait for completion in seconds
 145 * @option:     NFP SP Command Argument
 146 * @buf:        NFP SP Buffer Address
 147 * @error_cb:   Callback for interpreting option if error occurred
 148 * @error_quiet:Don't print command error/warning. Protocol errors are still
 149 *                  logged.
 150 */
 151struct nfp_nsp_command_arg {
 152        u16 code;
 153        bool dma;
 154        unsigned int timeout_sec;
 155        u32 option;
 156        u64 buf;
 157        void (*error_cb)(struct nfp_nsp *state, u32 ret_val);
 158        bool error_quiet;
 159};
 160
 161/**
 162 * struct nfp_nsp_command_buf_arg - NFP command with buffer argument structure
 163 * @arg:        NFP command argument structure
 164 * @in_buf:     Buffer with data for input
 165 * @in_size:    Size of @in_buf
 166 * @out_buf:    Buffer for output data
 167 * @out_size:   Size of @out_buf
 168 */
 169struct nfp_nsp_command_buf_arg {
 170        struct nfp_nsp_command_arg arg;
 171        const void *in_buf;
 172        unsigned int in_size;
 173        void *out_buf;
 174        unsigned int out_size;
 175};
 176
 177struct nfp_cpp *nfp_nsp_cpp(struct nfp_nsp *state)
 178{
 179        return state->cpp;
 180}
 181
 182bool nfp_nsp_config_modified(struct nfp_nsp *state)
 183{
 184        return state->modified;
 185}
 186
 187void nfp_nsp_config_set_modified(struct nfp_nsp *state, bool modified)
 188{
 189        state->modified = modified;
 190}
 191
 192void *nfp_nsp_config_entries(struct nfp_nsp *state)
 193{
 194        return state->entries;
 195}
 196
 197unsigned int nfp_nsp_config_idx(struct nfp_nsp *state)
 198{
 199        return state->idx;
 200}
 201
 202void
 203nfp_nsp_config_set_state(struct nfp_nsp *state, void *entries, unsigned int idx)
 204{
 205        state->entries = entries;
 206        state->idx = idx;
 207}
 208
 209void nfp_nsp_config_clear_state(struct nfp_nsp *state)
 210{
 211        state->entries = NULL;
 212        state->idx = 0;
 213}
 214
 215static void nfp_nsp_print_extended_error(struct nfp_nsp *state, u32 ret_val)
 216{
 217        int i;
 218
 219        if (!ret_val)
 220                return;
 221
 222        for (i = 0; i < ARRAY_SIZE(nsp_errors); i++)
 223                if (ret_val == nsp_errors[i].code)
 224                        nfp_err(state->cpp, "err msg: %s\n", nsp_errors[i].msg);
 225}
 226
 227static int nfp_nsp_check(struct nfp_nsp *state)
 228{
 229        struct nfp_cpp *cpp = state->cpp;
 230        u64 nsp_status, reg;
 231        u32 nsp_cpp;
 232        int err;
 233
 234        nsp_cpp = nfp_resource_cpp_id(state->res);
 235        nsp_status = nfp_resource_address(state->res) + NSP_STATUS;
 236
 237        err = nfp_cpp_readq(cpp, nsp_cpp, nsp_status, &reg);
 238        if (err < 0)
 239                return err;
 240
 241        if (FIELD_GET(NSP_STATUS_MAGIC, reg) != NSP_MAGIC) {
 242                nfp_err(cpp, "Cannot detect NFP Service Processor\n");
 243                return -ENODEV;
 244        }
 245
 246        state->ver.major = FIELD_GET(NSP_STATUS_MAJOR, reg);
 247        state->ver.minor = FIELD_GET(NSP_STATUS_MINOR, reg);
 248
 249        if (state->ver.major != NSP_MAJOR) {
 250                nfp_err(cpp, "Unsupported ABI %hu.%hu\n",
 251                        state->ver.major, state->ver.minor);
 252                return -EINVAL;
 253        }
 254        if (state->ver.minor < NSP_MINOR) {
 255                nfp_err(cpp, "ABI too old to support NIC operation (%u.%hu < %u.%u), please update the management FW on the flash\n",
 256                        NSP_MAJOR, state->ver.minor, NSP_MAJOR, NSP_MINOR);
 257                return -EINVAL;
 258        }
 259
 260        if (reg & NSP_STATUS_BUSY) {
 261                nfp_err(cpp, "Service processor busy!\n");
 262                return -EBUSY;
 263        }
 264
 265        return 0;
 266}
 267
 268/**
 269 * nfp_nsp_open() - Prepare for communication and lock the NSP resource.
 270 * @cpp:        NFP CPP Handle
 271 */
 272struct nfp_nsp *nfp_nsp_open(struct nfp_cpp *cpp)
 273{
 274        struct nfp_resource *res;
 275        struct nfp_nsp *state;
 276        int err;
 277
 278        res = nfp_resource_acquire(cpp, NFP_RESOURCE_NSP);
 279        if (IS_ERR(res))
 280                return (void *)res;
 281
 282        state = kzalloc(sizeof(*state), GFP_KERNEL);
 283        if (!state) {
 284                nfp_resource_release(res);
 285                return ERR_PTR(-ENOMEM);
 286        }
 287        state->cpp = cpp;
 288        state->res = res;
 289
 290        err = nfp_nsp_check(state);
 291        if (err) {
 292                nfp_nsp_close(state);
 293                return ERR_PTR(err);
 294        }
 295
 296        return state;
 297}
 298
 299/**
 300 * nfp_nsp_close() - Clean up and unlock the NSP resource.
 301 * @state:      NFP SP state
 302 */
 303void nfp_nsp_close(struct nfp_nsp *state)
 304{
 305        nfp_resource_release(state->res);
 306        kfree(state);
 307}
 308
 309u16 nfp_nsp_get_abi_ver_major(struct nfp_nsp *state)
 310{
 311        return state->ver.major;
 312}
 313
 314u16 nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state)
 315{
 316        return state->ver.minor;
 317}
 318
 319static int
 320nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg, u32 nsp_cpp, u64 addr,
 321                 u64 mask, u64 val, u32 timeout_sec)
 322{
 323        const unsigned long wait_until = jiffies + timeout_sec * HZ;
 324        int err;
 325
 326        for (;;) {
 327                const unsigned long start_time = jiffies;
 328
 329                err = nfp_cpp_readq(cpp, nsp_cpp, addr, reg);
 330                if (err < 0)
 331                        return err;
 332
 333                if ((*reg & mask) == val)
 334                        return 0;
 335
 336                msleep(25);
 337
 338                if (time_after(start_time, wait_until))
 339                        return -ETIMEDOUT;
 340        }
 341}
 342
 343/**
 344 * __nfp_nsp_command() - Execute a command on the NFP Service Processor
 345 * @state:      NFP SP state
 346 * @arg:        NFP command argument structure
 347 *
 348 * Return: 0 for success with no result
 349 *
 350 *       positive value for NSP completion with a result code
 351 *
 352 *      -EAGAIN if the NSP is not yet present
 353 *      -ENODEV if the NSP is not a supported model
 354 *      -EBUSY if the NSP is stuck
 355 *      -EINTR if interrupted while waiting for completion
 356 *      -ETIMEDOUT if the NSP took longer than @timeout_sec seconds to complete
 357 */
 358static int
 359__nfp_nsp_command(struct nfp_nsp *state, const struct nfp_nsp_command_arg *arg)
 360{
 361        u64 reg, ret_val, nsp_base, nsp_buffer, nsp_status, nsp_command;
 362        struct nfp_cpp *cpp = state->cpp;
 363        u32 nsp_cpp;
 364        int err;
 365
 366        nsp_cpp = nfp_resource_cpp_id(state->res);
 367        nsp_base = nfp_resource_address(state->res);
 368        nsp_status = nsp_base + NSP_STATUS;
 369        nsp_command = nsp_base + NSP_COMMAND;
 370        nsp_buffer = nsp_base + NSP_BUFFER;
 371
 372        err = nfp_nsp_check(state);
 373        if (err)
 374                return err;
 375
 376        err = nfp_cpp_writeq(cpp, nsp_cpp, nsp_buffer, arg->buf);
 377        if (err < 0)
 378                return err;
 379
 380        err = nfp_cpp_writeq(cpp, nsp_cpp, nsp_command,
 381                             FIELD_PREP(NSP_COMMAND_OPTION, arg->option) |
 382                             FIELD_PREP(NSP_COMMAND_CODE, arg->code) |
 383                             FIELD_PREP(NSP_COMMAND_DMA_BUF, arg->dma) |
 384                             FIELD_PREP(NSP_COMMAND_START, 1));
 385        if (err < 0)
 386                return err;
 387
 388        /* Wait for NSP_COMMAND_START to go to 0 */
 389        err = nfp_nsp_wait_reg(cpp, &reg, nsp_cpp, nsp_command,
 390                               NSP_COMMAND_START, 0, NFP_NSP_TIMEOUT_DEFAULT);
 391        if (err) {
 392                nfp_err(cpp, "Error %d waiting for code 0x%04x to start\n",
 393                        err, arg->code);
 394                return err;
 395        }
 396
 397        /* Wait for NSP_STATUS_BUSY to go to 0 */
 398        err = nfp_nsp_wait_reg(cpp, &reg, nsp_cpp, nsp_status, NSP_STATUS_BUSY,
 399                               0, arg->timeout_sec ?: NFP_NSP_TIMEOUT_DEFAULT);
 400        if (err) {
 401                nfp_err(cpp, "Error %d waiting for code 0x%04x to complete\n",
 402                        err, arg->code);
 403                return err;
 404        }
 405
 406        err = nfp_cpp_readq(cpp, nsp_cpp, nsp_command, &ret_val);
 407        if (err < 0)
 408                return err;
 409        ret_val = FIELD_GET(NSP_COMMAND_OPTION, ret_val);
 410
 411        err = FIELD_GET(NSP_STATUS_RESULT, reg);
 412        if (err) {
 413                if (!arg->error_quiet)
 414                        nfp_warn(cpp, "Result (error) code set: %d (%d) command: %d\n",
 415                                 -err, (int)ret_val, arg->code);
 416
 417                if (arg->error_cb)
 418                        arg->error_cb(state, ret_val);
 419                else
 420                        nfp_nsp_print_extended_error(state, ret_val);
 421                return -err;
 422        }
 423
 424        return ret_val;
 425}
 426
 427static int nfp_nsp_command(struct nfp_nsp *state, u16 code)
 428{
 429        const struct nfp_nsp_command_arg arg = {
 430                .code           = code,
 431        };
 432
 433        return __nfp_nsp_command(state, &arg);
 434}
 435
 436static int
 437nfp_nsp_command_buf_def(struct nfp_nsp *nsp,
 438                        struct nfp_nsp_command_buf_arg *arg)
 439{
 440        struct nfp_cpp *cpp = nsp->cpp;
 441        u64 reg, cpp_buf;
 442        int err, ret;
 443        u32 cpp_id;
 444
 445        err = nfp_cpp_readq(cpp, nfp_resource_cpp_id(nsp->res),
 446                            nfp_resource_address(nsp->res) +
 447                            NSP_DFLT_BUFFER,
 448                            &reg);
 449        if (err < 0)
 450                return err;
 451
 452        cpp_id = FIELD_GET(NSP_DFLT_BUFFER_CPP, reg) << 8;
 453        cpp_buf = FIELD_GET(NSP_DFLT_BUFFER_ADDRESS, reg);
 454
 455        if (arg->in_buf && arg->in_size) {
 456                err = nfp_cpp_write(cpp, cpp_id, cpp_buf,
 457                                    arg->in_buf, arg->in_size);
 458                if (err < 0)
 459                        return err;
 460        }
 461        /* Zero out remaining part of the buffer */
 462        if (arg->out_buf && arg->out_size && arg->out_size > arg->in_size) {
 463                err = nfp_cpp_write(cpp, cpp_id, cpp_buf + arg->in_size,
 464                                    arg->out_buf, arg->out_size - arg->in_size);
 465                if (err < 0)
 466                        return err;
 467        }
 468
 469        if (!FIELD_FIT(NSP_BUFFER_CPP, cpp_id >> 8) ||
 470            !FIELD_FIT(NSP_BUFFER_ADDRESS, cpp_buf)) {
 471                nfp_err(cpp, "Buffer out of reach %08x %016llx\n",
 472                        cpp_id, cpp_buf);
 473                return -EINVAL;
 474        }
 475
 476        arg->arg.buf = FIELD_PREP(NSP_BUFFER_CPP, cpp_id >> 8) |
 477                       FIELD_PREP(NSP_BUFFER_ADDRESS, cpp_buf);
 478        ret = __nfp_nsp_command(nsp, &arg->arg);
 479        if (ret < 0)
 480                return ret;
 481
 482        if (arg->out_buf && arg->out_size) {
 483                err = nfp_cpp_read(cpp, cpp_id, cpp_buf,
 484                                   arg->out_buf, arg->out_size);
 485                if (err < 0)
 486                        return err;
 487        }
 488
 489        return ret;
 490}
 491
 492static int
 493nfp_nsp_command_buf_dma_sg(struct nfp_nsp *nsp,
 494                           struct nfp_nsp_command_buf_arg *arg,
 495                           unsigned int max_size, unsigned int chunk_order,
 496                           unsigned int dma_order)
 497{
 498        struct nfp_cpp *cpp = nsp->cpp;
 499        struct nfp_nsp_dma_buf *desc;
 500        struct {
 501                dma_addr_t dma_addr;
 502                unsigned long len;
 503                void *chunk;
 504        } *chunks;
 505        size_t chunk_size, dma_size;
 506        dma_addr_t dma_desc;
 507        struct device *dev;
 508        unsigned long off;
 509        int i, ret, nseg;
 510        size_t desc_sz;
 511
 512        chunk_size = BIT_ULL(chunk_order);
 513        dma_size = BIT_ULL(dma_order);
 514        nseg = DIV_ROUND_UP(max_size, chunk_size);
 515
 516        chunks = kzalloc(array_size(sizeof(*chunks), nseg), GFP_KERNEL);
 517        if (!chunks)
 518                return -ENOMEM;
 519
 520        off = 0;
 521        ret = -ENOMEM;
 522        for (i = 0; i < nseg; i++) {
 523                unsigned long coff;
 524
 525                chunks[i].chunk = kmalloc(chunk_size,
 526                                          GFP_KERNEL | __GFP_NOWARN);
 527                if (!chunks[i].chunk)
 528                        goto exit_free_prev;
 529
 530                chunks[i].len = min_t(u64, chunk_size, max_size - off);
 531
 532                coff = 0;
 533                if (arg->in_size > off) {
 534                        coff = min_t(u64, arg->in_size - off, chunk_size);
 535                        memcpy(chunks[i].chunk, arg->in_buf + off, coff);
 536                }
 537                memset(chunks[i].chunk + coff, 0, chunk_size - coff);
 538
 539                off += chunks[i].len;
 540        }
 541
 542        dev = nfp_cpp_device(cpp)->parent;
 543
 544        for (i = 0; i < nseg; i++) {
 545                dma_addr_t addr;
 546
 547                addr = dma_map_single(dev, chunks[i].chunk, chunks[i].len,
 548                                      DMA_BIDIRECTIONAL);
 549                chunks[i].dma_addr = addr;
 550
 551                ret = dma_mapping_error(dev, addr);
 552                if (ret)
 553                        goto exit_unmap_prev;
 554
 555                if (WARN_ONCE(round_down(addr, dma_size) !=
 556                              round_down(addr + chunks[i].len - 1, dma_size),
 557                              "unaligned DMA address: %pad %lu %zd\n",
 558                              &addr, chunks[i].len, dma_size)) {
 559                        ret = -EFAULT;
 560                        i++;
 561                        goto exit_unmap_prev;
 562                }
 563        }
 564
 565        desc_sz = struct_size(desc, descs, nseg);
 566        desc = kmalloc(desc_sz, GFP_KERNEL);
 567        if (!desc) {
 568                ret = -ENOMEM;
 569                goto exit_unmap_all;
 570        }
 571
 572        desc->chunk_cnt = cpu_to_le32(nseg);
 573        for (i = 0; i < nseg; i++) {
 574                desc->descs[i].size = cpu_to_le32(chunks[i].len);
 575                desc->descs[i].addr = cpu_to_le64(chunks[i].dma_addr);
 576        }
 577
 578        dma_desc = dma_map_single(dev, desc, desc_sz, DMA_TO_DEVICE);
 579        ret = dma_mapping_error(dev, dma_desc);
 580        if (ret)
 581                goto exit_free_desc;
 582
 583        arg->arg.dma = true;
 584        arg->arg.buf = dma_desc;
 585        ret = __nfp_nsp_command(nsp, &arg->arg);
 586        if (ret < 0)
 587                goto exit_unmap_desc;
 588
 589        i = 0;
 590        off = 0;
 591        while (off < arg->out_size) {
 592                unsigned int len;
 593
 594                len = min_t(u64, chunks[i].len, arg->out_size - off);
 595                memcpy(arg->out_buf + off, chunks[i].chunk, len);
 596                off += len;
 597                i++;
 598        }
 599
 600exit_unmap_desc:
 601        dma_unmap_single(dev, dma_desc, desc_sz, DMA_TO_DEVICE);
 602exit_free_desc:
 603        kfree(desc);
 604exit_unmap_all:
 605        i = nseg;
 606exit_unmap_prev:
 607        while (--i >= 0)
 608                dma_unmap_single(dev, chunks[i].dma_addr, chunks[i].len,
 609                                 DMA_BIDIRECTIONAL);
 610        i = nseg;
 611exit_free_prev:
 612        while (--i >= 0)
 613                kfree(chunks[i].chunk);
 614        kfree(chunks);
 615        if (ret < 0)
 616                nfp_err(cpp, "NSP: SG DMA failed for command 0x%04x: %d (sz:%d cord:%d)\n",
 617                        arg->arg.code, ret, max_size, chunk_order);
 618        return ret;
 619}
 620
 621static int
 622nfp_nsp_command_buf_dma(struct nfp_nsp *nsp,
 623                        struct nfp_nsp_command_buf_arg *arg,
 624                        unsigned int max_size, unsigned int dma_order)
 625{
 626        unsigned int chunk_order, buf_order;
 627        struct nfp_cpp *cpp = nsp->cpp;
 628        bool sg_ok;
 629        u64 reg;
 630        int err;
 631
 632        buf_order = order_base_2(roundup_pow_of_two(max_size));
 633
 634        err = nfp_cpp_readq(cpp, nfp_resource_cpp_id(nsp->res),
 635                            nfp_resource_address(nsp->res) + NFP_CAP_CMD_DMA_SG,
 636                            &reg);
 637        if (err < 0)
 638                return err;
 639        sg_ok = reg & BIT_ULL(arg->arg.code - 1);
 640
 641        if (!sg_ok) {
 642                if (buf_order > dma_order) {
 643                        nfp_err(cpp, "NSP: can't service non-SG DMA for command 0x%04x\n",
 644                                arg->arg.code);
 645                        return -ENOMEM;
 646                }
 647                chunk_order = buf_order;
 648        } else {
 649                chunk_order = min_t(unsigned int, dma_order, PAGE_SHIFT);
 650        }
 651
 652        return nfp_nsp_command_buf_dma_sg(nsp, arg, max_size, chunk_order,
 653                                          dma_order);
 654}
 655
 656static int
 657nfp_nsp_command_buf(struct nfp_nsp *nsp, struct nfp_nsp_command_buf_arg *arg)
 658{
 659        unsigned int dma_order, def_size, max_size;
 660        struct nfp_cpp *cpp = nsp->cpp;
 661        u64 reg;
 662        int err;
 663
 664        if (nsp->ver.minor < 13) {
 665                nfp_err(cpp, "NSP: Code 0x%04x with buffer not supported (ABI %hu.%hu)\n",
 666                        arg->arg.code, nsp->ver.major, nsp->ver.minor);
 667                return -EOPNOTSUPP;
 668        }
 669
 670        err = nfp_cpp_readq(cpp, nfp_resource_cpp_id(nsp->res),
 671                            nfp_resource_address(nsp->res) +
 672                            NSP_DFLT_BUFFER_CONFIG,
 673                            &reg);
 674        if (err < 0)
 675                return err;
 676
 677        /* Zero out undefined part of the out buffer */
 678        if (arg->out_buf && arg->out_size && arg->out_size > arg->in_size)
 679                memset(arg->out_buf, 0, arg->out_size - arg->in_size);
 680
 681        max_size = max(arg->in_size, arg->out_size);
 682        def_size = FIELD_GET(NSP_DFLT_BUFFER_SIZE_MB, reg) * SZ_1M +
 683                   FIELD_GET(NSP_DFLT_BUFFER_SIZE_4KB, reg) * SZ_4K;
 684        dma_order = FIELD_GET(NSP_DFLT_BUFFER_DMA_CHUNK_ORDER, reg);
 685        if (def_size >= max_size) {
 686                return nfp_nsp_command_buf_def(nsp, arg);
 687        } else if (!dma_order) {
 688                nfp_err(cpp, "NSP: default buffer too small for command 0x%04x (%u < %u)\n",
 689                        arg->arg.code, def_size, max_size);
 690                return -EINVAL;
 691        }
 692
 693        return nfp_nsp_command_buf_dma(nsp, arg, max_size, dma_order);
 694}
 695
 696int nfp_nsp_wait(struct nfp_nsp *state)
 697{
 698        const unsigned long wait_until = jiffies + NFP_NSP_TIMEOUT_BOOT * HZ;
 699        int err;
 700
 701        nfp_dbg(state->cpp, "Waiting for NSP to respond (%u sec max).\n",
 702                NFP_NSP_TIMEOUT_BOOT);
 703
 704        for (;;) {
 705                const unsigned long start_time = jiffies;
 706
 707                err = nfp_nsp_command(state, SPCODE_NOOP);
 708                if (err != -EAGAIN)
 709                        break;
 710
 711                if (msleep_interruptible(25)) {
 712                        err = -ERESTARTSYS;
 713                        break;
 714                }
 715
 716                if (time_after(start_time, wait_until)) {
 717                        err = -ETIMEDOUT;
 718                        break;
 719                }
 720        }
 721        if (err)
 722                nfp_err(state->cpp, "NSP failed to respond %d\n", err);
 723
 724        return err;
 725}
 726
 727int nfp_nsp_device_soft_reset(struct nfp_nsp *state)
 728{
 729        return nfp_nsp_command(state, SPCODE_SOFT_RESET);
 730}
 731
 732int nfp_nsp_mac_reinit(struct nfp_nsp *state)
 733{
 734        return nfp_nsp_command(state, SPCODE_MAC_INIT);
 735}
 736
 737static void nfp_nsp_load_fw_extended_msg(struct nfp_nsp *state, u32 ret_val)
 738{
 739        static const char * const major_msg[] = {
 740                /* 0 */ "Firmware from driver loaded",
 741                /* 1 */ "Firmware from flash loaded",
 742                /* 2 */ "Firmware loading failure",
 743        };
 744        static const char * const minor_msg[] = {
 745                /*  0 */ "",
 746                /*  1 */ "no named partition on flash",
 747                /*  2 */ "error reading from flash",
 748                /*  3 */ "can not deflate",
 749                /*  4 */ "not a trusted file",
 750                /*  5 */ "can not parse FW file",
 751                /*  6 */ "MIP not found in FW file",
 752                /*  7 */ "null firmware name in MIP",
 753                /*  8 */ "FW version none",
 754                /*  9 */ "FW build number none",
 755                /* 10 */ "no FW selection policy HWInfo key found",
 756                /* 11 */ "static FW selection policy",
 757                /* 12 */ "FW version has precedence",
 758                /* 13 */ "different FW application load requested",
 759                /* 14 */ "development build",
 760        };
 761        unsigned int major, minor;
 762        const char *level;
 763
 764        major = FIELD_GET(NFP_FW_LOAD_RET_MAJOR, ret_val);
 765        minor = FIELD_GET(NFP_FW_LOAD_RET_MINOR, ret_val);
 766
 767        if (!nfp_nsp_has_stored_fw_load(state))
 768                return;
 769
 770        /* Lower the message level in legacy case */
 771        if (major == 0 && (minor == 0 || minor == 10))
 772                level = KERN_DEBUG;
 773        else if (major == 2)
 774                level = KERN_ERR;
 775        else
 776                level = KERN_INFO;
 777
 778        if (major >= ARRAY_SIZE(major_msg))
 779                nfp_printk(level, state->cpp, "FW loading status: %x\n",
 780                           ret_val);
 781        else if (minor >= ARRAY_SIZE(minor_msg))
 782                nfp_printk(level, state->cpp, "%s, reason code: %d\n",
 783                           major_msg[major], minor);
 784        else
 785                nfp_printk(level, state->cpp, "%s%c %s\n",
 786                           major_msg[major], minor ? ',' : '.',
 787                           minor_msg[minor]);
 788}
 789
 790int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw)
 791{
 792        struct nfp_nsp_command_buf_arg load_fw = {
 793                {
 794                        .code           = SPCODE_FW_LOAD,
 795                        .option         = fw->size,
 796                        .error_cb       = nfp_nsp_load_fw_extended_msg,
 797                },
 798                .in_buf         = fw->data,
 799                .in_size        = fw->size,
 800        };
 801        int ret;
 802
 803        ret = nfp_nsp_command_buf(state, &load_fw);
 804        if (ret < 0)
 805                return ret;
 806
 807        nfp_nsp_load_fw_extended_msg(state, ret);
 808        return 0;
 809}
 810
 811int nfp_nsp_write_flash(struct nfp_nsp *state, const struct firmware *fw)
 812{
 813        struct nfp_nsp_command_buf_arg write_flash = {
 814                {
 815                        .code           = SPCODE_NSP_WRITE_FLASH,
 816                        .option         = fw->size,
 817                        .timeout_sec    = 900,
 818                },
 819                .in_buf         = fw->data,
 820                .in_size        = fw->size,
 821        };
 822
 823        return nfp_nsp_command_buf(state, &write_flash);
 824}
 825
 826int nfp_nsp_read_eth_table(struct nfp_nsp *state, void *buf, unsigned int size)
 827{
 828        struct nfp_nsp_command_buf_arg eth_rescan = {
 829                {
 830                        .code           = SPCODE_ETH_RESCAN,
 831                        .option         = size,
 832                },
 833                .out_buf        = buf,
 834                .out_size       = size,
 835        };
 836
 837        return nfp_nsp_command_buf(state, &eth_rescan);
 838}
 839
 840int nfp_nsp_write_eth_table(struct nfp_nsp *state,
 841                            const void *buf, unsigned int size)
 842{
 843        struct nfp_nsp_command_buf_arg eth_ctrl = {
 844                {
 845                        .code           = SPCODE_ETH_CONTROL,
 846                        .option         = size,
 847                },
 848                .in_buf         = buf,
 849                .in_size        = size,
 850        };
 851
 852        return nfp_nsp_command_buf(state, &eth_ctrl);
 853}
 854
 855int nfp_nsp_read_identify(struct nfp_nsp *state, void *buf, unsigned int size)
 856{
 857        struct nfp_nsp_command_buf_arg identify = {
 858                {
 859                        .code           = SPCODE_NSP_IDENTIFY,
 860                        .option         = size,
 861                },
 862                .out_buf        = buf,
 863                .out_size       = size,
 864        };
 865
 866        return nfp_nsp_command_buf(state, &identify);
 867}
 868
 869int nfp_nsp_read_sensors(struct nfp_nsp *state, unsigned int sensor_mask,
 870                         void *buf, unsigned int size)
 871{
 872        struct nfp_nsp_command_buf_arg sensors = {
 873                {
 874                        .code           = SPCODE_NSP_SENSORS,
 875                        .option         = sensor_mask,
 876                },
 877                .out_buf        = buf,
 878                .out_size       = size,
 879        };
 880
 881        return nfp_nsp_command_buf(state, &sensors);
 882}
 883
 884int nfp_nsp_load_stored_fw(struct nfp_nsp *state)
 885{
 886        const struct nfp_nsp_command_arg arg = {
 887                .code           = SPCODE_FW_STORED,
 888                .error_cb       = nfp_nsp_load_fw_extended_msg,
 889        };
 890        int ret;
 891
 892        ret = __nfp_nsp_command(state, &arg);
 893        if (ret < 0)
 894                return ret;
 895
 896        nfp_nsp_load_fw_extended_msg(state, ret);
 897        return 0;
 898}
 899
 900static int
 901__nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size,
 902                        bool optional)
 903{
 904        struct nfp_nsp_command_buf_arg hwinfo_lookup = {
 905                {
 906                        .code           = SPCODE_HWINFO_LOOKUP,
 907                        .option         = size,
 908                        .error_quiet    = optional,
 909                },
 910                .in_buf         = buf,
 911                .in_size        = size,
 912                .out_buf        = buf,
 913                .out_size       = size,
 914        };
 915
 916        return nfp_nsp_command_buf(state, &hwinfo_lookup);
 917}
 918
 919int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size)
 920{
 921        int err;
 922
 923        size = min_t(u32, size, NFP_HWINFO_LOOKUP_SIZE);
 924
 925        err = __nfp_nsp_hwinfo_lookup(state, buf, size, false);
 926        if (err)
 927                return err;
 928
 929        if (strnlen(buf, size) == size) {
 930                nfp_err(state->cpp, "NSP HWinfo value not NULL-terminated\n");
 931                return -EINVAL;
 932        }
 933
 934        return 0;
 935}
 936
 937int nfp_nsp_hwinfo_lookup_optional(struct nfp_nsp *state, void *buf,
 938                                   unsigned int size, const char *default_val)
 939{
 940        int err;
 941
 942        /* Ensure that the default value is usable irrespective of whether
 943         * it is actually going to be used.
 944         */
 945        if (strnlen(default_val, size) == size)
 946                return -EINVAL;
 947
 948        if (!nfp_nsp_has_hwinfo_lookup(state)) {
 949                strcpy(buf, default_val);
 950                return 0;
 951        }
 952
 953        size = min_t(u32, size, NFP_HWINFO_LOOKUP_SIZE);
 954
 955        err = __nfp_nsp_hwinfo_lookup(state, buf, size, true);
 956        if (err) {
 957                if (err == -ENOENT) {
 958                        strcpy(buf, default_val);
 959                        return 0;
 960                }
 961
 962                nfp_err(state->cpp, "NSP HWinfo lookup failed: %d\n", err);
 963                return err;
 964        }
 965
 966        if (strnlen(buf, size) == size) {
 967                nfp_err(state->cpp, "NSP HWinfo value not NULL-terminated\n");
 968                return -EINVAL;
 969        }
 970
 971        return 0;
 972}
 973
 974int nfp_nsp_hwinfo_set(struct nfp_nsp *state, void *buf, unsigned int size)
 975{
 976        struct nfp_nsp_command_buf_arg hwinfo_set = {
 977                {
 978                        .code           = SPCODE_HWINFO_SET,
 979                        .option         = size,
 980                },
 981                .in_buf         = buf,
 982                .in_size        = size,
 983        };
 984
 985        return nfp_nsp_command_buf(state, &hwinfo_set);
 986}
 987
 988int nfp_nsp_fw_loaded(struct nfp_nsp *state)
 989{
 990        const struct nfp_nsp_command_arg arg = {
 991                .code           = SPCODE_FW_LOADED,
 992        };
 993
 994        return __nfp_nsp_command(state, &arg);
 995}
 996
 997int nfp_nsp_versions(struct nfp_nsp *state, void *buf, unsigned int size)
 998{
 999        struct nfp_nsp_command_buf_arg versions = {
1000                {
1001                        .code           = SPCODE_VERSIONS,
1002                        .option         = min_t(u32, size, NFP_VERSIONS_SIZE),
1003                },
1004                .out_buf        = buf,
1005                .out_size       = min_t(u32, size, NFP_VERSIONS_SIZE),
1006        };
1007
1008        return nfp_nsp_command_buf(state, &versions);
1009}
1010
1011const char *nfp_nsp_versions_get(enum nfp_nsp_versions id, bool flash,
1012                                 const u8 *buf, unsigned int size)
1013{
1014        static const u32 id2off[] = {
1015                [NFP_VERSIONS_BSP] =    NFP_VERSIONS_BSP_OFF,
1016                [NFP_VERSIONS_CPLD] =   NFP_VERSIONS_CPLD_OFF,
1017                [NFP_VERSIONS_APP] =    NFP_VERSIONS_APP_OFF,
1018                [NFP_VERSIONS_BUNDLE] = NFP_VERSIONS_BUNDLE_OFF,
1019                [NFP_VERSIONS_UNDI] =   NFP_VERSIONS_UNDI_OFF,
1020                [NFP_VERSIONS_NCSI] =   NFP_VERSIONS_NCSI_OFF,
1021                [NFP_VERSIONS_CFGR] =   NFP_VERSIONS_CFGR_OFF,
1022        };
1023        unsigned int field, buf_field_cnt, buf_off;
1024
1025        if (id >= ARRAY_SIZE(id2off) || !id2off[id])
1026                return ERR_PTR(-EINVAL);
1027
1028        field = id * 2 + flash;
1029
1030        buf_field_cnt = get_unaligned_le16(buf);
1031        if (buf_field_cnt <= field)
1032                return ERR_PTR(-ENOENT);
1033
1034        buf_off = get_unaligned_le16(buf + id2off[id] + flash * 2);
1035        if (!buf_off)
1036                return ERR_PTR(-ENOENT);
1037
1038        if (buf_off >= size)
1039                return ERR_PTR(-EINVAL);
1040        if (strnlen(&buf[buf_off], size - buf_off) == size - buf_off)
1041                return ERR_PTR(-EINVAL);
1042
1043        return (const char *)&buf[buf_off];
1044}
1045
1046static int
1047__nfp_nsp_module_eeprom(struct nfp_nsp *state, void *buf, unsigned int size)
1048{
1049        struct nfp_nsp_command_buf_arg module_eeprom = {
1050                {
1051                        .code           = SPCODE_READ_SFF_EEPROM,
1052                        .option         = size,
1053                },
1054                .in_buf         = buf,
1055                .in_size        = size,
1056                .out_buf        = buf,
1057                .out_size       = size,
1058        };
1059
1060        return nfp_nsp_command_buf(state, &module_eeprom);
1061}
1062
1063int nfp_nsp_read_module_eeprom(struct nfp_nsp *state, int eth_index,
1064                               unsigned int offset, void *data,
1065                               unsigned int len, unsigned int *read_len)
1066{
1067        struct eeprom_buf {
1068                u8 metalen;
1069                __le16 length;
1070                __le16 offset;
1071                __le16 readlen;
1072                u8 eth_index;
1073                u8 data[];
1074        } __packed *buf;
1075        int bufsz, ret;
1076
1077        BUILD_BUG_ON(offsetof(struct eeprom_buf, data) % 8);
1078
1079        /* Buffer must be large enough and rounded to the next block size. */
1080        bufsz = struct_size(buf, data, round_up(len, NSP_SFF_EEPROM_BLOCK_LEN));
1081        buf = kzalloc(bufsz, GFP_KERNEL);
1082        if (!buf)
1083                return -ENOMEM;
1084
1085        buf->metalen =
1086                offsetof(struct eeprom_buf, data) / NSP_SFF_EEPROM_BLOCK_LEN;
1087        buf->length = cpu_to_le16(len);
1088        buf->offset = cpu_to_le16(offset);
1089        buf->eth_index = eth_index;
1090
1091        ret = __nfp_nsp_module_eeprom(state, buf, bufsz);
1092
1093        *read_len = min_t(unsigned int, len, le16_to_cpu(buf->readlen));
1094        if (*read_len)
1095                memcpy(data, buf->data, *read_len);
1096
1097        if (!ret && *read_len < len)
1098                ret = -EIO;
1099
1100        kfree(buf);
1101
1102        return ret;
1103}
1104