Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d79e19f5 authored by Carl Heymann's avatar Carl Heymann Committed by David S. Miller
Browse files

nfp: debug dump ethtool ops



- Skeleton code to perform a binary debug dump via ethtoolops
  "set_dump", "get_dump_flags" and "get_dump_data", i.e. the ethtool
  -W/w mechanism.
- Skeleton functions for debugdump operations provided.
- An integer "dump level" can be specified, this is stored between
  ethtool invocations. Dump level 0 is still the "arm.diag" resource for
  backward compatibility. Other dump levels each define a set of state
  information to include in the dump, driven by a spec from FW.

Signed-off-by: default avatarCarl Heymann <carl.heymann@netronome.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent efbf7897
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ nfp-objs := \
	    nfp_hwmon.o \
	    nfp_main.o \
	    nfp_net_common.o \
	    nfp_net_debugdump.o \
	    nfp_net_ethtool.o \
	    nfp_net_main.o \
	    nfp_net_repr.o \
+6 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/vermagic.h>
#include <linux/vmalloc.h>
#include <net/devlink.h>

#include "nfpcore/nfp.h"
@@ -509,6 +510,9 @@ static int nfp_pci_probe(struct pci_dev *pdev,
	pf->mip = nfp_mip_open(pf->cpp);
	pf->rtbl = __nfp_rtsym_table_read(pf->cpp, pf->mip);

	pf->dump_flag = NFP_DUMP_NSP_DIAG;
	pf->dumpspec = nfp_net_dump_load_dumpspec(pf->cpp, pf->rtbl);

	err = nfp_pcie_sriov_read_nfd_limit(pf);
	if (err)
		goto err_fw_unload;
@@ -544,6 +548,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
		nfp_fw_unload(pf);
	kfree(pf->eth_tbl);
	kfree(pf->nspi);
	vfree(pf->dumpspec);
err_devlink_unreg:
	devlink_unregister(devlink);
err_hwinfo_free:
@@ -579,6 +584,7 @@ static void nfp_pci_remove(struct pci_dev *pdev)

	devlink_unregister(devlink);

	vfree(pf->dumpspec);
	kfree(pf->rtbl);
	nfp_mip_close(pf->mip);
	if (pf->fw_loaded)
+29 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#ifndef NFP_MAIN_H
#define NFP_MAIN_H

#include <linux/ethtool.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/msi.h>
@@ -61,6 +62,17 @@ struct nfp_nsp_identify;
struct nfp_port;
struct nfp_rtsym_table;

/**
 * struct nfp_dumpspec - NFP FW dump specification structure
 * @size:	Size of the data
 * @data:	Sequence of TLVs, each being an instruction to dump some data
 *		from FW
 */
struct nfp_dumpspec {
	u32 size;
	u8 data[0];
};

/**
 * struct nfp_pf - NFP PF-specific device structure
 * @pdev:		Backpointer to PCI device
@@ -83,6 +95,9 @@ struct nfp_rtsym_table;
 * @mip:		MIP handle
 * @rtbl:		RTsym table
 * @hwinfo:		HWInfo table
 * @dumpspec:		Debug dump specification
 * @dump_flag:		Store dump flag between set_dump and get_dump_flag
 * @dump_len:		Store dump length between set_dump and get_dump_flag
 * @eth_tbl:		NSP ETH table
 * @nspi:		NSP identification info
 * @hwmon_dev:		pointer to hwmon device
@@ -124,6 +139,9 @@ struct nfp_pf {
	const struct nfp_mip *mip;
	struct nfp_rtsym_table *rtbl;
	struct nfp_hwinfo *hwinfo;
	struct nfp_dumpspec *dumpspec;
	u32 dump_flag;
	u32 dump_len;
	struct nfp_eth_table *eth_tbl;
	struct nfp_nsp_identify *nspi;

@@ -157,4 +175,15 @@ void nfp_net_get_mac_addr(struct nfp_pf *pf, struct nfp_port *port);

bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);

enum nfp_dump_diag {
	NFP_DUMP_NSP_DIAG = 0,
};

struct nfp_dumpspec *
nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct nfp_rtsym_table *rtbl);
s64 nfp_net_dump_calculate_size(struct nfp_pf *pf, struct nfp_dumpspec *spec,
				u32 flag);
int nfp_net_dump_populate_buffer(struct nfp_pf *pf, struct nfp_dumpspec *spec,
				 struct ethtool_dump *dump_param, void *dest);

#endif /* NFP_MAIN_H */
+54 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 Netronome Systems, Inc.
 *
 * This software is dual licensed under the GNU General License Version 2,
 * June 1991 as shown in the file COPYING in the top-level directory of this
 * source tree or the BSD 2-Clause License provided below.  You have the
 * option to license this software under the complete terms of either license.
 *
 * The BSD 2-Clause License:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      1. Redistributions of source code must retain the above
 *         copyright notice, this list of conditions and the following
 *         disclaimer.
 *
 *      2. Redistributions in binary form must reproduce the above
 *         copyright notice, this list of conditions and the following
 *         disclaimer in the documentation and/or other materials
 *         provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/ethtool.h>

#include "nfp_main.h"

struct nfp_dumpspec *
nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct nfp_rtsym_table *rtbl)
{
	return NULL;
}

s64 nfp_net_dump_calculate_size(struct nfp_pf *pf, struct nfp_dumpspec *spec,
				u32 flag)
{
	return -EOPNOTSUPP;
}

int nfp_net_dump_populate_buffer(struct nfp_pf *pf, struct nfp_dumpspec *spec,
				 struct ethtool_dump *dump_param, void *dest)
{
	return -EOPNOTSUPP;
}
+47 −8
Original line number Diff line number Diff line
@@ -51,14 +51,11 @@
#include "nfpcore/nfp.h"
#include "nfpcore/nfp_nsp.h"
#include "nfp_app.h"
#include "nfp_main.h"
#include "nfp_net_ctrl.h"
#include "nfp_net.h"
#include "nfp_port.h"

enum nfp_dump_diag {
	NFP_DUMP_NSP_DIAG = 0,
};

struct nfp_et_stat {
	char name[ETH_GSTRING_LEN];
	int off;
@@ -1066,15 +1063,34 @@ nfp_dump_nsp_diag(struct nfp_app *app, struct ethtool_dump *dump, void *buffer)
	return ret;
}

/* Set the dump flag/level. Calculate the dump length for flag > 0 only (new TLV
 * based dumps), since flag 0 (default) calculates the length in
 * nfp_app_get_dump_flag(), and we need to support triggering a level 0 dump
 * without setting the flag first, for backward compatibility.
 */
static int nfp_app_set_dump(struct net_device *netdev, struct ethtool_dump *val)
{
	struct nfp_app *app = nfp_app_from_netdev(netdev);
	s64 len;

	if (!app)
		return -EOPNOTSUPP;

	if (val->flag != NFP_DUMP_NSP_DIAG)
		return -EINVAL;
	if (val->flag == NFP_DUMP_NSP_DIAG) {
		app->pf->dump_flag = val->flag;
		return 0;
	}

	if (!app->pf->dumpspec)
		return -EOPNOTSUPP;

	len = nfp_net_dump_calculate_size(app->pf, app->pf->dumpspec,
					  val->flag);
	if (len < 0)
		return len;

	app->pf->dump_flag = val->flag;
	app->pf->dump_len = len;

	return 0;
}
@@ -1082,14 +1098,37 @@ static int nfp_app_set_dump(struct net_device *netdev, struct ethtool_dump *val)
static int
nfp_app_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
{
	return nfp_dump_nsp_diag(nfp_app_from_netdev(netdev), dump, NULL);
	struct nfp_app *app = nfp_app_from_netdev(netdev);

	if (!app)
		return -EOPNOTSUPP;

	if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG)
		return nfp_dump_nsp_diag(app, dump, NULL);

	dump->flag = app->pf->dump_flag;
	dump->len = app->pf->dump_len;

	return 0;
}

static int
nfp_app_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
		      void *buffer)
{
	return nfp_dump_nsp_diag(nfp_app_from_netdev(netdev), dump, buffer);
	struct nfp_app *app = nfp_app_from_netdev(netdev);

	if (!app)
		return -EOPNOTSUPP;

	if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG)
		return nfp_dump_nsp_diag(app, dump, buffer);

	dump->flag = app->pf->dump_flag;
	dump->len = app->pf->dump_len;

	return nfp_net_dump_populate_buffer(app->pf, app->pf->dumpspec, dump,
					    buffer);
}

static int nfp_net_set_coalesce(struct net_device *netdev,