cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nfp_nsp.c (26756B)


      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 = kcalloc(nseg, sizeof(*chunks), 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}