net: dsa: dump CPU port regs through master
Merge the CPU port registers dump into the master interface registers dump through ethtool, by nesting the ethtool_drvinfo and ethtool_regs structures of the CPU port into the dump. drvinfo->regdump_len will contain the full data length, while regs->len will contain only the master interface registers dump length. This allows for example to dump the CPU port registers on a ZII Dev C board like this: # ethtool -d eth1 0x004: 0x00000000 0x008: 0x0a8000aa 0x010: 0x01000000 0x014: 0x00000000 0x024: 0xf0000102 0x040: 0x6d82c800 0x044: 0x00000020 0x064: 0x40000000 0x084: RCR (Receive Control Register) 0x47c00104 MAX_FL (Maximum frame length) 1984 FCE (Flow control enable) 0 BC_REJ (Broadcast frame reject) 0 PROM (Promiscuous mode) 0 DRT (Disable receive on transmit) 0 LOOP (Internal loopback) 0 0x0c4: TCR (Transmit Control Register) 0x00000004 RFC_PAUSE (Receive frame control pause) 0 TFC_PAUSE (Transmit frame control pause) 0 FDEN (Full duplex enable) 1 HBC (Heartbeat control) 0 GTS (Graceful transmit stop) 0 0x0e4: 0x76735d6d 0x0e8: 0x7e9e8808 0x0ec: 0x00010000 . . . 88E6352 Switch Port Registers ------------------------------ 00: Port Status 0x4d04 Pause Enabled 0 My Pause 1 802.3 PHY Detected 0 Link Status Up Duplex Full Speed 100 or 200 Mbps EEE Enabled 0 Transmitter Paused 0 Flow Control 0 Config Mode 0x4 01: Physical Control 0x003d RGMII Receive Timing Control Default RGMII Transmit Timing Control Default 200 BASE Mode 100 Flow Control's Forced value 0 Force Flow Control 0 Link's Forced value Up Force Link 1 Duplex's Forced value Full Force Duplex 1 Force Speed 100 or 200 Mbps . . . Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
c4ed52538c
Коммит
48e2331197
|
@ -8,6 +8,70 @@
|
|||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
static int dsa_master_get_regs_len(struct net_device *dev)
|
||||
{
|
||||
struct dsa_port *cpu_dp = dev->dsa_ptr;
|
||||
const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
|
||||
struct dsa_switch *ds = cpu_dp->ds;
|
||||
int port = cpu_dp->index;
|
||||
int ret = 0;
|
||||
int len;
|
||||
|
||||
if (ops->get_regs_len) {
|
||||
len = ops->get_regs_len(dev);
|
||||
if (len < 0)
|
||||
return len;
|
||||
ret += len;
|
||||
}
|
||||
|
||||
ret += sizeof(struct ethtool_drvinfo);
|
||||
ret += sizeof(struct ethtool_regs);
|
||||
|
||||
if (ds->ops->get_regs_len) {
|
||||
len = ds->ops->get_regs_len(ds, port);
|
||||
if (len < 0)
|
||||
return len;
|
||||
ret += len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dsa_master_get_regs(struct net_device *dev,
|
||||
struct ethtool_regs *regs, void *data)
|
||||
{
|
||||
struct dsa_port *cpu_dp = dev->dsa_ptr;
|
||||
const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
|
||||
struct dsa_switch *ds = cpu_dp->ds;
|
||||
struct ethtool_drvinfo *cpu_info;
|
||||
struct ethtool_regs *cpu_regs;
|
||||
int port = cpu_dp->index;
|
||||
int len;
|
||||
|
||||
if (ops->get_regs_len && ops->get_regs) {
|
||||
len = ops->get_regs_len(dev);
|
||||
if (len < 0)
|
||||
return;
|
||||
regs->len = len;
|
||||
ops->get_regs(dev, regs, data);
|
||||
data += regs->len;
|
||||
}
|
||||
|
||||
cpu_info = (struct ethtool_drvinfo *)data;
|
||||
strlcpy(cpu_info->driver, "dsa", sizeof(cpu_info->driver));
|
||||
data += sizeof(*cpu_info);
|
||||
cpu_regs = (struct ethtool_regs *)data;
|
||||
data += sizeof(*cpu_regs);
|
||||
|
||||
if (ds->ops->get_regs_len && ds->ops->get_regs) {
|
||||
len = ds->ops->get_regs_len(ds, port);
|
||||
if (len < 0)
|
||||
return;
|
||||
cpu_regs->len = len;
|
||||
ds->ops->get_regs(ds, port, cpu_regs, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void dsa_master_get_ethtool_stats(struct net_device *dev,
|
||||
struct ethtool_stats *stats,
|
||||
uint64_t *data)
|
||||
|
@ -147,6 +211,8 @@ static int dsa_master_ethtool_setup(struct net_device *dev)
|
|||
if (cpu_dp->orig_ethtool_ops)
|
||||
memcpy(ops, cpu_dp->orig_ethtool_ops, sizeof(*ops));
|
||||
|
||||
ops->get_regs_len = dsa_master_get_regs_len;
|
||||
ops->get_regs = dsa_master_get_regs;
|
||||
ops->get_sset_count = dsa_master_get_sset_count;
|
||||
ops->get_ethtool_stats = dsa_master_get_ethtool_stats;
|
||||
ops->get_strings = dsa_master_get_strings;
|
||||
|
|
Загрузка…
Ссылка в новой задаче