summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-11-04 20:56:28 +0000
committerjhb <jhb@FreeBSD.org>2016-11-04 20:56:28 +0000
commit5338a780ee984a9041fc6ace725f8c43215c4ed5 (patch)
treeaa307001e4c321db2e17d5a5496c89b15d64400e
parent25ff16ca3a725bcde793795a0f19e184de8ecd3c (diff)
downloadFreeBSD-src-5338a780ee984a9041fc6ace725f8c43215c4ed5.zip
FreeBSD-src-5338a780ee984a9041fc6ace725f8c43215c4ed5.tar.gz
MFC 296975: cxgbe(4): Tidy up PAUSE frame accounting.
Figure out if the chip is counting PAUSE frames in the "normal" stats and take them out if it is. This fixes a bug in the tx stats because the default hardware behavior is different for Tx and Rx but the driver was treating both the same way. The result was that OPACKETS, OBYTES, and OMCASTS were under-reported (if tx_pause > 0) before this change. Note that the mac_stats sysctl still gives you the raw value of these statistics straight from the device registers. Sponsored by: Chelsio Communications
-rw-r--r--sys/dev/cxgbe/common/t4_hw.c15
-rw-r--r--sys/dev/cxgbe/t4_main.c12
2 files changed, 21 insertions, 6 deletions
diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c
index a618297..ef24ca5 100644
--- a/sys/dev/cxgbe/common/t4_hw.c
+++ b/sys/dev/cxgbe/common/t4_hw.c
@@ -5612,6 +5612,7 @@ void t4_get_port_stats_offset(struct adapter *adap, int idx,
void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
{
u32 bgmap = t4_get_mps_bg_map(adap, idx);
+ u32 stat_ctl;
#define GET_STAT(name) \
t4_read_reg64(adap, \
@@ -5619,6 +5620,8 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
T5_PORT_REG(idx, A_MPS_PORT_STAT_##name##_L)))
#define GET_STAT_COM(name) t4_read_reg64(adap, A_MPS_STAT_##name##_L)
+ stat_ctl = t4_read_reg(adap, A_MPS_STAT_CTL);
+
p->tx_pause = GET_STAT(TX_PORT_PAUSE);
p->tx_octets = GET_STAT(TX_PORT_BYTES);
p->tx_frames = GET_STAT(TX_PORT_FRAMES);
@@ -5643,6 +5646,12 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
p->tx_ppp6 = GET_STAT(TX_PORT_PPP6);
p->tx_ppp7 = GET_STAT(TX_PORT_PPP7);
+ if (stat_ctl & F_COUNTPAUSESTATTX) {
+ p->tx_frames -= p->tx_pause;
+ p->tx_octets -= p->tx_pause * 64;
+ p->tx_mcast_frames -= p->tx_pause;
+ }
+
p->rx_pause = GET_STAT(RX_PORT_PAUSE);
p->rx_octets = GET_STAT(RX_PORT_BYTES);
p->rx_frames = GET_STAT(RX_PORT_FRAMES);
@@ -5671,6 +5680,12 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
p->rx_ppp6 = GET_STAT(RX_PORT_PPP6);
p->rx_ppp7 = GET_STAT(RX_PORT_PPP7);
+ if (stat_ctl & F_COUNTPAUSESTATRX) {
+ p->rx_frames -= p->rx_pause;
+ p->rx_octets -= p->rx_pause * 64;
+ p->rx_mcast_frames -= p->rx_pause;
+ }
+
p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0;
p->rx_ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_DROP_FRAME) : 0;
p->rx_ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_DROP_FRAME) : 0;
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 132c026..f64ce21 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -4346,12 +4346,12 @@ cxgbe_refresh_stats(struct adapter *sc, struct port_info *pi)
t4_get_port_stats(sc, pi->tx_chan, s);
- ifp->if_opackets = s->tx_frames - s->tx_pause;
- ifp->if_ipackets = s->rx_frames - s->rx_pause;
- ifp->if_obytes = s->tx_octets - s->tx_pause * 64;
- ifp->if_ibytes = s->rx_octets - s->rx_pause * 64;
- ifp->if_omcasts = s->tx_mcast_frames - s->tx_pause;
- ifp->if_imcasts = s->rx_mcast_frames - s->rx_pause;
+ ifp->if_opackets = s->tx_frames;
+ ifp->if_ipackets = s->rx_frames;
+ ifp->if_obytes = s->tx_octets;
+ ifp->if_ibytes = s->rx_octets;
+ ifp->if_omcasts = s->tx_mcast_frames;
+ ifp->if_imcasts = s->rx_mcast_frames;
ifp->if_iqdrops = s->rx_ovflow0 + s->rx_ovflow1 + s->rx_ovflow2 +
s->rx_ovflow3 + s->rx_trunc0 + s->rx_trunc1 + s->rx_trunc2 +
s->rx_trunc3;
OpenPOWER on IntegriCloud