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 {