Generate the net_dev_stats from rmon stats.
b/13396740
Change-Id: I4012c8f99592712568788783e549ebcc71298e1f
diff --git a/pfe_ctrl/pfe_eth.c b/pfe_ctrl/pfe_eth.c
index 61fdeb4..0d9dcbd 100644
--- a/pfe_ctrl/pfe_eth.c
+++ b/pfe_ctrl/pfe_eth.c
@@ -601,6 +601,22 @@
}
}
+
+static void pfe_eth_read_rmon_stats(struct net_device *dev) {
+ struct pfe_eth_priv_s *priv = netdev_priv(dev);
+ u32 *counts = (u32*)&priv->rmon_counts;
+ u32 *totals = (u32*)&priv->rmon_totals;
+ u32 tmp;
+ int i;
+
+ for (i=0;i<EMAC_RMON_LEN;i++, counts++, totals++) {
+ tmp = readl(priv->EMAC_baseaddr + EMAC_RMON_BASE_OFST + (i << 2));
+ *counts += tmp;
+ *totals += tmp;
+ }
+}
+
+
/**
* pfe_eth_fill_stats - Fill in an array of 64-bit statistics from
* various sources. This array will be appended
@@ -611,14 +627,16 @@
{
struct pfe_eth_priv_s *priv = netdev_priv(dev);
int i;
+ u32 *counts = (u32*)&priv->rmon_counts;
+ pfe_eth_read_rmon_stats(dev);
for (i=0;i<EMAC_RMON_LEN;i++, buf++) {
- *buf = readl(priv->EMAC_baseaddr + EMAC_RMON_BASE_OFST + (i << 2));
+ *buf = counts[i];
if ( ( i == EMAC_RMON_TXBYTES_POS ) || ( i == EMAC_RMON_RXBYTES_POS ) ){
i++;
- *buf |= (u64)readl(priv->EMAC_baseaddr + EMAC_RMON_BASE_OFST + (i << 2)) << 32;
+ *buf |= (u64)counts[i] << 32;
}
}
-
+ memset(&priv->rmon_counts, 0, sizeof(priv->rmon_counts));
}
/**
@@ -1796,7 +1814,53 @@
netif_info(priv, drv, dev, "%s\n", __func__);
- return &priv->stats;
+ // read the rmon stats.
+ pfe_eth_read_rmon_stats(dev);
+
+ // create net_dev stats from the rmon totals.
+ priv->rmon_stats.rx_packets = priv->rmon_totals.frames_rx;
+ priv->rmon_stats.tx_packets = priv->rmon_totals.frames_tx;
+ priv->rmon_stats.rx_bytes = priv->rmon_totals.octets_rx_bot;
+ priv->rmon_stats.tx_bytes = priv->rmon_totals.octets_tx_bot;
+ priv->rmon_stats.rx_errors =
+ priv->rmon_totals.usize_frames +
+ priv->rmon_totals.excess_length +
+ priv->rmon_totals.jabbers +
+ priv->rmon_totals.fcs_errors +
+ priv->rmon_totals.length_check_errors +
+ priv->rmon_totals.rx_symbol_errors +
+ priv->rmon_totals.align_errors +
+ priv->stats.rx_errors;
+
+ priv->rmon_stats.tx_errors =
+ priv->rmon_totals.excess_col +
+ priv->rmon_totals.late_col +
+ priv->rmon_totals.crs_errors +
+ priv->stats.tx_errors;
+
+ priv->rmon_stats.rx_dropped =
+ priv->stats.rx_dropped +
+ priv->rmon_totals.rx_res_errors +
+ priv->rmon_totals.rx_orun;
+
+ priv->rmon_stats.tx_dropped =
+ priv->stats.tx_dropped +
+ priv->rmon_totals.tx_urun;
+
+ priv->rmon_stats.multicast = priv->rmon_totals.multicast_rx;
+
+ priv->rmon_stats.collisions =
+ priv->rmon_totals.single_col +
+ priv->rmon_totals.multi_col;
+
+ priv->rmon_stats.rx_length_errors =
+ priv->rmon_totals.usize_frames +
+ priv->rmon_totals.excess_length +
+ priv->rmon_totals.length_check_errors;
+
+ priv->rmon_stats.rx_crc_errors = priv->rmon_totals.fcs_errors;
+
+ return &priv->rmon_stats;
}
@@ -2739,4 +2803,3 @@
pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
}
}
-
diff --git a/pfe_ctrl/pfe_eth.h b/pfe_ctrl/pfe_eth.h
index 76d8e44..cbc35e6 100644
--- a/pfe_ctrl/pfe_eth.h
+++ b/pfe_ctrl/pfe_eth.h
@@ -291,6 +291,10 @@
unsigned int napi_counters[NAPI_MAX_COUNT];
#endif
+ // Keeps the most read of the rmon registers as well as a running total.
+ struct gemac_stats rmon_counts;
+ struct gemac_stats rmon_totals;
+ struct net_device_stats rmon_stats;
}pfe_eth_priv_t;
struct pfe_eth {