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