Skip to content

Commit 0fe7463

Browse files
Sriramdavem330
authored andcommitted
TI DaVinci EMAC: Clear statistics register properly.
The mechanism to clear the statistics register is dependent on the status of GMIIEN bit in MAC control register. If the GMIIEN bit is set, the stats registers are write to decrement. If the GMIIEN bit is cleared, the stats registers are plain read/write registers. The stats register clearing operation must take into account the current state of GMIIEN as it can be cleared when the interface is brought down. With existing implementation logic, querying for interface stats when the interface is down, can corrupt the statistics counters. This patch examines the GMIIEN bit status in MAC_CONTROL register before choosing an appropriate mask for clearing stats registers. Signed-off-by: Sriramakrishnan <[email protected]> Acked-by: Chaithrika U S <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent daf9df6 commit 0fe7463

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

drivers/net/davinci_emac.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
333333
#define EMAC_DM646X_MAC_EOI_C0_RXEN (0x01)
334334
#define EMAC_DM646X_MAC_EOI_C0_TXEN (0x02)
335335

336+
/* EMAC Stats Clear Mask */
337+
#define EMAC_STATS_CLR_MASK (0xFFFFFFFF)
338+
336339
/** net_buf_obj: EMAC network bufferdata structure
337340
*
338341
* EMAC network buffer data structure
@@ -2548,40 +2551,49 @@ static int emac_dev_stop(struct net_device *ndev)
25482551
static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
25492552
{
25502553
struct emac_priv *priv = netdev_priv(ndev);
2554+
u32 mac_control;
2555+
u32 stats_clear_mask;
25512556

25522557
/* update emac hardware stats and reset the registers*/
25532558

2559+
mac_control = emac_read(EMAC_MACCONTROL);
2560+
2561+
if (mac_control & EMAC_MACCONTROL_GMIIEN)
2562+
stats_clear_mask = EMAC_STATS_CLR_MASK;
2563+
else
2564+
stats_clear_mask = 0;
2565+
25542566
priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
2555-
emac_write(EMAC_RXMCASTFRAMES, EMAC_ALL_MULTI_REG_VALUE);
2567+
emac_write(EMAC_RXMCASTFRAMES, stats_clear_mask);
25562568

25572569
priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
25582570
emac_read(EMAC_TXSINGLECOLL) +
25592571
emac_read(EMAC_TXMULTICOLL));
2560-
emac_write(EMAC_TXCOLLISION, EMAC_ALL_MULTI_REG_VALUE);
2561-
emac_write(EMAC_TXSINGLECOLL, EMAC_ALL_MULTI_REG_VALUE);
2562-
emac_write(EMAC_TXMULTICOLL, EMAC_ALL_MULTI_REG_VALUE);
2572+
emac_write(EMAC_TXCOLLISION, stats_clear_mask);
2573+
emac_write(EMAC_TXSINGLECOLL, stats_clear_mask);
2574+
emac_write(EMAC_TXMULTICOLL, stats_clear_mask);
25632575

25642576
priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
25652577
emac_read(EMAC_RXJABBER) +
25662578
emac_read(EMAC_RXUNDERSIZED));
2567-
emac_write(EMAC_RXOVERSIZED, EMAC_ALL_MULTI_REG_VALUE);
2568-
emac_write(EMAC_RXJABBER, EMAC_ALL_MULTI_REG_VALUE);
2569-
emac_write(EMAC_RXUNDERSIZED, EMAC_ALL_MULTI_REG_VALUE);
2579+
emac_write(EMAC_RXOVERSIZED, stats_clear_mask);
2580+
emac_write(EMAC_RXJABBER, stats_clear_mask);
2581+
emac_write(EMAC_RXUNDERSIZED, stats_clear_mask);
25702582

25712583
priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
25722584
emac_read(EMAC_RXMOFOVERRUNS));
2573-
emac_write(EMAC_RXSOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
2574-
emac_write(EMAC_RXMOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
2585+
emac_write(EMAC_RXSOFOVERRUNS, stats_clear_mask);
2586+
emac_write(EMAC_RXMOFOVERRUNS, stats_clear_mask);
25752587

25762588
priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
2577-
emac_write(EMAC_RXDMAOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
2589+
emac_write(EMAC_RXDMAOVERRUNS, stats_clear_mask);
25782590

25792591
priv->net_dev_stats.tx_carrier_errors +=
25802592
emac_read(EMAC_TXCARRIERSENSE);
2581-
emac_write(EMAC_TXCARRIERSENSE, EMAC_ALL_MULTI_REG_VALUE);
2593+
emac_write(EMAC_TXCARRIERSENSE, stats_clear_mask);
25822594

25832595
priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
2584-
emac_write(EMAC_TXUNDERRUN, EMAC_ALL_MULTI_REG_VALUE);
2596+
emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
25852597

25862598
return &priv->net_dev_stats;
25872599
}

0 commit comments

Comments
 (0)