linux/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015-2017 Netronome Systems, Inc.
   3 *
   4 * This software is dual licensed under the GNU General License Version 2,
   5 * June 1991 as shown in the file COPYING in the top-level directory of this
   6 * source tree or the BSD 2-Clause License provided below.  You have the
   7 * option to license this software under the complete terms of either license.
   8 *
   9 * The BSD 2-Clause License:
  10 *
  11 *     Redistribution and use in source and binary forms, with or
  12 *     without modification, are permitted provided that the following
  13 *     conditions are met:
  14 *
  15 *      1. Redistributions of source code must retain the above
  16 *         copyright notice, this list of conditions and the following
  17 *         disclaimer.
  18 *
  19 *      2. Redistributions in binary form must reproduce the above
  20 *         copyright notice, this list of conditions and the following
  21 *         disclaimer in the documentation and/or other materials
  22 *         provided with the distribution.
  23 *
  24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  31 * SOFTWARE.
  32 */
  33
  34/*
  35 * nfp_nsp.c
  36 * Author: Jakub Kicinski <jakub.kicinski@netronome.com>
  37 *         Jason McMullan <jason.mcmullan@netronome.com>
  38 */
  39
  40#include <linux/bitfield.h>
  41#include <linux/delay.h>
  42#include <linux/firmware.h>
  43#include <linux/kernel.h>
  44#include <linux/kthread.h>
  45#include <linux/sizes.h>
  46#include <linux/slab.h>
  47
  48#define NFP_SUBSYS "nfp_nsp"
  49
  50#include "nfp.h"
  51#include "nfp_cpp.h"
  52#include "nfp_nsp.h"
  53
  54#define NFP_NSP_TIMEOUT_DEFAULT 30
  55#define NFP_NSP_TIMEOUT_BOOT    30
  56
  57/* Offsets relative to the CSR base */
  58#define NSP_STATUS              0x00
  59#define   NSP_STATUS_MAGIC      GENMASK_ULL(63, 48)
  60#define   NSP_STATUS_MAJOR      GENMASK_ULL(47, 44)
  61#define   NSP_STATUS_MINOR      GENMASK_ULL(43, 32)
  62#define   NSP_STATUS_CODE       GENMASK_ULL(31, 16)
  63#define   NSP_STATUS_RESULT     GENMASK_ULL(15, 8)
  64#define   NSP_STATUS_BUSY       BIT_ULL(0)
  65
  66#define NSP_COMMAND             0x08
  67#define   NSP_COMMAND_OPTION    GENMASK_ULL(63, 32)
  68#define   NSP_COMMAND_CODE      GENMASK_ULL(31, 16)
  69#define   NSP_COMMAND_START     BIT_ULL(0)
  70
  71/* CPP address to retrieve the data from */
  72#define NSP_BUFFER              0x10
  73#define   NSP_BUFFER_CPP        GENMASK_ULL(63, 40)
  74#define   NSP_BUFFER_ADDRESS    GENMASK_ULL(39, 0)
  75
  76#define NSP_DFLT_BUFFER         0x18
  77#define   NSP_DFLT_BUFFER_CPP   GENMASK_ULL(63, 40)
  78#define   NSP_DFLT_BUFFER_ADDRESS       GENMASK_ULL(39, 0)
  79
  80#define NSP_DFLT_BUFFER_CONFIG  0x20
  81#define   NSP_DFLT_BUFFER_SIZE_MB       GENMASK_ULL(7, 0)
  82
  83#define NSP_MAGIC               0xab10
  84#define NSP_MAJOR               0
  85#define NSP_MINOR               8
  86
  87#define NSP_CODE_MAJOR          GENMASK(15, 12)
  88#define NSP_CODE_MINOR          GENMASK(11, 0)
  89
  90enum nfp_nsp_cmd {
  91        SPCODE_NOOP             = 0, /* No operation */
  92        SPCODE_SOFT_RESET       = 1, /* Soft reset the NFP */
  93        SPCODE_FW_DEFAULT       = 2, /* Load default (UNDI) FW */
  94        SPCODE_PHY_INIT         = 3, /* Initialize the PHY */
  95        SPCODE_MAC_INIT         = 4, /* Initialize the MAC */
  96        SPCODE_PHY_RXADAPT      = 5, /* Re-run PHY RX Adaptation */
  97        SPCODE_FW_LOAD          = 6, /* Load fw from buffer, len in option */
  98        SPCODE_ETH_RESCAN       = 7, /* Rescan ETHs, write ETH_TABLE to buf */
  99        SPCODE_ETH_CONTROL      = 8, /* Update media config from buffer */
 100        SPCODE_NSP_WRITE_FLASH  = 11, /* Load and flash image from buffer */
 101        SPCODE_NSP_SENSORS      = 12, /* Read NSP sensor(s) */
 102        SPCODE_NSP_IDENTIFY     = 13, /* Read NSP version */
 103};
 104
 105static const struct {
 106        int code;
 107        const char *msg;
 108} nsp_errors[] = {
 109        { 6010, "could not map to phy for port" },
 110        { 6011, "not an allowed rate/lanes for port" },
 111        { 6012, "not an allowed rate/lanes for port" },
 112        { 6013, "high/low error, change other port first" },
 113        { 6014, "config not found in flash" },
 114};
 115
 116struct nfp_nsp {
 117        struct nfp_cpp *cpp;
 118        struct nfp_resource *res;
 119        struct {
 120                u16 major;
 121                u16 minor;
 122        } ver;
 123
 124        /* Eth table config state */
 125        bool modified;
 126        unsigned int idx;
 127        void *entries;
 128};
 129
 130struct nfp_cpp *nfp_nsp_cpp(struct nfp_nsp *state)
 131{
 132        return state->cpp;
 133}
 134
 135bool nfp_nsp_config_modified(struct nfp_nsp *state)
 136{
 137        return state->modified;
 138}
 139
 140void nfp_nsp_config_set_modified(struct nfp_nsp *state, bool modified)
 141{
 142        state->modified = modified;
 143}
 144
 145void *nfp_nsp_config_entries(struct nfp_nsp *state)
 146{
 147        return state->entries;
 148}
 149
 150unsigned int nfp_nsp_config_idx(struct nfp_nsp *state)
 151{
 152        return state->idx;
 153}
 154
 155void
 156nfp_nsp_config_set_state(struct nfp_nsp *state, void *entries, unsigned int idx)
 157{
 158        state->entries = entries;
 159        state->idx = idx;
 160}
 161
 162void nfp_nsp_config_clear_state(struct nfp_nsp *state)
 163{
 164        state->entries = NULL;
 165        state->idx = 0;
 166}
 167
 168static void nfp_nsp_print_extended_error(struct nfp_nsp *state, u32 ret_val)
 169{
 170        int i;
 171
 172        if (!ret_val)
 173                return;
 174
 175        for (i = 0; i < ARRAY_SIZE(nsp_errors); i++)
 176                if (ret_val == nsp_errors[i].code)
 177                        nfp_err(state->cpp, "err msg: %s\n", nsp_errors[i].msg);
 178}
 179
 180static int nfp_nsp_check(struct nfp_nsp *state)
 181{
 182        struct nfp_cpp *cpp = state->cpp;
 183        u64 nsp_status, reg;
 184        u32 nsp_cpp;
 185        int err;
 186
 187        nsp_cpp = nfp_resource_cpp_id(state->res);
 188        nsp_status = nfp_resource_address(state->res) + NSP_STATUS;
 189
 190        err = nfp_cpp_readq(cpp, nsp_cpp, nsp_status, &reg);
 191        if (err < 0)
 192                return err;
 193
 194        if (FIELD_GET(NSP_STATUS_MAGIC, reg) != NSP_MAGIC) {
 195                nfp_err(cpp, "Cannot detect NFP Service Processor\n");
 196                return -ENODEV;
 197        }
 198
 199        state->ver.major = FIELD_GET(NSP_STATUS_MAJOR, reg);
 200        state->ver.minor = FIELD_GET(NSP_STATUS_MINOR, reg);
 201
 202        if (state->ver.major != NSP_MAJOR || state->ver.minor < NSP_MINOR) {
 203                nfp_err(cpp, "Unsupported ABI %hu.%hu\n",
 204                        state->ver.major, state->ver.minor);
 205                return -EINVAL;
 206        }
 207
 208        if (reg & NSP_STATUS_BUSY) {
 209                nfp_err(cpp, "Service processor busy!\n");
 210                return -EBUSY;
 211        }
 212
 213        return 0;
 214}
 215
 216/**
 217 * nfp_nsp_open() - Prepare for communication and lock the NSP resource.
 218 * @cpp:        NFP CPP Handle
 219 */
 220struct nfp_nsp *nfp_nsp_open(struct nfp_cpp *cpp)
 221{
 222        struct nfp_resource *res;
 223        struct nfp_nsp *state;
 224        int err;
 225
 226        res = nfp_resource_acquire(cpp, NFP_RESOURCE_NSP);
 227        if (IS_ERR(res))
 228                return (void *)res;
 229
 230        state = kzalloc(sizeof(*state), GFP_KERNEL);
 231        if (!state) {
 232                nfp_resource_release(res);
 233                return ERR_PTR(-ENOMEM);
 234        }
 235        state->cpp = cpp;
 236        state->res = res;
 237
 238        err = nfp_nsp_check(state);
 239        if (err) {
 240                nfp_nsp_close(state);
 241                return ERR_PTR(err);
 242        }
 243
 244        return state;
 245}
 246
 247/**
 248 * nfp_nsp_close() - Clean up and unlock the NSP resource.
 249 * @state:      NFP SP state
 250 */
 251void nfp_nsp_close(struct nfp_nsp *state)
 252{
 253        nfp_resource_release(state->res);
 254        kfree(state);
 255}
 256
 257u16 nfp_nsp_get_abi_ver_major(struct nfp_nsp *state)
 258{
 259        return state->ver.major;
 260}
 261
 262u16 nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state)
 263{
 264        return state->ver.minor;
 265}
 266
 267static int
 268nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg, u32 nsp_cpp, u64 addr,
 269                 u64 mask, u64 val, u32 timeout_sec)
 270{
 271        const unsigned long wait_until = jiffies + timeout_sec * HZ;
 272        int err;
 273
 274        for (;;) {
 275                const unsigned long start_time = jiffies;
 276
 277                err = nfp_cpp_readq(cpp, nsp_cpp, addr, reg);
 278                if (err < 0)
 279                        return err;
 280
 281                if ((*reg & mask) == val)
 282                        return 0;
 283
 284                msleep(25);
 285
 286                if (time_after(start_time, wait_until))
 287                        return -ETIMEDOUT;
 288        }
 289}
 290
 291/**
 292 * __nfp_nsp_command() - Execute a command on the NFP Service Processor
 293 * @state:      NFP SP state
 294 * @code:       NFP SP Command Code
 295 * @option:     NFP SP Command Argument
 296 * @buff_cpp:   NFP SP Buffer CPP Address info
 297 * @buff_addr:  NFP SP Buffer Host address
 298 * @timeout_sec:Timeout value to wait for completion in seconds
 299 *
 300 * Return: 0 for success with no result
 301 *
 302 *       positive value for NSP completion with a result code
 303 *
 304 *      -EAGAIN if the NSP is not yet present
 305 *      -ENODEV if the NSP is not a supported model
 306 *      -EBUSY if the NSP is stuck
 307 *      -EINTR if interrupted while waiting for completion
 308 *      -ETIMEDOUT if the NSP took longer than @timeout_sec seconds to complete
 309 */
 310static int
 311__nfp_nsp_command(struct nfp_nsp *state, u16 code, u32 option, u32 buff_cpp,
 312                  u64 buff_addr, u32 timeout_sec)
 313{
 314        u64 reg, ret_val, nsp_base, nsp_buffer, nsp_status, nsp_command;
 315        struct nfp_cpp *cpp = state->cpp;
 316        u32 nsp_cpp;
 317        int err;
 318
 319        nsp_cpp = nfp_resource_cpp_id(state->res);
 320        nsp_base = nfp_resource_address(state->res);
 321        nsp_status = nsp_base + NSP_STATUS;
 322        nsp_command = nsp_base + NSP_COMMAND;
 323        nsp_buffer = nsp_base + NSP_BUFFER;
 324
 325        err = nfp_nsp_check(state);
 326        if (err)
 327                return err;
 328
 329        if (!FIELD_FIT(NSP_BUFFER_CPP, buff_cpp >> 8) ||
 330            !FIELD_FIT(NSP_BUFFER_ADDRESS, buff_addr)) {
 331                nfp_err(cpp, "Host buffer out of reach %08x %016llx\n",
 332                        buff_cpp, buff_addr);
 333                return -EINVAL;
 334        }
 335
 336        err = nfp_cpp_writeq(cpp, nsp_cpp, nsp_buffer,
 337                             FIELD_PREP(NSP_BUFFER_CPP, buff_cpp >> 8) |
 338                             FIELD_PREP(NSP_BUFFER_ADDRESS, buff_addr));
 339        if (err < 0)
 340                return err;
 341
 342        err = nfp_cpp_writeq(cpp, nsp_cpp, nsp_command,
 343                             FIELD_PREP(NSP_COMMAND_OPTION, option) |
 344                             FIELD_PREP(NSP_COMMAND_CODE, code) |
 345                             FIELD_PREP(NSP_COMMAND_START, 1));
 346        if (err < 0)
 347                return err;
 348
 349        /* Wait for NSP_COMMAND_START to go to 0 */
 350        err = nfp_nsp_wait_reg(cpp, &reg, nsp_cpp, nsp_command,
 351                               NSP_COMMAND_START, 0, NFP_NSP_TIMEOUT_DEFAULT);
 352        if (err) {
 353                nfp_err(cpp, "Error %d waiting for code 0x%04x to start\n",
 354                        err, code);
 355                return err;
 356        }
 357
 358        /* Wait for NSP_STATUS_BUSY to go to 0 */
 359        err = nfp_nsp_wait_reg(cpp, &reg, nsp_cpp, nsp_status, NSP_STATUS_BUSY,
 360                               0, timeout_sec);
 361        if (err) {
 362                nfp_err(cpp, "Error %d waiting for code 0x%04x to complete\n",
 363                        err, code);
 364                return err;
 365        }
 366
 367        err = nfp_cpp_readq(cpp, nsp_cpp, nsp_command, &ret_val);
 368        if (err < 0)
 369                return err;
 370        ret_val = FIELD_GET(NSP_COMMAND_OPTION, ret_val);
 371
 372        err = FIELD_GET(NSP_STATUS_RESULT, reg);
 373        if (err) {
 374                nfp_warn(cpp, "Result (error) code set: %d (%d) command: %d\n",
 375                         -err, (int)ret_val, code);
 376                nfp_nsp_print_extended_error(state, ret_val);
 377                return -err;
 378        }
 379
 380        return ret_val;
 381}
 382
 383static int
 384nfp_nsp_command(struct nfp_nsp *state, u16 code, u32 option, u32 buff_cpp,
 385                u64 buff_addr)
 386{
 387        return __nfp_nsp_command(state, code, option, buff_cpp, buff_addr,
 388                                 NFP_NSP_TIMEOUT_DEFAULT);
 389}
 390
 391static int
 392__nfp_nsp_command_buf(struct nfp_nsp *nsp, u16 code, u32 option,
 393                      const void *in_buf, unsigned int in_size, void *out_buf,
 394                      unsigned int out_size, u32 timeout_sec)
 395{
 396        struct nfp_cpp *cpp = nsp->cpp;
 397        unsigned int max_size;
 398        u64 reg, cpp_buf;
 399        int ret, err;
 400        u32 cpp_id;
 401
 402        if (nsp->ver.minor < 13) {
 403                nfp_err(cpp, "NSP: Code 0x%04x with buffer not supported (ABI %hu.%hu)\n",
 404                        code, nsp->ver.major, nsp->ver.minor);
 405                return -EOPNOTSUPP;
 406        }
 407
 408        err = nfp_cpp_readq(cpp, nfp_resource_cpp_id(nsp->res),
 409                            nfp_resource_address(nsp->res) +
 410                            NSP_DFLT_BUFFER_CONFIG,
 411                            &reg);
 412        if (err < 0)
 413                return err;
 414
 415        max_size = max(in_size, out_size);
 416        if (FIELD_GET(NSP_DFLT_BUFFER_SIZE_MB, reg) * SZ_1M < max_size) {
 417                nfp_err(cpp, "NSP: default buffer too small for command 0x%04x (%llu < %u)\n",
 418                        code, FIELD_GET(NSP_DFLT_BUFFER_SIZE_MB, reg) * SZ_1M,
 419                        max_size);
 420                return -EINVAL;
 421        }
 422
 423        err = nfp_cpp_readq(cpp, nfp_resource_cpp_id(nsp->res),
 424                            nfp_resource_address(nsp->res) +
 425                            NSP_DFLT_BUFFER,
 426                            &reg);
 427        if (err < 0)
 428                return err;
 429
 430        cpp_id = FIELD_GET(NSP_DFLT_BUFFER_CPP, reg) << 8;
 431        cpp_buf = FIELD_GET(NSP_DFLT_BUFFER_ADDRESS, reg);
 432
 433        if (in_buf && in_size) {
 434                err = nfp_cpp_write(cpp, cpp_id, cpp_buf, in_buf, in_size);
 435                if (err < 0)
 436                        return err;
 437        }
 438        /* Zero out remaining part of the buffer */
 439        if (out_buf && out_size && out_size > in_size) {
 440                memset(out_buf, 0, out_size - in_size);
 441                err = nfp_cpp_write(cpp, cpp_id, cpp_buf + in_size,
 442                                    out_buf, out_size - in_size);
 443                if (err < 0)
 444                        return err;
 445        }
 446
 447        ret = __nfp_nsp_command(nsp, code, option, cpp_id, cpp_buf,
 448                                timeout_sec);
 449        if (ret < 0)
 450                return ret;
 451
 452        if (out_buf && out_size) {
 453                err = nfp_cpp_read(cpp, cpp_id, cpp_buf, out_buf, out_size);
 454                if (err < 0)
 455                        return err;
 456        }
 457
 458        return ret;
 459}
 460
 461static int
 462nfp_nsp_command_buf(struct nfp_nsp *nsp, u16 code, u32 option,
 463                    const void *in_buf, unsigned int in_size, void *out_buf,
 464                    unsigned int out_size)
 465{
 466        return __nfp_nsp_command_buf(nsp, code, option, in_buf, in_size,
 467                                     out_buf, out_size,
 468                                     NFP_NSP_TIMEOUT_DEFAULT);
 469}
 470
 471int nfp_nsp_wait(struct nfp_nsp *state)
 472{
 473        const unsigned long wait_until = jiffies + NFP_NSP_TIMEOUT_BOOT * HZ;
 474        int err;
 475
 476        nfp_dbg(state->cpp, "Waiting for NSP to respond (%u sec max).\n",
 477                NFP_NSP_TIMEOUT_BOOT);
 478
 479        for (;;) {
 480                const unsigned long start_time = jiffies;
 481
 482                err = nfp_nsp_command(state, SPCODE_NOOP, 0, 0, 0);
 483                if (err != -EAGAIN)
 484                        break;
 485
 486                if (msleep_interruptible(25)) {
 487                        err = -ERESTARTSYS;
 488                        break;
 489                }
 490
 491                if (time_after(start_time, wait_until)) {
 492                        err = -ETIMEDOUT;
 493                        break;
 494                }
 495        }
 496        if (err)
 497                nfp_err(state->cpp, "NSP failed to respond %d\n", err);
 498
 499        return err;
 500}
 501
 502int nfp_nsp_device_soft_reset(struct nfp_nsp *state)
 503{
 504        return nfp_nsp_command(state, SPCODE_SOFT_RESET, 0, 0, 0);
 505}
 506
 507int nfp_nsp_mac_reinit(struct nfp_nsp *state)
 508{
 509        return nfp_nsp_command(state, SPCODE_MAC_INIT, 0, 0, 0);
 510}
 511
 512int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw)
 513{
 514        return nfp_nsp_command_buf(state, SPCODE_FW_LOAD, fw->size, fw->data,
 515                                   fw->size, NULL, 0);
 516}
 517
 518int nfp_nsp_write_flash(struct nfp_nsp *state, const struct firmware *fw)
 519{
 520        /* The flash time is specified to take a maximum of 70s so we add an
 521         * additional factor to this spec time.
 522         */
 523        u32 timeout_sec = 2.5 * 70;
 524
 525        return __nfp_nsp_command_buf(state, SPCODE_NSP_WRITE_FLASH, fw->size,
 526                                     fw->data, fw->size, NULL, 0, timeout_sec);
 527}
 528
 529int nfp_nsp_read_eth_table(struct nfp_nsp *state, void *buf, unsigned int size)
 530{
 531        return nfp_nsp_command_buf(state, SPCODE_ETH_RESCAN, size, NULL, 0,
 532                                   buf, size);
 533}
 534
 535int nfp_nsp_write_eth_table(struct nfp_nsp *state,
 536                            const void *buf, unsigned int size)
 537{
 538        return nfp_nsp_command_buf(state, SPCODE_ETH_CONTROL, size, buf, size,
 539                                   NULL, 0);
 540}
 541
 542int nfp_nsp_read_identify(struct nfp_nsp *state, void *buf, unsigned int size)
 543{
 544        return nfp_nsp_command_buf(state, SPCODE_NSP_IDENTIFY, size, NULL, 0,
 545                                   buf, size);
 546}
 547
 548int nfp_nsp_read_sensors(struct nfp_nsp *state, unsigned int sensor_mask,
 549                         void *buf, unsigned int size)
 550{
 551        return nfp_nsp_command_buf(state, SPCODE_NSP_SENSORS, sensor_mask,
 552                                   NULL, 0, buf, size);
 553}
 554