diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/bcmsysport.c')
| -rw-r--r-- | drivers/net/ethernet/broadcom/bcmsysport.c | 62 | 
1 files changed, 38 insertions, 24 deletions
| diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index c3c53f6cd9e6..eb441e5e2cd8 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -432,6 +432,27 @@ static void bcm_sysport_update_mib_counters(struct bcm_sysport_priv *priv)  	netif_dbg(priv, hw, priv->netdev, "updated MIB counters\n");  } +static void bcm_sysport_update_tx_stats(struct bcm_sysport_priv *priv, +					u64 *tx_bytes, u64 *tx_packets) +{ +	struct bcm_sysport_tx_ring *ring; +	u64 bytes = 0, packets = 0; +	unsigned int start; +	unsigned int q; + +	for (q = 0; q < priv->netdev->num_tx_queues; q++) { +		ring = &priv->tx_rings[q]; +		do { +			start = u64_stats_fetch_begin_irq(&priv->syncp); +			bytes = ring->bytes; +			packets = ring->packets; +		} while (u64_stats_fetch_retry_irq(&priv->syncp, start)); + +		*tx_bytes += bytes; +		*tx_packets += packets; +	} +} +  static void bcm_sysport_get_stats(struct net_device *dev,  				  struct ethtool_stats *stats, u64 *data)  { @@ -439,11 +460,16 @@ static void bcm_sysport_get_stats(struct net_device *dev,  	struct bcm_sysport_stats64 *stats64 = &priv->stats64;  	struct u64_stats_sync *syncp = &priv->syncp;  	struct bcm_sysport_tx_ring *ring; +	u64 tx_bytes = 0, tx_packets = 0;  	unsigned int start;  	int i, j; -	if (netif_running(dev)) +	if (netif_running(dev)) {  		bcm_sysport_update_mib_counters(priv); +		bcm_sysport_update_tx_stats(priv, &tx_bytes, &tx_packets); +		stats64->tx_bytes = tx_bytes; +		stats64->tx_packets = tx_packets; +	}  	for (i =  0, j = 0; i < BCM_SYSPORT_STATS_LEN; i++) {  		const struct bcm_sysport_stats *s; @@ -461,12 +487,13 @@ static void bcm_sysport_get_stats(struct net_device *dev,  			continue;  		p += s->stat_offset; -		if (s->stat_sizeof == sizeof(u64)) +		if (s->stat_sizeof == sizeof(u64) && +		    s->type == BCM_SYSPORT_STAT_NETDEV64) {  			do {  				start = u64_stats_fetch_begin_irq(syncp);  				data[i] = *(u64 *)p;  			} while (u64_stats_fetch_retry_irq(syncp, start)); -		else +		} else  			data[i] = *(u32 *)p;  		j++;  	} @@ -1716,27 +1743,12 @@ static void bcm_sysport_get_stats64(struct net_device *dev,  {  	struct bcm_sysport_priv *priv = netdev_priv(dev);  	struct bcm_sysport_stats64 *stats64 = &priv->stats64; -	struct bcm_sysport_tx_ring *ring; -	u64 tx_packets = 0, tx_bytes = 0;  	unsigned int start; -	unsigned int q;  	netdev_stats_to_stats64(stats, &dev->stats); -	for (q = 0; q < dev->num_tx_queues; q++) { -		ring = &priv->tx_rings[q]; -		do { -			start = u64_stats_fetch_begin_irq(&priv->syncp); -			tx_bytes = ring->bytes; -			tx_packets = ring->packets; -		} while (u64_stats_fetch_retry_irq(&priv->syncp, start)); - -		stats->tx_bytes += tx_bytes; -		stats->tx_packets += tx_packets; -	} - -	stats64->tx_bytes = stats->tx_bytes; -	stats64->tx_packets = stats->tx_packets; +	bcm_sysport_update_tx_stats(priv, &stats->tx_bytes, +				    &stats->tx_packets);  	do {  		start = u64_stats_fetch_begin_irq(&priv->syncp); @@ -1797,15 +1809,17 @@ static inline void bcm_sysport_mask_all_intrs(struct bcm_sysport_priv *priv)  static inline void gib_set_pad_extension(struct bcm_sysport_priv *priv)  { -	u32 __maybe_unused reg; +	u32 reg; -	/* Include Broadcom tag in pad extension */ +	reg = gib_readl(priv, GIB_CONTROL); +	/* Include Broadcom tag in pad extension and fix up IPG_LENGTH */  	if (netdev_uses_dsa(priv->netdev)) { -		reg = gib_readl(priv, GIB_CONTROL);  		reg &= ~(GIB_PAD_EXTENSION_MASK << GIB_PAD_EXTENSION_SHIFT);  		reg |= ENET_BRCM_TAG_LEN << GIB_PAD_EXTENSION_SHIFT; -		gib_writel(priv, reg, GIB_CONTROL);  	} +	reg &= ~(GIB_IPG_LEN_MASK << GIB_IPG_LEN_SHIFT); +	reg |= 12 << GIB_IPG_LEN_SHIFT; +	gib_writel(priv, reg, GIB_CONTROL);  }  static int bcm_sysport_open(struct net_device *dev) |