mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-20 03:36:36 +07:00
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: Carl Heymann <carl.heymann@netronome.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
efbf789739
commit
d79e19f564
@ -22,6 +22,7 @@ nfp-objs := \
|
|||||||
nfp_hwmon.o \
|
nfp_hwmon.o \
|
||||||
nfp_main.o \
|
nfp_main.o \
|
||||||
nfp_net_common.o \
|
nfp_net_common.o \
|
||||||
|
nfp_net_debugdump.o \
|
||||||
nfp_net_ethtool.o \
|
nfp_net_ethtool.o \
|
||||||
nfp_net_main.o \
|
nfp_net_main.o \
|
||||||
nfp_net_repr.o \
|
nfp_net_repr.o \
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include <linux/vermagic.h>
|
#include <linux/vermagic.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
#include <net/devlink.h>
|
#include <net/devlink.h>
|
||||||
|
|
||||||
#include "nfpcore/nfp.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->mip = nfp_mip_open(pf->cpp);
|
||||||
pf->rtbl = __nfp_rtsym_table_read(pf->cpp, pf->mip);
|
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);
|
err = nfp_pcie_sriov_read_nfd_limit(pf);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_fw_unload;
|
goto err_fw_unload;
|
||||||
@ -544,6 +548,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
|
|||||||
nfp_fw_unload(pf);
|
nfp_fw_unload(pf);
|
||||||
kfree(pf->eth_tbl);
|
kfree(pf->eth_tbl);
|
||||||
kfree(pf->nspi);
|
kfree(pf->nspi);
|
||||||
|
vfree(pf->dumpspec);
|
||||||
err_devlink_unreg:
|
err_devlink_unreg:
|
||||||
devlink_unregister(devlink);
|
devlink_unregister(devlink);
|
||||||
err_hwinfo_free:
|
err_hwinfo_free:
|
||||||
@ -579,6 +584,7 @@ static void nfp_pci_remove(struct pci_dev *pdev)
|
|||||||
|
|
||||||
devlink_unregister(devlink);
|
devlink_unregister(devlink);
|
||||||
|
|
||||||
|
vfree(pf->dumpspec);
|
||||||
kfree(pf->rtbl);
|
kfree(pf->rtbl);
|
||||||
nfp_mip_close(pf->mip);
|
nfp_mip_close(pf->mip);
|
||||||
if (pf->fw_loaded)
|
if (pf->fw_loaded)
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#ifndef NFP_MAIN_H
|
#ifndef NFP_MAIN_H
|
||||||
#define NFP_MAIN_H
|
#define NFP_MAIN_H
|
||||||
|
|
||||||
|
#include <linux/ethtool.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/msi.h>
|
#include <linux/msi.h>
|
||||||
@ -61,6 +62,17 @@ struct nfp_nsp_identify;
|
|||||||
struct nfp_port;
|
struct nfp_port;
|
||||||
struct nfp_rtsym_table;
|
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
|
* struct nfp_pf - NFP PF-specific device structure
|
||||||
* @pdev: Backpointer to PCI device
|
* @pdev: Backpointer to PCI device
|
||||||
@ -83,6 +95,9 @@ struct nfp_rtsym_table;
|
|||||||
* @mip: MIP handle
|
* @mip: MIP handle
|
||||||
* @rtbl: RTsym table
|
* @rtbl: RTsym table
|
||||||
* @hwinfo: HWInfo 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
|
* @eth_tbl: NSP ETH table
|
||||||
* @nspi: NSP identification info
|
* @nspi: NSP identification info
|
||||||
* @hwmon_dev: pointer to hwmon device
|
* @hwmon_dev: pointer to hwmon device
|
||||||
@ -124,6 +139,9 @@ struct nfp_pf {
|
|||||||
const struct nfp_mip *mip;
|
const struct nfp_mip *mip;
|
||||||
struct nfp_rtsym_table *rtbl;
|
struct nfp_rtsym_table *rtbl;
|
||||||
struct nfp_hwinfo *hwinfo;
|
struct nfp_hwinfo *hwinfo;
|
||||||
|
struct nfp_dumpspec *dumpspec;
|
||||||
|
u32 dump_flag;
|
||||||
|
u32 dump_len;
|
||||||
struct nfp_eth_table *eth_tbl;
|
struct nfp_eth_table *eth_tbl;
|
||||||
struct nfp_nsp_identify *nspi;
|
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);
|
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 */
|
#endif /* NFP_MAIN_H */
|
||||||
|
54
drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
Normal file
54
drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
@ -51,14 +51,11 @@
|
|||||||
#include "nfpcore/nfp.h"
|
#include "nfpcore/nfp.h"
|
||||||
#include "nfpcore/nfp_nsp.h"
|
#include "nfpcore/nfp_nsp.h"
|
||||||
#include "nfp_app.h"
|
#include "nfp_app.h"
|
||||||
|
#include "nfp_main.h"
|
||||||
#include "nfp_net_ctrl.h"
|
#include "nfp_net_ctrl.h"
|
||||||
#include "nfp_net.h"
|
#include "nfp_net.h"
|
||||||
#include "nfp_port.h"
|
#include "nfp_port.h"
|
||||||
|
|
||||||
enum nfp_dump_diag {
|
|
||||||
NFP_DUMP_NSP_DIAG = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nfp_et_stat {
|
struct nfp_et_stat {
|
||||||
char name[ETH_GSTRING_LEN];
|
char name[ETH_GSTRING_LEN];
|
||||||
int off;
|
int off;
|
||||||
@ -1066,15 +1063,34 @@ nfp_dump_nsp_diag(struct nfp_app *app, struct ethtool_dump *dump, void *buffer)
|
|||||||
return ret;
|
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)
|
static int nfp_app_set_dump(struct net_device *netdev, struct ethtool_dump *val)
|
||||||
{
|
{
|
||||||
struct nfp_app *app = nfp_app_from_netdev(netdev);
|
struct nfp_app *app = nfp_app_from_netdev(netdev);
|
||||||
|
s64 len;
|
||||||
|
|
||||||
if (!app)
|
if (!app)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (val->flag != NFP_DUMP_NSP_DIAG)
|
if (val->flag == NFP_DUMP_NSP_DIAG) {
|
||||||
return -EINVAL;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1082,14 +1098,37 @@ static int nfp_app_set_dump(struct net_device *netdev, struct ethtool_dump *val)
|
|||||||
static int
|
static int
|
||||||
nfp_app_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
|
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
|
static int
|
||||||
nfp_app_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
|
nfp_app_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
|
||||||
void *buffer)
|
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,
|
static int nfp_net_set_coalesce(struct net_device *netdev,
|
||||||
|
Loading…
Reference in New Issue
Block a user