mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
net: fman_memac: report structured ethtool counters
The FMan driver has support for 2 MACs: mEMAC (newer, present on Layerscape and PowerPC T series) and dTSEC/TGEC (older, present on PowerPC P series). I only have handy access to the mEMAC, and this adds support for MAC counters for those platforms. MAC counters are necessary for any kind of low-level debugging, and currently there is no mechanism to dump them. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://patch.msgid.link/20251122115931.151719-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
7241d80e77
commit
37a96c2009
@@ -467,6 +467,47 @@ revert_values:
|
||||
return res;
|
||||
}
|
||||
|
||||
static void dpaa_get_pause_stats(struct net_device *net_dev,
|
||||
struct ethtool_pause_stats *s)
|
||||
{
|
||||
struct dpaa_priv *priv = netdev_priv(net_dev);
|
||||
struct mac_device *mac_dev = priv->mac_dev;
|
||||
|
||||
if (mac_dev->get_pause_stats)
|
||||
mac_dev->get_pause_stats(mac_dev->fman_mac, s);
|
||||
}
|
||||
|
||||
static void dpaa_get_rmon_stats(struct net_device *net_dev,
|
||||
struct ethtool_rmon_stats *s,
|
||||
const struct ethtool_rmon_hist_range **ranges)
|
||||
{
|
||||
struct dpaa_priv *priv = netdev_priv(net_dev);
|
||||
struct mac_device *mac_dev = priv->mac_dev;
|
||||
|
||||
if (mac_dev->get_rmon_stats)
|
||||
mac_dev->get_rmon_stats(mac_dev->fman_mac, s, ranges);
|
||||
}
|
||||
|
||||
static void dpaa_get_eth_ctrl_stats(struct net_device *net_dev,
|
||||
struct ethtool_eth_ctrl_stats *s)
|
||||
{
|
||||
struct dpaa_priv *priv = netdev_priv(net_dev);
|
||||
struct mac_device *mac_dev = priv->mac_dev;
|
||||
|
||||
if (mac_dev->get_eth_ctrl_stats)
|
||||
mac_dev->get_eth_ctrl_stats(mac_dev->fman_mac, s);
|
||||
}
|
||||
|
||||
static void dpaa_get_eth_mac_stats(struct net_device *net_dev,
|
||||
struct ethtool_eth_mac_stats *s)
|
||||
{
|
||||
struct dpaa_priv *priv = netdev_priv(net_dev);
|
||||
struct mac_device *mac_dev = priv->mac_dev;
|
||||
|
||||
if (mac_dev->get_eth_mac_stats)
|
||||
mac_dev->get_eth_mac_stats(mac_dev->fman_mac, s);
|
||||
}
|
||||
|
||||
const struct ethtool_ops dpaa_ethtool_ops = {
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
|
||||
ETHTOOL_COALESCE_RX_MAX_FRAMES,
|
||||
@@ -487,4 +528,8 @@ const struct ethtool_ops dpaa_ethtool_ops = {
|
||||
.get_ts_info = dpaa_get_ts_info,
|
||||
.get_coalesce = dpaa_get_coalesce,
|
||||
.set_coalesce = dpaa_set_coalesce,
|
||||
.get_pause_stats = dpaa_get_pause_stats,
|
||||
.get_rmon_stats = dpaa_get_rmon_stats,
|
||||
.get_eth_ctrl_stats = dpaa_get_eth_ctrl_stats,
|
||||
.get_eth_mac_stats = dpaa_get_eth_mac_stats,
|
||||
};
|
||||
|
||||
@@ -900,6 +900,89 @@ static int memac_set_exception(struct fman_mac *memac,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 memac_read64(void __iomem *reg)
|
||||
{
|
||||
u32 low, high, tmp;
|
||||
|
||||
do {
|
||||
high = ioread32be(reg + 4);
|
||||
low = ioread32be(reg);
|
||||
tmp = ioread32be(reg + 4);
|
||||
} while (high != tmp);
|
||||
|
||||
return ((u64)high << 32) | low;
|
||||
}
|
||||
|
||||
static void memac_get_pause_stats(struct fman_mac *memac,
|
||||
struct ethtool_pause_stats *s)
|
||||
{
|
||||
s->tx_pause_frames = memac_read64(&memac->regs->txpf_l);
|
||||
s->rx_pause_frames = memac_read64(&memac->regs->rxpf_l);
|
||||
}
|
||||
|
||||
static const struct ethtool_rmon_hist_range memac_rmon_ranges[] = {
|
||||
{ 64, 64 },
|
||||
{ 65, 127 },
|
||||
{ 128, 255 },
|
||||
{ 256, 511 },
|
||||
{ 512, 1023 },
|
||||
{ 1024, 1518 },
|
||||
{ 1519, 9600 },
|
||||
{},
|
||||
};
|
||||
|
||||
static void memac_get_rmon_stats(struct fman_mac *memac,
|
||||
struct ethtool_rmon_stats *s,
|
||||
const struct ethtool_rmon_hist_range **ranges)
|
||||
{
|
||||
s->undersize_pkts = memac_read64(&memac->regs->rund_l);
|
||||
s->oversize_pkts = memac_read64(&memac->regs->rovr_l);
|
||||
s->fragments = memac_read64(&memac->regs->rfrg_l);
|
||||
s->jabbers = memac_read64(&memac->regs->rjbr_l);
|
||||
|
||||
s->hist[0] = memac_read64(&memac->regs->r64_l);
|
||||
s->hist[1] = memac_read64(&memac->regs->r127_l);
|
||||
s->hist[2] = memac_read64(&memac->regs->r255_l);
|
||||
s->hist[3] = memac_read64(&memac->regs->r511_l);
|
||||
s->hist[4] = memac_read64(&memac->regs->r1023_l);
|
||||
s->hist[5] = memac_read64(&memac->regs->r1518_l);
|
||||
s->hist[6] = memac_read64(&memac->regs->r1519x_l);
|
||||
|
||||
s->hist_tx[0] = memac_read64(&memac->regs->t64_l);
|
||||
s->hist_tx[1] = memac_read64(&memac->regs->t127_l);
|
||||
s->hist_tx[2] = memac_read64(&memac->regs->t255_l);
|
||||
s->hist_tx[3] = memac_read64(&memac->regs->t511_l);
|
||||
s->hist_tx[4] = memac_read64(&memac->regs->t1023_l);
|
||||
s->hist_tx[5] = memac_read64(&memac->regs->t1518_l);
|
||||
s->hist_tx[6] = memac_read64(&memac->regs->t1519x_l);
|
||||
|
||||
*ranges = memac_rmon_ranges;
|
||||
}
|
||||
|
||||
static void memac_get_eth_ctrl_stats(struct fman_mac *memac,
|
||||
struct ethtool_eth_ctrl_stats *s)
|
||||
{
|
||||
s->MACControlFramesTransmitted = memac_read64(&memac->regs->tcnp_l);
|
||||
s->MACControlFramesReceived = memac_read64(&memac->regs->rcnp_l);
|
||||
}
|
||||
|
||||
static void memac_get_eth_mac_stats(struct fman_mac *memac,
|
||||
struct ethtool_eth_mac_stats *s)
|
||||
{
|
||||
s->FramesTransmittedOK = memac_read64(&memac->regs->tfrm_l);
|
||||
s->FramesReceivedOK = memac_read64(&memac->regs->rfrm_l);
|
||||
s->FrameCheckSequenceErrors = memac_read64(&memac->regs->rfcs_l);
|
||||
s->AlignmentErrors = memac_read64(&memac->regs->raln_l);
|
||||
s->OctetsTransmittedOK = memac_read64(&memac->regs->teoct_l);
|
||||
s->FramesLostDueToIntMACXmitError = memac_read64(&memac->regs->terr_l);
|
||||
s->OctetsReceivedOK = memac_read64(&memac->regs->reoct_l);
|
||||
s->FramesLostDueToIntMACRcvError = memac_read64(&memac->regs->rdrntp_l);
|
||||
s->MulticastFramesXmittedOK = memac_read64(&memac->regs->tmca_l);
|
||||
s->BroadcastFramesXmittedOK = memac_read64(&memac->regs->tbca_l);
|
||||
s->MulticastFramesReceivedOK = memac_read64(&memac->regs->rmca_l);
|
||||
s->BroadcastFramesReceivedOK = memac_read64(&memac->regs->rbca_l);
|
||||
}
|
||||
|
||||
static int memac_init(struct fman_mac *memac)
|
||||
{
|
||||
struct memac_cfg *memac_drv_param;
|
||||
@@ -1092,6 +1175,10 @@ int memac_initialization(struct mac_device *mac_dev,
|
||||
mac_dev->set_tstamp = memac_set_tstamp;
|
||||
mac_dev->enable = memac_enable;
|
||||
mac_dev->disable = memac_disable;
|
||||
mac_dev->get_pause_stats = memac_get_pause_stats;
|
||||
mac_dev->get_rmon_stats = memac_get_rmon_stats;
|
||||
mac_dev->get_eth_ctrl_stats = memac_get_eth_ctrl_stats;
|
||||
mac_dev->get_eth_mac_stats = memac_get_eth_mac_stats;
|
||||
|
||||
mac_dev->fman_mac = memac_config(mac_dev, params);
|
||||
if (!mac_dev->fman_mac)
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
#include "fman.h"
|
||||
#include "fman_mac.h"
|
||||
|
||||
struct ethtool_eth_ctrl_stats;
|
||||
struct ethtool_eth_mac_stats;
|
||||
struct ethtool_pause_stats;
|
||||
struct ethtool_rmon_stats;
|
||||
struct ethtool_rmon_hist_range;
|
||||
struct fman_mac;
|
||||
struct mac_priv_s;
|
||||
|
||||
@@ -46,6 +51,15 @@ struct mac_device {
|
||||
enet_addr_t *eth_addr);
|
||||
int (*remove_hash_mac_addr)(struct fman_mac *mac_dev,
|
||||
enet_addr_t *eth_addr);
|
||||
void (*get_pause_stats)(struct fman_mac *memac,
|
||||
struct ethtool_pause_stats *s);
|
||||
void (*get_rmon_stats)(struct fman_mac *memac,
|
||||
struct ethtool_rmon_stats *s,
|
||||
const struct ethtool_rmon_hist_range **ranges);
|
||||
void (*get_eth_ctrl_stats)(struct fman_mac *memac,
|
||||
struct ethtool_eth_ctrl_stats *s);
|
||||
void (*get_eth_mac_stats)(struct fman_mac *memac,
|
||||
struct ethtool_eth_mac_stats *s);
|
||||
|
||||
void (*update_speed)(struct mac_device *mac_dev, int speed);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user