Skip to content

Commit 4650b75

Browse files
committed
Merge branch 'nfp-ethtool-flash-updates'
Jakub Kicinski says: ==================== nfp: ethtool flash updates Dirk says: This series adds the ability to update the control FW with ethtool. It should be noted that the locking scheme here is to release the RTNL lock before the flashing operation and to take it again afterwards to ensure consistent state from the core code point of view. In this time, we take a reference to the device to prevent the device being freed while its being flashed. This provides protection for the device being flashed while at the same time not holding up any networking related functions which would otherwise be locked out due to RTNL being held. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents d31d38a + 7a74156 commit 4650b75

File tree

3 files changed

+110
-17
lines changed

3 files changed

+110
-17
lines changed

drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <linux/interrupt.h>
4848
#include <linux/pci.h>
4949
#include <linux/ethtool.h>
50+
#include <linux/firmware.h>
5051

5152
#include "nfpcore/nfp.h"
5253
#include "nfpcore/nfp_nsp.h"
@@ -1269,6 +1270,57 @@ static int nfp_net_set_channels(struct net_device *netdev,
12691270
return nfp_net_set_num_rings(nn, total_rx, total_tx);
12701271
}
12711272

1273+
static int
1274+
nfp_net_flash_device(struct net_device *netdev, struct ethtool_flash *flash)
1275+
{
1276+
const struct firmware *fw;
1277+
struct nfp_app *app;
1278+
struct nfp_nsp *nsp;
1279+
struct device *dev;
1280+
int err;
1281+
1282+
if (flash->region != ETHTOOL_FLASH_ALL_REGIONS)
1283+
return -EOPNOTSUPP;
1284+
1285+
app = nfp_app_from_netdev(netdev);
1286+
if (!app)
1287+
return -EOPNOTSUPP;
1288+
1289+
dev = &app->pdev->dev;
1290+
1291+
nsp = nfp_nsp_open(app->cpp);
1292+
if (IS_ERR(nsp)) {
1293+
err = PTR_ERR(nsp);
1294+
dev_err(dev, "Failed to access the NSP: %d\n", err);
1295+
return err;
1296+
}
1297+
1298+
err = request_firmware_direct(&fw, flash->data, dev);
1299+
if (err)
1300+
goto exit_close_nsp;
1301+
1302+
dev_info(dev, "Please be patient while writing flash image: %s\n",
1303+
flash->data);
1304+
dev_hold(netdev);
1305+
rtnl_unlock();
1306+
1307+
err = nfp_nsp_write_flash(nsp, fw);
1308+
if (err < 0) {
1309+
dev_err(dev, "Flash write failed: %d\n", err);
1310+
goto exit_rtnl_lock;
1311+
}
1312+
dev_info(dev, "Finished writing flash image\n");
1313+
1314+
exit_rtnl_lock:
1315+
rtnl_lock();
1316+
dev_put(netdev);
1317+
release_firmware(fw);
1318+
1319+
exit_close_nsp:
1320+
nfp_nsp_close(nsp);
1321+
return err;
1322+
}
1323+
12721324
static const struct ethtool_ops nfp_net_ethtool_ops = {
12731325
.get_drvinfo = nfp_net_get_drvinfo,
12741326
.get_link = ethtool_op_get_link,
@@ -1279,6 +1331,7 @@ static const struct ethtool_ops nfp_net_ethtool_ops = {
12791331
.get_sset_count = nfp_net_get_sset_count,
12801332
.get_rxnfc = nfp_net_get_rxnfc,
12811333
.set_rxnfc = nfp_net_set_rxnfc,
1334+
.flash_device = nfp_net_flash_device,
12821335
.get_rxfh_indir_size = nfp_net_get_rxfh_indir_size,
12831336
.get_rxfh_key_size = nfp_net_get_rxfh_key_size,
12841337
.get_rxfh = nfp_net_get_rxfh,
@@ -1304,6 +1357,7 @@ const struct ethtool_ops nfp_port_ethtool_ops = {
13041357
.get_strings = nfp_port_get_strings,
13051358
.get_ethtool_stats = nfp_port_get_stats,
13061359
.get_sset_count = nfp_port_get_sset_count,
1360+
.flash_device = nfp_net_flash_device,
13071361
.set_dump = nfp_app_set_dump,
13081362
.get_dump_flag = nfp_app_get_dump_flag,
13091363
.get_dump_data = nfp_app_get_dump_data,

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
#include "nfp_cpp.h"
5252
#include "nfp_nsp.h"
5353

54+
#define NFP_NSP_TIMEOUT_DEFAULT 30
55+
#define NFP_NSP_TIMEOUT_BOOT 30
56+
5457
/* Offsets relative to the CSR base */
5558
#define NSP_STATUS 0x00
5659
#define NSP_STATUS_MAGIC GENMASK_ULL(63, 48)
@@ -93,6 +96,7 @@ enum nfp_nsp_cmd {
9396
SPCODE_FW_LOAD = 6, /* Load fw from buffer, len in option */
9497
SPCODE_ETH_RESCAN = 7, /* Rescan ETHs, write ETH_TABLE to buf */
9598
SPCODE_ETH_CONTROL = 8, /* Update media config from buffer */
99+
SPCODE_NSP_WRITE_FLASH = 11, /* Load and flash image from buffer */
96100
SPCODE_NSP_SENSORS = 12, /* Read NSP sensor(s) */
97101
SPCODE_NSP_IDENTIFY = 13, /* Read NSP version */
98102
};
@@ -260,10 +264,10 @@ u16 nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state)
260264
}
261265

262266
static int
263-
nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg,
264-
u32 nsp_cpp, u64 addr, u64 mask, u64 val)
267+
nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg, u32 nsp_cpp, u64 addr,
268+
u64 mask, u64 val, u32 timeout_sec)
265269
{
266-
const unsigned long wait_until = jiffies + 30 * HZ;
270+
const unsigned long wait_until = jiffies + timeout_sec * HZ;
267271
int err;
268272

269273
for (;;) {
@@ -285,12 +289,13 @@ nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg,
285289
}
286290

287291
/**
288-
* nfp_nsp_command() - Execute a command on the NFP Service Processor
292+
* __nfp_nsp_command() - Execute a command on the NFP Service Processor
289293
* @state: NFP SP state
290294
* @code: NFP SP Command Code
291295
* @option: NFP SP Command Argument
292296
* @buff_cpp: NFP SP Buffer CPP Address info
293297
* @buff_addr: NFP SP Buffer Host address
298+
* @timeout_sec:Timeout value to wait for completion in seconds
294299
*
295300
* Return: 0 for success with no result
296301
*
@@ -300,10 +305,11 @@ nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg,
300305
* -ENODEV if the NSP is not a supported model
301306
* -EBUSY if the NSP is stuck
302307
* -EINTR if interrupted while waiting for completion
303-
* -ETIMEDOUT if the NSP took longer than 30 seconds to complete
308+
* -ETIMEDOUT if the NSP took longer than @timeout_sec seconds to complete
304309
*/
305-
static int nfp_nsp_command(struct nfp_nsp *state, u16 code, u32 option,
306-
u32 buff_cpp, u64 buff_addr)
310+
static int
311+
__nfp_nsp_command(struct nfp_nsp *state, u16 code, u32 option, u32 buff_cpp,
312+
u64 buff_addr, u32 timeout_sec)
307313
{
308314
u64 reg, ret_val, nsp_base, nsp_buffer, nsp_status, nsp_command;
309315
struct nfp_cpp *cpp = state->cpp;
@@ -341,17 +347,17 @@ static int nfp_nsp_command(struct nfp_nsp *state, u16 code, u32 option,
341347
return err;
342348

343349
/* Wait for NSP_COMMAND_START to go to 0 */
344-
err = nfp_nsp_wait_reg(cpp, &reg,
345-
nsp_cpp, nsp_command, NSP_COMMAND_START, 0);
350+
err = nfp_nsp_wait_reg(cpp, &reg, nsp_cpp, nsp_command,
351+
NSP_COMMAND_START, 0, NFP_NSP_TIMEOUT_DEFAULT);
346352
if (err) {
347353
nfp_err(cpp, "Error %d waiting for code 0x%04x to start\n",
348354
err, code);
349355
return err;
350356
}
351357

352358
/* Wait for NSP_STATUS_BUSY to go to 0 */
353-
err = nfp_nsp_wait_reg(cpp, &reg,
354-
nsp_cpp, nsp_status, NSP_STATUS_BUSY, 0);
359+
err = nfp_nsp_wait_reg(cpp, &reg, nsp_cpp, nsp_status, NSP_STATUS_BUSY,
360+
0, timeout_sec);
355361
if (err) {
356362
nfp_err(cpp, "Error %d waiting for code 0x%04x to complete\n",
357363
err, code);
@@ -374,9 +380,18 @@ static int nfp_nsp_command(struct nfp_nsp *state, u16 code, u32 option,
374380
return ret_val;
375381
}
376382

377-
static int nfp_nsp_command_buf(struct nfp_nsp *nsp, u16 code, u32 option,
378-
const void *in_buf, unsigned int in_size,
379-
void *out_buf, unsigned int out_size)
383+
static int
384+
nfp_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+
391+
static 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)
380395
{
381396
struct nfp_cpp *cpp = nsp->cpp;
382397
unsigned int max_size;
@@ -429,7 +444,8 @@ static int nfp_nsp_command_buf(struct nfp_nsp *nsp, u16 code, u32 option,
429444
return err;
430445
}
431446

432-
ret = nfp_nsp_command(nsp, code, option, cpp_id, cpp_buf);
447+
ret = __nfp_nsp_command(nsp, code, option, cpp_id, cpp_buf,
448+
timeout_sec);
433449
if (ret < 0)
434450
return ret;
435451

@@ -442,12 +458,23 @@ static int nfp_nsp_command_buf(struct nfp_nsp *nsp, u16 code, u32 option,
442458
return ret;
443459
}
444460

461+
static int
462+
nfp_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+
445471
int nfp_nsp_wait(struct nfp_nsp *state)
446472
{
447-
const unsigned long wait_until = jiffies + 30 * HZ;
473+
const unsigned long wait_until = jiffies + NFP_NSP_TIMEOUT_BOOT * HZ;
448474
int err;
449475

450-
nfp_dbg(state->cpp, "Waiting for NSP to respond (30 sec max).\n");
476+
nfp_dbg(state->cpp, "Waiting for NSP to respond (%u sec max).\n",
477+
NFP_NSP_TIMEOUT_BOOT);
451478

452479
for (;;) {
453480
const unsigned long start_time = jiffies;
@@ -488,6 +515,17 @@ int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw)
488515
fw->size, NULL, 0);
489516
}
490517

518+
int 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+
491529
int nfp_nsp_read_eth_table(struct nfp_nsp *state, void *buf, unsigned int size)
492530
{
493531
return nfp_nsp_command_buf(state, SPCODE_ETH_RESCAN, size, NULL, 0,

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ u16 nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state);
4848
int nfp_nsp_wait(struct nfp_nsp *state);
4949
int nfp_nsp_device_soft_reset(struct nfp_nsp *state);
5050
int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw);
51+
int nfp_nsp_write_flash(struct nfp_nsp *state, const struct firmware *fw);
5152
int nfp_nsp_mac_reinit(struct nfp_nsp *state);
5253

5354
static inline bool nfp_nsp_has_mac_reinit(struct nfp_nsp *state)

0 commit comments

Comments
 (0)