mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
net: microchip: sparx5: Add VCAP debugFS support
Add a debugFS root folder for Sparx5 and add a vcap folder underneath with the VCAP instances and the ports Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
277e9179ef
commit
e0305cc1d1
@ -12,6 +12,7 @@ sparx5-switch-y := sparx5_main.o sparx5_packet.o \
|
||||
sparx5_vcap_impl.o sparx5_vcap_ag_api.o sparx5_tc_flower.o sparx5_tc_matchall.o
|
||||
|
||||
sparx5-switch-$(CONFIG_SPARX5_DCB) += sparx5_dcb.o
|
||||
sparx5-switch-$(CONFIG_DEBUG_FS) += sparx5_vcap_debugfs.o
|
||||
|
||||
# Provide include files
|
||||
ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
|
||||
|
@ -763,6 +763,8 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
|
||||
/* Default values, some from DT */
|
||||
sparx5->coreclock = SPX5_CORE_CLOCK_DEFAULT;
|
||||
|
||||
sparx5->debugfs_root = debugfs_create_dir("sparx5", NULL);
|
||||
|
||||
ports = of_get_child_by_name(np, "ethernet-ports");
|
||||
if (!ports) {
|
||||
dev_err(sparx5->dev, "no ethernet-ports child node found\n");
|
||||
@ -906,6 +908,7 @@ static int mchp_sparx5_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct sparx5 *sparx5 = platform_get_drvdata(pdev);
|
||||
|
||||
debugfs_remove_recursive(sparx5->debugfs_root);
|
||||
if (sparx5->xtr_irq) {
|
||||
disable_irq(sparx5->xtr_irq);
|
||||
sparx5->xtr_irq = -ENXIO;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/net_tstamp.h>
|
||||
#include <linux/ptp_clock_kernel.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#include "sparx5_main_regs.h"
|
||||
|
||||
@ -292,6 +293,8 @@ struct sparx5 {
|
||||
struct vcap_control *vcap_ctrl;
|
||||
/* PGID allocation map */
|
||||
u8 pgid_map[PGID_TABLE_SIZE];
|
||||
/* Common root for debugfs */
|
||||
struct dentry *debugfs_root;
|
||||
};
|
||||
|
||||
/* sparx5_switchdev.c */
|
||||
|
23
drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.c
Normal file
23
drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.c
Normal file
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/* Microchip Sparx5 Switch driver VCAP debugFS implementation
|
||||
*
|
||||
* Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include "sparx5_vcap_debugfs.h"
|
||||
#include "sparx5_main_regs.h"
|
||||
#include "sparx5_main.h"
|
||||
#include "sparx5_vcap_impl.h"
|
||||
#include "sparx5_vcap_ag_api.h"
|
||||
|
||||
/* Provide port information via a callback interface */
|
||||
int sparx5_port_info(struct net_device *ndev,
|
||||
struct vcap_admin *admin,
|
||||
struct vcap_output_print *out)
|
||||
{
|
||||
/* this will be added later */
|
||||
return 0;
|
||||
}
|
33
drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.h
Normal file
33
drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/* Microchip Sparx5 Switch driver VCAP implementation
|
||||
*
|
||||
* Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef __SPARX5_VCAP_DEBUGFS_H__
|
||||
#define __SPARX5_VCAP_DEBUGFS_H__
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include <vcap_api.h>
|
||||
#include <vcap_api_client.h>
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
|
||||
/* Provide port information via a callback interface */
|
||||
int sparx5_port_info(struct net_device *ndev,
|
||||
struct vcap_admin *admin,
|
||||
struct vcap_output_print *out);
|
||||
|
||||
#else
|
||||
|
||||
static inline int sparx5_port_info(struct net_device *ndev,
|
||||
struct vcap_admin *admin,
|
||||
struct vcap_output_print *out)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __SPARX5_VCAP_DEBUGFS_H__ */
|
@ -12,10 +12,12 @@
|
||||
|
||||
#include "vcap_api.h"
|
||||
#include "vcap_api_client.h"
|
||||
#include "vcap_api_debugfs.h"
|
||||
#include "sparx5_main_regs.h"
|
||||
#include "sparx5_main.h"
|
||||
#include "sparx5_vcap_impl.h"
|
||||
#include "sparx5_vcap_ag_api.h"
|
||||
#include "sparx5_vcap_debugfs.h"
|
||||
|
||||
#define SUPER_VCAP_BLK_SIZE 3072 /* addresses per Super VCAP block */
|
||||
#define STREAMSIZE (64 * 4) /* bytes in the VCAP cache area */
|
||||
@ -30,54 +32,6 @@
|
||||
ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(_v6_uc) | \
|
||||
ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(_arp))
|
||||
|
||||
/* IS2 port keyset selection control */
|
||||
|
||||
/* IS2 non-ethernet traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_noneth {
|
||||
VCAP_IS2_PS_NONETH_MAC_ETYPE,
|
||||
VCAP_IS2_PS_NONETH_CUSTOM_1,
|
||||
VCAP_IS2_PS_NONETH_CUSTOM_2,
|
||||
VCAP_IS2_PS_NONETH_NO_LOOKUP
|
||||
};
|
||||
|
||||
/* IS2 IPv4 unicast traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_ipv4_uc {
|
||||
VCAP_IS2_PS_IPV4_UC_MAC_ETYPE,
|
||||
VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
|
||||
VCAP_IS2_PS_IPV4_UC_IP_7TUPLE,
|
||||
};
|
||||
|
||||
/* IS2 IPv4 multicast traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_ipv4_mc {
|
||||
VCAP_IS2_PS_IPV4_MC_MAC_ETYPE,
|
||||
VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER,
|
||||
VCAP_IS2_PS_IPV4_MC_IP_7TUPLE,
|
||||
VCAP_IS2_PS_IPV4_MC_IP4_VID,
|
||||
};
|
||||
|
||||
/* IS2 IPv6 unicast traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_ipv6_uc {
|
||||
VCAP_IS2_PS_IPV6_UC_MAC_ETYPE,
|
||||
VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
|
||||
VCAP_IS2_PS_IPV6_UC_IP6_STD,
|
||||
VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER,
|
||||
};
|
||||
|
||||
/* IS2 IPv6 multicast traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_ipv6_mc {
|
||||
VCAP_IS2_PS_IPV6_MC_MAC_ETYPE,
|
||||
VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
|
||||
VCAP_IS2_PS_IPV6_MC_IP6_VID,
|
||||
VCAP_IS2_PS_IPV6_MC_IP6_STD,
|
||||
VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER,
|
||||
};
|
||||
|
||||
/* IS2 ARP traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_arp {
|
||||
VCAP_IS2_PS_ARP_MAC_ETYPE,
|
||||
VCAP_IS2_PS_ARP_ARP,
|
||||
};
|
||||
|
||||
static struct sparx5_vcap_inst {
|
||||
enum vcap_type vtype; /* type of vcap */
|
||||
int vinst; /* instance number within the same type */
|
||||
@ -548,15 +502,6 @@ static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin,
|
||||
sparx5_vcap_wait_super_update(sparx5);
|
||||
}
|
||||
|
||||
/* Provide port information via a callback interface */
|
||||
static int sparx5_port_info(struct net_device *ndev, enum vcap_type vtype,
|
||||
int (*pf)(void *out, int arg, const char *fmt, ...),
|
||||
void *out, int arg)
|
||||
{
|
||||
/* this will be added later */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Enable all lookups in the VCAP instance */
|
||||
static int sparx5_vcap_enable(struct net_device *ndev,
|
||||
struct vcap_admin *admin,
|
||||
@ -702,6 +647,7 @@ int sparx5_vcap_init(struct sparx5 *sparx5)
|
||||
const struct sparx5_vcap_inst *cfg;
|
||||
struct vcap_control *ctrl;
|
||||
struct vcap_admin *admin;
|
||||
struct dentry *dir;
|
||||
int err = 0, idx;
|
||||
|
||||
/* Create a VCAP control instance that owns the platform specific VCAP
|
||||
@ -740,6 +686,11 @@ int sparx5_vcap_init(struct sparx5 *sparx5)
|
||||
sparx5_vcap_port_key_selection(sparx5, admin);
|
||||
list_add_tail(&admin->list, &ctrl->list);
|
||||
}
|
||||
dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl);
|
||||
for (idx = 0; idx < SPX5_PORTS; ++idx)
|
||||
if (sparx5->ports[idx])
|
||||
vcap_port_debugfs(sparx5->dev, dir, ctrl,
|
||||
sparx5->ports[idx]->ndev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -17,4 +17,52 @@
|
||||
#define SPARX5_VCAP_CID_IS2_MAX \
|
||||
(VCAP_CID_INGRESS_STAGE2_L3 + VCAP_CID_LOOKUP_SIZE - 1) /* IS2 Max */
|
||||
|
||||
/* IS2 port keyset selection control */
|
||||
|
||||
/* IS2 non-ethernet traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_noneth {
|
||||
VCAP_IS2_PS_NONETH_MAC_ETYPE,
|
||||
VCAP_IS2_PS_NONETH_CUSTOM_1,
|
||||
VCAP_IS2_PS_NONETH_CUSTOM_2,
|
||||
VCAP_IS2_PS_NONETH_NO_LOOKUP
|
||||
};
|
||||
|
||||
/* IS2 IPv4 unicast traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_ipv4_uc {
|
||||
VCAP_IS2_PS_IPV4_UC_MAC_ETYPE,
|
||||
VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
|
||||
VCAP_IS2_PS_IPV4_UC_IP_7TUPLE,
|
||||
};
|
||||
|
||||
/* IS2 IPv4 multicast traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_ipv4_mc {
|
||||
VCAP_IS2_PS_IPV4_MC_MAC_ETYPE,
|
||||
VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER,
|
||||
VCAP_IS2_PS_IPV4_MC_IP_7TUPLE,
|
||||
VCAP_IS2_PS_IPV4_MC_IP4_VID,
|
||||
};
|
||||
|
||||
/* IS2 IPv6 unicast traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_ipv6_uc {
|
||||
VCAP_IS2_PS_IPV6_UC_MAC_ETYPE,
|
||||
VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
|
||||
VCAP_IS2_PS_IPV6_UC_IP6_STD,
|
||||
VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER,
|
||||
};
|
||||
|
||||
/* IS2 IPv6 multicast traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_ipv6_mc {
|
||||
VCAP_IS2_PS_IPV6_MC_MAC_ETYPE,
|
||||
VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
|
||||
VCAP_IS2_PS_IPV6_MC_IP6_VID,
|
||||
VCAP_IS2_PS_IPV6_MC_IP6_STD,
|
||||
VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER,
|
||||
};
|
||||
|
||||
/* IS2 ARP traffic type keyset generation */
|
||||
enum vcap_is2_port_sel_arp {
|
||||
VCAP_IS2_PS_ARP_MAC_ETYPE,
|
||||
VCAP_IS2_PS_ARP_ARP,
|
||||
};
|
||||
|
||||
#endif /* __SPARX5_VCAP_IMPL_H__ */
|
||||
|
@ -5,5 +5,6 @@
|
||||
|
||||
obj-$(CONFIG_VCAP) += vcap.o
|
||||
obj-$(CONFIG_VCAP_KUNIT_TEST) += vcap_model_kunit.o
|
||||
vcap-$(CONFIG_DEBUG_FS) += vcap_api_debugfs.o
|
||||
|
||||
vcap-y += vcap_api.o
|
||||
|
@ -203,6 +203,13 @@ struct vcap_keyset_list {
|
||||
enum vcap_keyfield_set *keysets; /* the list of keysets */
|
||||
};
|
||||
|
||||
/* Client output printf-like function with destination */
|
||||
struct vcap_output_print {
|
||||
__printf(2, 3)
|
||||
void (*prf)(void *out, const char *fmt, ...);
|
||||
void *dst;
|
||||
};
|
||||
|
||||
/* Client supplied VCAP callback operations */
|
||||
struct vcap_operations {
|
||||
/* validate port keyset operation */
|
||||
@ -252,10 +259,8 @@ struct vcap_operations {
|
||||
/* informational */
|
||||
int (*port_info)
|
||||
(struct net_device *ndev,
|
||||
enum vcap_type vtype,
|
||||
int (*pf)(void *out, int arg, const char *fmt, ...),
|
||||
void *out,
|
||||
int arg);
|
||||
struct vcap_admin *admin,
|
||||
struct vcap_output_print *out);
|
||||
/* enable/disable the lookups in a vcap instance */
|
||||
int (*enable)
|
||||
(struct net_device *ndev,
|
||||
|
93
drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
Normal file
93
drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
Normal file
@ -0,0 +1,93 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/* Microchip VCAP API debug file system support
|
||||
*
|
||||
* Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include "vcap_api_debugfs.h"
|
||||
|
||||
struct vcap_admin_debugfs_info {
|
||||
struct vcap_control *vctrl;
|
||||
struct vcap_admin *admin;
|
||||
};
|
||||
|
||||
struct vcap_port_debugfs_info {
|
||||
struct vcap_control *vctrl;
|
||||
struct net_device *ndev;
|
||||
};
|
||||
|
||||
/* Show the port configuration and status */
|
||||
static int vcap_port_debugfs_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct vcap_port_debugfs_info *info = m->private;
|
||||
struct vcap_admin *admin;
|
||||
struct vcap_output_print out = {
|
||||
.prf = (void *)seq_printf,
|
||||
.dst = m,
|
||||
};
|
||||
|
||||
list_for_each_entry(admin, &info->vctrl->list, list) {
|
||||
if (admin->vinst)
|
||||
continue;
|
||||
info->vctrl->ops->port_info(info->ndev, admin, &out);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(vcap_port_debugfs);
|
||||
|
||||
void vcap_port_debugfs(struct device *dev, struct dentry *parent,
|
||||
struct vcap_control *vctrl,
|
||||
struct net_device *ndev)
|
||||
{
|
||||
struct vcap_port_debugfs_info *info;
|
||||
|
||||
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
info->vctrl = vctrl;
|
||||
info->ndev = ndev;
|
||||
debugfs_create_file(netdev_name(ndev), 0444, parent, info,
|
||||
&vcap_port_debugfs_fops);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vcap_port_debugfs);
|
||||
|
||||
/* Show the raw VCAP instance data (rules with address info) */
|
||||
static int vcap_raw_debugfs_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
/* The output will be added later */
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(vcap_raw_debugfs);
|
||||
|
||||
struct dentry *vcap_debugfs(struct device *dev, struct dentry *parent,
|
||||
struct vcap_control *vctrl)
|
||||
{
|
||||
struct vcap_admin_debugfs_info *info;
|
||||
struct vcap_admin *admin;
|
||||
struct dentry *dir;
|
||||
char name[50];
|
||||
|
||||
dir = debugfs_create_dir("vcaps", parent);
|
||||
if (PTR_ERR_OR_ZERO(dir))
|
||||
return NULL;
|
||||
list_for_each_entry(admin, &vctrl->list, list) {
|
||||
sprintf(name, "raw_%s_%d", vctrl->vcaps[admin->vtype].name,
|
||||
admin->vinst);
|
||||
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return NULL;
|
||||
info->vctrl = vctrl;
|
||||
info->admin = admin;
|
||||
debugfs_create_file(name, 0444, dir, info,
|
||||
&vcap_raw_debugfs_fops);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vcap_debugfs);
|
41
drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.h
Normal file
41
drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries.
|
||||
* Microchip VCAP API
|
||||
*/
|
||||
|
||||
#ifndef __VCAP_API_DEBUGFS__
|
||||
#define __VCAP_API_DEBUGFS__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include "vcap_api.h"
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
|
||||
void vcap_port_debugfs(struct device *dev, struct dentry *parent,
|
||||
struct vcap_control *vctrl,
|
||||
struct net_device *ndev);
|
||||
|
||||
/* Create a debugFS entry for a vcap instance */
|
||||
struct dentry *vcap_debugfs(struct device *dev, struct dentry *parent,
|
||||
struct vcap_control *vctrl);
|
||||
|
||||
#else
|
||||
|
||||
static inline void vcap_port_debugfs(struct device *dev, struct dentry *parent,
|
||||
struct vcap_control *vctrl,
|
||||
struct net_device *ndev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct dentry *vcap_debugfs(struct device *dev,
|
||||
struct dentry *parent,
|
||||
struct vcap_control *vctrl)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* __VCAP_API_DEBUGFS__ */
|
@ -204,9 +204,9 @@ static void test_cache_move(struct net_device *ndev, struct vcap_admin *admin,
|
||||
}
|
||||
|
||||
/* Provide port information via a callback interface */
|
||||
static int vcap_test_port_info(struct net_device *ndev, enum vcap_type vtype,
|
||||
int (*pf)(void *out, int arg, const char *fmt, ...),
|
||||
void *out, int arg)
|
||||
static int vcap_test_port_info(struct net_device *ndev,
|
||||
struct vcap_admin *admin,
|
||||
struct vcap_output_print *out)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user