aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc/mcdi_port.c
diff options
context:
space:
mode:
authorJon Cooper <jcooper@solarflare.com>2013-09-30 12:36:50 -0400
committerBen Hutchings <bhutchings@solarflare.com>2013-12-12 17:06:51 -0500
commitf8f3b5ae3ea45ef6b00b471fed0fc90552a3c4af (patch)
treee65cedae54bb32528176a2d31890ee86cd6db62d /drivers/net/ethernet/sfc/mcdi_port.c
parentcce28794bc99c15f0d4c98936a473ac6e21be0ad (diff)
sfc: Correct RX dropped count for drops while interface is down
We don't directly control RX ingress on Siena or any later controllers, and so we cannot prevent packets from entering the RX datapath while the RX queues are not set up. This results in the hardware incrementing RX_NODESC_DROP_CNT, but it's not an error and we should not include it in error stats. When bringing an interface up or down, pull (or wait for) stats and count the number of packets that were dropped while the interface was down. Subtract this from the reported RX dropped count. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/mcdi_port.c')
-rw-r--r--drivers/net/ethernet/sfc/mcdi_port.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi_port.c b/drivers/net/ethernet/sfc/mcdi_port.c
index 7b6be61d549f..7288aefc2877 100644
--- a/drivers/net/ethernet/sfc/mcdi_port.c
+++ b/drivers/net/ethernet/sfc/mcdi_port.c
@@ -927,12 +927,23 @@ bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
927 return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0; 927 return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
928} 928}
929 929
930static int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, 930enum efx_stats_action {
931 u32 dma_len, int enable, int clear) 931 EFX_STATS_ENABLE,
932 EFX_STATS_DISABLE,
933 EFX_STATS_PULL,
934};
935
936static int efx_mcdi_mac_stats(struct efx_nic *efx,
937 enum efx_stats_action action, int clear)
932{ 938{
933 MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN); 939 MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
934 int rc; 940 int rc;
935 int period = enable ? 1000 : 0; 941 int change = action == EFX_STATS_PULL ? 0 : 1;
942 int enable = action == EFX_STATS_ENABLE ? 1 : 0;
943 int period = action == EFX_STATS_ENABLE ? 1000 : 0;
944 dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
945 u32 dma_len = action != EFX_STATS_DISABLE ?
946 MC_CMD_MAC_NSTATS * sizeof(u64) : 0;
936 947
937 BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0); 948 BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
938 949
@@ -940,8 +951,8 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
940 MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD, 951 MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
941 MAC_STATS_IN_DMA, !!enable, 952 MAC_STATS_IN_DMA, !!enable,
942 MAC_STATS_IN_CLEAR, clear, 953 MAC_STATS_IN_CLEAR, clear,
943 MAC_STATS_IN_PERIODIC_CHANGE, 1, 954 MAC_STATS_IN_PERIODIC_CHANGE, change,
944 MAC_STATS_IN_PERIODIC_ENABLE, !!enable, 955 MAC_STATS_IN_PERIODIC_ENABLE, enable,
945 MAC_STATS_IN_PERIODIC_CLEAR, 0, 956 MAC_STATS_IN_PERIODIC_CLEAR, 0,
946 MAC_STATS_IN_PERIODIC_NOEVENT, 1, 957 MAC_STATS_IN_PERIODIC_NOEVENT, 1,
947 MAC_STATS_IN_PERIOD_MS, period); 958 MAC_STATS_IN_PERIOD_MS, period);
@@ -955,8 +966,8 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
955 return 0; 966 return 0;
956 967
957fail: 968fail:
958 netif_err(efx, hw, efx->net_dev, "%s: %s failed rc=%d\n", 969 netif_err(efx, hw, efx->net_dev, "%s: action %d failed rc=%d\n",
959 __func__, enable ? "enable" : "disable", rc); 970 __func__, action, rc);
960 return rc; 971 return rc;
961} 972}
962 973
@@ -966,13 +977,29 @@ void efx_mcdi_mac_start_stats(struct efx_nic *efx)
966 977
967 dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID; 978 dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID;
968 979
969 efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 980 efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
970 MC_CMD_MAC_NSTATS * sizeof(u64), 1, 0);
971} 981}
972 982
973void efx_mcdi_mac_stop_stats(struct efx_nic *efx) 983void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
974{ 984{
975 efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 0, 0, 0); 985 efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
986}
987
988#define EFX_MAC_STATS_WAIT_US 100
989#define EFX_MAC_STATS_WAIT_ATTEMPTS 10
990
991void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
992{
993 __le64 *dma_stats = efx->stats_buffer.addr;
994 int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
995
996 dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID;
997 efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
998
999 while (dma_stats[MC_CMD_MAC_GENERATION_END] ==
1000 EFX_MC_STATS_GENERATION_INVALID &&
1001 attempts-- != 0)
1002 udelay(EFX_MAC_STATS_WAIT_US);
976} 1003}
977 1004
978int efx_mcdi_port_probe(struct efx_nic *efx) 1005int efx_mcdi_port_probe(struct efx_nic *efx)
@@ -1003,7 +1030,7 @@ int efx_mcdi_port_probe(struct efx_nic *efx)
1003 efx->stats_buffer.addr, 1030 efx->stats_buffer.addr,
1004 (u64)virt_to_phys(efx->stats_buffer.addr)); 1031 (u64)virt_to_phys(efx->stats_buffer.addr));
1005 1032
1006 efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 0, 0, 1); 1033 efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 1);
1007 1034
1008 return 0; 1035 return 0;
1009} 1036}