Skip to content

Commit 38ae92d

Browse files
chealydavem330
authored andcommitted
fec: Add support for reading RMON registers
Add ethtool operation to read RMON registers. Tested against net-next on i.MX28. v2: make conditional on #ifndef CONFIG_M5272 Signed-off-by: Chris Healy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 77ecaac commit 38ae92d

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed

drivers/net/ethernet/freescale/fec.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,61 @@
6060
#define BM_MIIGSK_CFGR_RMII 0x01
6161
#define BM_MIIGSK_CFGR_FRCONT_10M 0x40
6262

63+
#define RMON_T_DROP 0x200 /* Count of frames not cntd correctly */
64+
#define RMON_T_PACKETS 0x204 /* RMON TX packet count */
65+
#define RMON_T_BC_PKT 0x208 /* RMON TX broadcast pkts */
66+
#define RMON_T_MC_PKT 0x20C /* RMON TX multicast pkts */
67+
#define RMON_T_CRC_ALIGN 0x210 /* RMON TX pkts with CRC align err */
68+
#define RMON_T_UNDERSIZE 0x214 /* RMON TX pkts < 64 bytes, good CRC */
69+
#define RMON_T_OVERSIZE 0x218 /* RMON TX pkts > MAX_FL bytes good CRC */
70+
#define RMON_T_FRAG 0x21C /* RMON TX pkts < 64 bytes, bad CRC */
71+
#define RMON_T_JAB 0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */
72+
#define RMON_T_COL 0x224 /* RMON TX collision count */
73+
#define RMON_T_P64 0x228 /* RMON TX 64 byte pkts */
74+
#define RMON_T_P65TO127 0x22C /* RMON TX 65 to 127 byte pkts */
75+
#define RMON_T_P128TO255 0x230 /* RMON TX 128 to 255 byte pkts */
76+
#define RMON_T_P256TO511 0x234 /* RMON TX 256 to 511 byte pkts */
77+
#define RMON_T_P512TO1023 0x238 /* RMON TX 512 to 1023 byte pkts */
78+
#define RMON_T_P1024TO2047 0x23C /* RMON TX 1024 to 2047 byte pkts */
79+
#define RMON_T_P_GTE2048 0x240 /* RMON TX pkts > 2048 bytes */
80+
#define RMON_T_OCTETS 0x244 /* RMON TX octets */
81+
#define IEEE_T_DROP 0x248 /* Count of frames not counted crtly */
82+
#define IEEE_T_FRAME_OK 0x24C /* Frames tx'd OK */
83+
#define IEEE_T_1COL 0x250 /* Frames tx'd with single collision */
84+
#define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */
85+
#define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */
86+
#define IEEE_T_LCOL 0x25C /* Frames tx'd with late collision */
87+
#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */
88+
#define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */
89+
#define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */
90+
#define IEEE_T_SQE 0x26C /* Frames tx'd with SQE err */
91+
#define IEEE_T_FDXFC 0x270 /* Flow control pause frames tx'd */
92+
#define IEEE_T_OCTETS_OK 0x274 /* Octet count for frames tx'd w/o err */
93+
#define RMON_R_PACKETS 0x284 /* RMON RX packet count */
94+
#define RMON_R_BC_PKT 0x288 /* RMON RX broadcast pkts */
95+
#define RMON_R_MC_PKT 0x28C /* RMON RX multicast pkts */
96+
#define RMON_R_CRC_ALIGN 0x290 /* RMON RX pkts with CRC alignment err */
97+
#define RMON_R_UNDERSIZE 0x294 /* RMON RX pkts < 64 bytes, good CRC */
98+
#define RMON_R_OVERSIZE 0x298 /* RMON RX pkts > MAX_FL bytes good CRC */
99+
#define RMON_R_FRAG 0x29C /* RMON RX pkts < 64 bytes, bad CRC */
100+
#define RMON_R_JAB 0x2A0 /* RMON RX pkts > MAX_FL bytes, bad CRC */
101+
#define RMON_R_RESVD_O 0x2A4 /* Reserved */
102+
#define RMON_R_P64 0x2A8 /* RMON RX 64 byte pkts */
103+
#define RMON_R_P65TO127 0x2AC /* RMON RX 65 to 127 byte pkts */
104+
#define RMON_R_P128TO255 0x2B0 /* RMON RX 128 to 255 byte pkts */
105+
#define RMON_R_P256TO511 0x2B4 /* RMON RX 256 to 511 byte pkts */
106+
#define RMON_R_P512TO1023 0x2B8 /* RMON RX 512 to 1023 byte pkts */
107+
#define RMON_R_P1024TO2047 0x2BC /* RMON RX 1024 to 2047 byte pkts */
108+
#define RMON_R_P_GTE2048 0x2C0 /* RMON RX pkts > 2048 bytes */
109+
#define RMON_R_OCTETS 0x2C4 /* RMON RX octets */
110+
#define IEEE_R_DROP 0x2C8 /* Count frames not counted correctly */
111+
#define IEEE_R_FRAME_OK 0x2CC /* Frames rx'd OK */
112+
#define IEEE_R_CRC 0x2D0 /* Frames rx'd with CRC err */
113+
#define IEEE_R_ALIGN 0x2D4 /* Frames rx'd with alignment err */
114+
#define IEEE_R_MACERR 0x2D8 /* Receive FIFO overflow count */
115+
#define IEEE_R_FDXFC 0x2DC /* Flow control pause frames rx'd */
116+
#define IEEE_R_OCTETS_OK 0x2E0 /* Octet cnt for frames rx'd w/o err */
117+
63118
#else
64119

65120
#define FEC_ECNTRL 0x000 /* Ethernet control reg */

drivers/net/ethernet/freescale/fec_main.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,14 @@ fec_restart(struct net_device *ndev, int duplex)
604604
if (fep->bufdesc_ex)
605605
ecntl |= (1 << 4);
606606

607+
#ifndef CONFIG_M5272
608+
/* Disable, clear, and enable the MIB */
609+
writel(1 << 31, fep->hwp + FEC_MIB_CTRLSTAT);
610+
for (i = RMON_T_DROP; i < IEEE_R_OCTETS_OK; i++)
611+
writel(0, fep->hwp + i);
612+
writel(0, fep->hwp + FEC_MIB_CTRLSTAT);
613+
#endif
614+
607615
/* And last, enable the transmit and receive processing */
608616
writel(ecntl, fep->hwp + FEC_ECNTRL);
609617
writel(0, fep->hwp + FEC_R_DES_ACTIVE);
@@ -1435,6 +1443,107 @@ static int fec_enet_set_pauseparam(struct net_device *ndev,
14351443
return 0;
14361444
}
14371445

1446+
#ifndef CONFIG_M5272
1447+
static const struct fec_stat {
1448+
char name[ETH_GSTRING_LEN];
1449+
u16 offset;
1450+
} fec_stats[] = {
1451+
/* RMON TX */
1452+
{ "tx_dropped", RMON_T_DROP },
1453+
{ "tx_packets", RMON_T_PACKETS },
1454+
{ "tx_broadcast", RMON_T_BC_PKT },
1455+
{ "tx_multicast", RMON_T_MC_PKT },
1456+
{ "tx_crc_errors", RMON_T_CRC_ALIGN },
1457+
{ "tx_undersize", RMON_T_UNDERSIZE },
1458+
{ "tx_oversize", RMON_T_OVERSIZE },
1459+
{ "tx_fragment", RMON_T_FRAG },
1460+
{ "tx_jabber", RMON_T_JAB },
1461+
{ "tx_collision", RMON_T_COL },
1462+
{ "tx_64byte", RMON_T_P64 },
1463+
{ "tx_65to127byte", RMON_T_P65TO127 },
1464+
{ "tx_128to255byte", RMON_T_P128TO255 },
1465+
{ "tx_256to511byte", RMON_T_P256TO511 },
1466+
{ "tx_512to1023byte", RMON_T_P512TO1023 },
1467+
{ "tx_1024to2047byte", RMON_T_P1024TO2047 },
1468+
{ "tx_GTE2048byte", RMON_T_P_GTE2048 },
1469+
{ "tx_octets", RMON_T_OCTETS },
1470+
1471+
/* IEEE TX */
1472+
{ "IEEE_tx_drop", IEEE_T_DROP },
1473+
{ "IEEE_tx_frame_ok", IEEE_T_FRAME_OK },
1474+
{ "IEEE_tx_1col", IEEE_T_1COL },
1475+
{ "IEEE_tx_mcol", IEEE_T_MCOL },
1476+
{ "IEEE_tx_def", IEEE_T_DEF },
1477+
{ "IEEE_tx_lcol", IEEE_T_LCOL },
1478+
{ "IEEE_tx_excol", IEEE_T_EXCOL },
1479+
{ "IEEE_tx_macerr", IEEE_T_MACERR },
1480+
{ "IEEE_tx_cserr", IEEE_T_CSERR },
1481+
{ "IEEE_tx_sqe", IEEE_T_SQE },
1482+
{ "IEEE_tx_fdxfc", IEEE_T_FDXFC },
1483+
{ "IEEE_tx_octets_ok", IEEE_T_OCTETS_OK },
1484+
1485+
/* RMON RX */
1486+
{ "rx_packets", RMON_R_PACKETS },
1487+
{ "rx_broadcast", RMON_R_BC_PKT },
1488+
{ "rx_multicast", RMON_R_MC_PKT },
1489+
{ "rx_crc_errors", RMON_R_CRC_ALIGN },
1490+
{ "rx_undersize", RMON_R_UNDERSIZE },
1491+
{ "rx_oversize", RMON_R_OVERSIZE },
1492+
{ "rx_fragment", RMON_R_FRAG },
1493+
{ "rx_jabber", RMON_R_JAB },
1494+
{ "rx_64byte", RMON_R_P64 },
1495+
{ "rx_65to127byte", RMON_R_P65TO127 },
1496+
{ "rx_128to255byte", RMON_R_P128TO255 },
1497+
{ "rx_256to511byte", RMON_R_P256TO511 },
1498+
{ "rx_512to1023byte", RMON_R_P512TO1023 },
1499+
{ "rx_1024to2047byte", RMON_R_P1024TO2047 },
1500+
{ "rx_GTE2048byte", RMON_R_P_GTE2048 },
1501+
{ "rx_octets", RMON_R_OCTETS },
1502+
1503+
/* IEEE RX */
1504+
{ "IEEE_rx_drop", IEEE_R_DROP },
1505+
{ "IEEE_rx_frame_ok", IEEE_R_FRAME_OK },
1506+
{ "IEEE_rx_crc", IEEE_R_CRC },
1507+
{ "IEEE_rx_align", IEEE_R_ALIGN },
1508+
{ "IEEE_rx_macerr", IEEE_R_MACERR },
1509+
{ "IEEE_rx_fdxfc", IEEE_R_FDXFC },
1510+
{ "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
1511+
};
1512+
1513+
static void fec_enet_get_ethtool_stats(struct net_device *dev,
1514+
struct ethtool_stats *stats, u64 *data)
1515+
{
1516+
struct fec_enet_private *fep = netdev_priv(dev);
1517+
int i;
1518+
1519+
for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
1520+
data[i] = readl(fep->hwp + fec_stats[i].offset);
1521+
}
1522+
1523+
static void fec_enet_get_strings(struct net_device *netdev,
1524+
u32 stringset, u8 *data)
1525+
{
1526+
int i;
1527+
switch (stringset) {
1528+
case ETH_SS_STATS:
1529+
for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
1530+
memcpy(data + i * ETH_GSTRING_LEN,
1531+
fec_stats[i].name, ETH_GSTRING_LEN);
1532+
break;
1533+
}
1534+
}
1535+
1536+
static int fec_enet_get_sset_count(struct net_device *dev, int sset)
1537+
{
1538+
switch (sset) {
1539+
case ETH_SS_STATS:
1540+
return ARRAY_SIZE(fec_stats);
1541+
default:
1542+
return -EOPNOTSUPP;
1543+
}
1544+
}
1545+
#endif
1546+
14381547
static int fec_enet_nway_reset(struct net_device *dev)
14391548
{
14401549
struct fec_enet_private *fep = netdev_priv(dev);
@@ -1455,6 +1564,11 @@ static const struct ethtool_ops fec_enet_ethtool_ops = {
14551564
.get_link = ethtool_op_get_link,
14561565
.get_ts_info = fec_enet_get_ts_info,
14571566
.nway_reset = fec_enet_nway_reset,
1567+
#ifndef CONFIG_M5272
1568+
.get_ethtool_stats = fec_enet_get_ethtool_stats,
1569+
.get_strings = fec_enet_get_strings,
1570+
.get_sset_count = fec_enet_get_sset_count,
1571+
#endif
14581572
};
14591573

14601574
static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)

0 commit comments

Comments
 (0)