From mboxrd@z Thu Jan 1 00:00:00 1970 From: Guenter Roeck Subject: Re: [PATCH 1/1] fec: Add support for reading RMON registers Date: Tue, 25 Jun 2013 22:08:52 -0700 Message-ID: <20130626050852.GB17339@roeck-us.net> References: <1372220708-27147-1-git-send-email-cphealy@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: "David S. Miller" , Frank Li , Fabio Estevam , Ruslan Sushko , netdev@vger.kernel.org To: Chris Healy Return-path: Received: from mail.active-venture.com ([67.228.131.205]:59227 "EHLO mail.active-venture.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750718Ab3FZFIr (ORCPT ); Wed, 26 Jun 2013 01:08:47 -0400 Content-Disposition: inline In-Reply-To: <1372220708-27147-1-git-send-email-cphealy@gmail.com> Sender: netdev-owner@vger.kernel.org List-ID: On Tue, Jun 25, 2013 at 09:25:08PM -0700, Chris Healy wrote: > Add ethtool operation to read RMON registers. > > Tested against net-next on i.MX28. > > Signed-off-by: Chris Healy > --- Hi Chris, headline should say [PATCH v2], and you should have a changelog here. Otherwise it is difficult to distinguish the patch from v1. Thanks, Guenter > drivers/net/ethernet/freescale/fec.h | 55 ++++++++++++++ > drivers/net/ethernet/freescale/fec_main.c | 114 ++++++++++++++++++++++++++++++ > 2 files changed, 169 insertions(+) > > diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h > index e3ed6c5..8362a03 100644 > --- a/drivers/net/ethernet/freescale/fec.h > +++ b/drivers/net/ethernet/freescale/fec.h > @@ -60,6 +60,61 @@ > #define BM_MIIGSK_CFGR_RMII 0x01 > #define BM_MIIGSK_CFGR_FRCONT_10M 0x40 > > +#define RMON_T_DROP 0x200 /* Count of frames not cntd correctly */ > +#define RMON_T_PACKETS 0x204 /* RMON TX packet count */ > +#define RMON_T_BC_PKT 0x208 /* RMON TX broadcast pkts */ > +#define RMON_T_MC_PKT 0x20C /* RMON TX multicast pkts */ > +#define RMON_T_CRC_ALIGN 0x210 /* RMON TX pkts with CRC align err */ > +#define RMON_T_UNDERSIZE 0x214 /* RMON TX pkts < 64 bytes, good CRC */ > +#define RMON_T_OVERSIZE 0x218 /* RMON TX pkts > MAX_FL bytes good CRC */ > +#define RMON_T_FRAG 0x21C /* RMON TX pkts < 64 bytes, bad CRC */ > +#define RMON_T_JAB 0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */ > +#define RMON_T_COL 0x224 /* RMON TX collision count */ > +#define RMON_T_P64 0x228 /* RMON TX 64 byte pkts */ > +#define RMON_T_P65TO127 0x22C /* RMON TX 65 to 127 byte pkts */ > +#define RMON_T_P128TO255 0x230 /* RMON TX 128 to 255 byte pkts */ > +#define RMON_T_P256TO511 0x234 /* RMON TX 256 to 511 byte pkts */ > +#define RMON_T_P512TO1023 0x238 /* RMON TX 512 to 1023 byte pkts */ > +#define RMON_T_P1024TO2047 0x23C /* RMON TX 1024 to 2047 byte pkts */ > +#define RMON_T_P_GTE2048 0x240 /* RMON TX pkts > 2048 bytes */ > +#define RMON_T_OCTETS 0x244 /* RMON TX octets */ > +#define IEEE_T_DROP 0x248 /* Count of frames not counted crtly */ > +#define IEEE_T_FRAME_OK 0x24C /* Frames tx'd OK */ > +#define IEEE_T_1COL 0x250 /* Frames tx'd with single collision */ > +#define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */ > +#define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */ > +#define IEEE_T_LCOL 0x25C /* Frames tx'd with late collision */ > +#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */ > +#define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */ > +#define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */ > +#define IEEE_T_SQE 0x26C /* Frames tx'd with SQE err */ > +#define IEEE_T_FDXFC 0x270 /* Flow control pause frames tx'd */ > +#define IEEE_T_OCTETS_OK 0x274 /* Octet count for frames tx'd w/o err */ > +#define RMON_R_PACKETS 0x284 /* RMON RX packet count */ > +#define RMON_R_BC_PKT 0x288 /* RMON RX broadcast pkts */ > +#define RMON_R_MC_PKT 0x28C /* RMON RX multicast pkts */ > +#define RMON_R_CRC_ALIGN 0x290 /* RMON RX pkts with CRC alignment err */ > +#define RMON_R_UNDERSIZE 0x294 /* RMON RX pkts < 64 bytes, good CRC */ > +#define RMON_R_OVERSIZE 0x298 /* RMON RX pkts > MAX_FL bytes good CRC */ > +#define RMON_R_FRAG 0x29C /* RMON RX pkts < 64 bytes, bad CRC */ > +#define RMON_R_JAB 0x2A0 /* RMON RX pkts > MAX_FL bytes, bad CRC */ > +#define RMON_R_RESVD_O 0x2A4 /* Reserved */ > +#define RMON_R_P64 0x2A8 /* RMON RX 64 byte pkts */ > +#define RMON_R_P65TO127 0x2AC /* RMON RX 65 to 127 byte pkts */ > +#define RMON_R_P128TO255 0x2B0 /* RMON RX 128 to 255 byte pkts */ > +#define RMON_R_P256TO511 0x2B4 /* RMON RX 256 to 511 byte pkts */ > +#define RMON_R_P512TO1023 0x2B8 /* RMON RX 512 to 1023 byte pkts */ > +#define RMON_R_P1024TO2047 0x2BC /* RMON RX 1024 to 2047 byte pkts */ > +#define RMON_R_P_GTE2048 0x2C0 /* RMON RX pkts > 2048 bytes */ > +#define RMON_R_OCTETS 0x2C4 /* RMON RX octets */ > +#define IEEE_R_DROP 0x2C8 /* Count frames not counted correctly */ > +#define IEEE_R_FRAME_OK 0x2CC /* Frames rx'd OK */ > +#define IEEE_R_CRC 0x2D0 /* Frames rx'd with CRC err */ > +#define IEEE_R_ALIGN 0x2D4 /* Frames rx'd with alignment err */ > +#define IEEE_R_MACERR 0x2D8 /* Receive FIFO overflow count */ > +#define IEEE_R_FDXFC 0x2DC /* Flow control pause frames rx'd */ > +#define IEEE_R_OCTETS_OK 0x2E0 /* Octet cnt for frames rx'd w/o err */ > + > #else > > #define FEC_ECNTRL 0x000 /* Ethernet control reg */ > diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c > index 46f2544..ed6180e 100644 > --- a/drivers/net/ethernet/freescale/fec_main.c > +++ b/drivers/net/ethernet/freescale/fec_main.c > @@ -604,6 +604,14 @@ fec_restart(struct net_device *ndev, int duplex) > if (fep->bufdesc_ex) > ecntl |= (1 << 4); > > +#ifndef CONFIG_M5272 > + /* Disable, clear, and enable the MIB */ > + writel(1 << 31, fep->hwp + FEC_MIB_CTRLSTAT); > + for (i = RMON_T_DROP; i < IEEE_R_OCTETS_OK; i++) > + writel(0, fep->hwp + i); > + writel(0, fep->hwp + FEC_MIB_CTRLSTAT); > +#endif > + > /* And last, enable the transmit and receive processing */ > writel(ecntl, fep->hwp + FEC_ECNTRL); > writel(0, fep->hwp + FEC_R_DES_ACTIVE); > @@ -1435,6 +1443,107 @@ static int fec_enet_set_pauseparam(struct net_device *ndev, > return 0; > } > > +#ifndef CONFIG_M5272 > +static const struct fec_stat { > + char name[ETH_GSTRING_LEN]; > + u16 offset; > +} fec_stats[] = { > + /* RMON TX */ > + { "tx_dropped", RMON_T_DROP }, > + { "tx_packets", RMON_T_PACKETS }, > + { "tx_broadcast", RMON_T_BC_PKT }, > + { "tx_multicast", RMON_T_MC_PKT }, > + { "tx_crc_errors", RMON_T_CRC_ALIGN }, > + { "tx_undersize", RMON_T_UNDERSIZE }, > + { "tx_oversize", RMON_T_OVERSIZE }, > + { "tx_fragment", RMON_T_FRAG }, > + { "tx_jabber", RMON_T_JAB }, > + { "tx_collision", RMON_T_COL }, > + { "tx_64byte", RMON_T_P64 }, > + { "tx_65to127byte", RMON_T_P65TO127 }, > + { "tx_128to255byte", RMON_T_P128TO255 }, > + { "tx_256to511byte", RMON_T_P256TO511 }, > + { "tx_512to1023byte", RMON_T_P512TO1023 }, > + { "tx_1024to2047byte", RMON_T_P1024TO2047 }, > + { "tx_GTE2048byte", RMON_T_P_GTE2048 }, > + { "tx_octets", RMON_T_OCTETS }, > + > + /* IEEE TX */ > + { "IEEE_tx_drop", IEEE_T_DROP }, > + { "IEEE_tx_frame_ok", IEEE_T_FRAME_OK }, > + { "IEEE_tx_1col", IEEE_T_1COL }, > + { "IEEE_tx_mcol", IEEE_T_MCOL }, > + { "IEEE_tx_def", IEEE_T_DEF }, > + { "IEEE_tx_lcol", IEEE_T_LCOL }, > + { "IEEE_tx_excol", IEEE_T_EXCOL }, > + { "IEEE_tx_macerr", IEEE_T_MACERR }, > + { "IEEE_tx_cserr", IEEE_T_CSERR }, > + { "IEEE_tx_sqe", IEEE_T_SQE }, > + { "IEEE_tx_fdxfc", IEEE_T_FDXFC }, > + { "IEEE_tx_octets_ok", IEEE_T_OCTETS_OK }, > + > + /* RMON RX */ > + { "rx_packets", RMON_R_PACKETS }, > + { "rx_broadcast", RMON_R_BC_PKT }, > + { "rx_multicast", RMON_R_MC_PKT }, > + { "rx_crc_errors", RMON_R_CRC_ALIGN }, > + { "rx_undersize", RMON_R_UNDERSIZE }, > + { "rx_oversize", RMON_R_OVERSIZE }, > + { "rx_fragment", RMON_R_FRAG }, > + { "rx_jabber", RMON_R_JAB }, > + { "rx_64byte", RMON_R_P64 }, > + { "rx_65to127byte", RMON_R_P65TO127 }, > + { "rx_128to255byte", RMON_R_P128TO255 }, > + { "rx_256to511byte", RMON_R_P256TO511 }, > + { "rx_512to1023byte", RMON_R_P512TO1023 }, > + { "rx_1024to2047byte", RMON_R_P1024TO2047 }, > + { "rx_GTE2048byte", RMON_R_P_GTE2048 }, > + { "rx_octets", RMON_R_OCTETS }, > + > + /* IEEE RX */ > + { "IEEE_rx_drop", IEEE_R_DROP }, > + { "IEEE_rx_frame_ok", IEEE_R_FRAME_OK }, > + { "IEEE_rx_crc", IEEE_R_CRC }, > + { "IEEE_rx_align", IEEE_R_ALIGN }, > + { "IEEE_rx_macerr", IEEE_R_MACERR }, > + { "IEEE_rx_fdxfc", IEEE_R_FDXFC }, > + { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK }, > +}; > + > +static void fec_enet_get_ethtool_stats(struct net_device *dev, > + struct ethtool_stats *stats, u64 *data) > +{ > + struct fec_enet_private *fep = netdev_priv(dev); > + int i; > + > + for (i = 0; i < ARRAY_SIZE(fec_stats); i++) > + data[i] = readl(fep->hwp + fec_stats[i].offset); > +} > + > +static void fec_enet_get_strings(struct net_device *netdev, > + u32 stringset, u8 *data) > +{ > + int i; > + switch (stringset) { > + case ETH_SS_STATS: > + for (i = 0; i < ARRAY_SIZE(fec_stats); i++) > + memcpy(data + i * ETH_GSTRING_LEN, > + fec_stats[i].name, ETH_GSTRING_LEN); > + break; > + } > +} > + > +static int fec_enet_get_sset_count(struct net_device *dev, int sset) > +{ > + switch (sset) { > + case ETH_SS_STATS: > + return ARRAY_SIZE(fec_stats); > + default: > + return -EOPNOTSUPP; > + } > +} > +#endif > + > static int fec_enet_nway_reset(struct net_device *dev) > { > struct fec_enet_private *fep = netdev_priv(dev); > @@ -1455,6 +1564,11 @@ static const struct ethtool_ops fec_enet_ethtool_ops = { > .get_link = ethtool_op_get_link, > .get_ts_info = fec_enet_get_ts_info, > .nway_reset = fec_enet_nway_reset, > +#ifndef CONFIG_M5272 > + .get_ethtool_stats = fec_enet_get_ethtool_stats, > + .get_strings = fec_enet_get_strings, > + .get_sset_count = fec_enet_get_sset_count, > +#endif > }; > > static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) > -- > 1.8.1.2 > >