Commit 9684d7b0 authored by David S. Miller's avatar David S. Miller

Merge branch 'sfc-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc

Ben Hutchings says:

====================
Some more fixes for EF10 support; hopefully the last lot:

1. Fixes for reading statistics, from Edward Cree and Jon Cooper.
2. Addition of ethtool statistics for packets dropped by the hardware
before they were associated with a specific function, from Edward Cree.
3. Only bind to functions that are in control of their associated port,
as the driver currently assumes this is the case.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7eec4174 ecb1c9cc
...@@ -444,6 +444,18 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = { ...@@ -444,6 +444,18 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
EF10_DMA_STAT(rx_align_error, RX_ALIGN_ERROR_PKTS), EF10_DMA_STAT(rx_align_error, RX_ALIGN_ERROR_PKTS),
EF10_DMA_STAT(rx_length_error, RX_LENGTH_ERROR_PKTS), EF10_DMA_STAT(rx_length_error, RX_LENGTH_ERROR_PKTS),
EF10_DMA_STAT(rx_nodesc_drops, RX_NODESC_DROPS), EF10_DMA_STAT(rx_nodesc_drops, RX_NODESC_DROPS),
EF10_DMA_STAT(rx_pm_trunc_bb_overflow, PM_TRUNC_BB_OVERFLOW),
EF10_DMA_STAT(rx_pm_discard_bb_overflow, PM_DISCARD_BB_OVERFLOW),
EF10_DMA_STAT(rx_pm_trunc_vfifo_full, PM_TRUNC_VFIFO_FULL),
EF10_DMA_STAT(rx_pm_discard_vfifo_full, PM_DISCARD_VFIFO_FULL),
EF10_DMA_STAT(rx_pm_trunc_qbb, PM_TRUNC_QBB),
EF10_DMA_STAT(rx_pm_discard_qbb, PM_DISCARD_QBB),
EF10_DMA_STAT(rx_pm_discard_mapping, PM_DISCARD_MAPPING),
EF10_DMA_STAT(rx_dp_q_disabled_packets, RXDP_Q_DISABLED_PKTS),
EF10_DMA_STAT(rx_dp_di_dropped_packets, RXDP_DI_DROPPED_PKTS),
EF10_DMA_STAT(rx_dp_streaming_packets, RXDP_STREAMING_PKTS),
EF10_DMA_STAT(rx_dp_emerg_fetch, RXDP_EMERGENCY_FETCH_CONDITIONS),
EF10_DMA_STAT(rx_dp_emerg_wait, RXDP_EMERGENCY_WAIT_CONDITIONS),
}; };
#define HUNT_COMMON_STAT_MASK ((1ULL << EF10_STAT_tx_bytes) | \ #define HUNT_COMMON_STAT_MASK ((1ULL << EF10_STAT_tx_bytes) | \
...@@ -498,44 +510,72 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = { ...@@ -498,44 +510,72 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
#define HUNT_40G_EXTRA_STAT_MASK ((1ULL << EF10_STAT_rx_align_error) | \ #define HUNT_40G_EXTRA_STAT_MASK ((1ULL << EF10_STAT_rx_align_error) | \
(1ULL << EF10_STAT_rx_length_error)) (1ULL << EF10_STAT_rx_length_error))
#if BITS_PER_LONG == 64 /* These statistics are only provided if the firmware supports the
#define STAT_MASK_BITMAP(bits) (bits) * capability PM_AND_RXDP_COUNTERS.
#else */
#define STAT_MASK_BITMAP(bits) (bits) & 0xffffffff, (bits) >> 32 #define HUNT_PM_AND_RXDP_STAT_MASK ( \
#endif (1ULL << EF10_STAT_rx_pm_trunc_bb_overflow) | \
(1ULL << EF10_STAT_rx_pm_discard_bb_overflow) | \
static const unsigned long *efx_ef10_stat_mask(struct efx_nic *efx) (1ULL << EF10_STAT_rx_pm_trunc_vfifo_full) | \
{ (1ULL << EF10_STAT_rx_pm_discard_vfifo_full) | \
static const unsigned long hunt_40g_stat_mask[] = { (1ULL << EF10_STAT_rx_pm_trunc_qbb) | \
STAT_MASK_BITMAP(HUNT_COMMON_STAT_MASK | (1ULL << EF10_STAT_rx_pm_discard_qbb) | \
HUNT_40G_EXTRA_STAT_MASK) (1ULL << EF10_STAT_rx_pm_discard_mapping) | \
}; (1ULL << EF10_STAT_rx_dp_q_disabled_packets) | \
static const unsigned long hunt_10g_only_stat_mask[] = { (1ULL << EF10_STAT_rx_dp_di_dropped_packets) | \
STAT_MASK_BITMAP(HUNT_COMMON_STAT_MASK | (1ULL << EF10_STAT_rx_dp_streaming_packets) | \
HUNT_10G_ONLY_STAT_MASK) (1ULL << EF10_STAT_rx_dp_emerg_fetch) | \
}; (1ULL << EF10_STAT_rx_dp_emerg_wait))
static u64 efx_ef10_raw_stat_mask(struct efx_nic *efx)
{
u64 raw_mask = HUNT_COMMON_STAT_MASK;
u32 port_caps = efx_mcdi_phy_get_caps(efx); u32 port_caps = efx_mcdi_phy_get_caps(efx);
struct efx_ef10_nic_data *nic_data = efx->nic_data;
if (port_caps & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) if (port_caps & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
return hunt_40g_stat_mask; raw_mask |= HUNT_40G_EXTRA_STAT_MASK;
else else
return hunt_10g_only_stat_mask; raw_mask |= HUNT_10G_ONLY_STAT_MASK;
if (nic_data->datapath_caps &
(1 << MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_LBN))
raw_mask |= HUNT_PM_AND_RXDP_STAT_MASK;
return raw_mask;
}
static void efx_ef10_get_stat_mask(struct efx_nic *efx, unsigned long *mask)
{
u64 raw_mask = efx_ef10_raw_stat_mask(efx);
#if BITS_PER_LONG == 64
mask[0] = raw_mask;
#else
mask[0] = raw_mask & 0xffffffff;
mask[1] = raw_mask >> 32;
#endif
} }
static size_t efx_ef10_describe_stats(struct efx_nic *efx, u8 *names) static size_t efx_ef10_describe_stats(struct efx_nic *efx, u8 *names)
{ {
DECLARE_BITMAP(mask, EF10_STAT_COUNT);
efx_ef10_get_stat_mask(efx, mask);
return efx_nic_describe_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, return efx_nic_describe_stats(efx_ef10_stat_desc, EF10_STAT_COUNT,
efx_ef10_stat_mask(efx), names); mask, names);
} }
static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) static int efx_ef10_try_update_nic_stats(struct efx_nic *efx)
{ {
struct efx_ef10_nic_data *nic_data = efx->nic_data; struct efx_ef10_nic_data *nic_data = efx->nic_data;
const unsigned long *stats_mask = efx_ef10_stat_mask(efx); DECLARE_BITMAP(mask, EF10_STAT_COUNT);
__le64 generation_start, generation_end; __le64 generation_start, generation_end;
u64 *stats = nic_data->stats; u64 *stats = nic_data->stats;
__le64 *dma_stats; __le64 *dma_stats;
efx_ef10_get_stat_mask(efx, mask);
dma_stats = efx->stats_buffer.addr; dma_stats = efx->stats_buffer.addr;
nic_data = efx->nic_data; nic_data = efx->nic_data;
...@@ -543,8 +583,9 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) ...@@ -543,8 +583,9 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx)
if (generation_end == EFX_MC_STATS_GENERATION_INVALID) if (generation_end == EFX_MC_STATS_GENERATION_INVALID)
return 0; return 0;
rmb(); rmb();
efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, stats_mask, efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, mask,
stats, efx->stats_buffer.addr, false); stats, efx->stats_buffer.addr, false);
rmb();
generation_start = dma_stats[MC_CMD_MAC_GENERATION_START]; generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
if (generation_end != generation_start) if (generation_end != generation_start)
return -EAGAIN; return -EAGAIN;
...@@ -563,12 +604,14 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) ...@@ -563,12 +604,14 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx)
static size_t efx_ef10_update_stats(struct efx_nic *efx, u64 *full_stats, static size_t efx_ef10_update_stats(struct efx_nic *efx, u64 *full_stats,
struct rtnl_link_stats64 *core_stats) struct rtnl_link_stats64 *core_stats)
{ {
const unsigned long *mask = efx_ef10_stat_mask(efx); DECLARE_BITMAP(mask, EF10_STAT_COUNT);
struct efx_ef10_nic_data *nic_data = efx->nic_data; struct efx_ef10_nic_data *nic_data = efx->nic_data;
u64 *stats = nic_data->stats; u64 *stats = nic_data->stats;
size_t stats_count = 0, index; size_t stats_count = 0, index;
int retry; int retry;
efx_ef10_get_stat_mask(efx, mask);
/* If we're unlucky enough to read statistics during the DMA, wait /* If we're unlucky enough to read statistics during the DMA, wait
* up to 10ms for it to finish (typically takes <500us) * up to 10ms for it to finish (typically takes <500us)
*/ */
......
...@@ -963,7 +963,7 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, ...@@ -963,7 +963,7 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
bool *was_attached) bool *was_attached)
{ {
MCDI_DECLARE_BUF(inbuf, MC_CMD_DRV_ATTACH_IN_LEN); MCDI_DECLARE_BUF(inbuf, MC_CMD_DRV_ATTACH_IN_LEN);
MCDI_DECLARE_BUF(outbuf, MC_CMD_DRV_ATTACH_OUT_LEN); MCDI_DECLARE_BUF(outbuf, MC_CMD_DRV_ATTACH_EXT_OUT_LEN);
size_t outlen; size_t outlen;
int rc; int rc;
...@@ -981,6 +981,22 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, ...@@ -981,6 +981,22 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
goto fail; goto fail;
} }
/* We currently assume we have control of the external link
* and are completely trusted by firmware. Abort probing
* if that's not true for this function.
*/
if (driver_operating &&
outlen >= MC_CMD_DRV_ATTACH_EXT_OUT_LEN &&
(MCDI_DWORD(outbuf, DRV_ATTACH_EXT_OUT_FUNC_FLAGS) &
(1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL |
1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TRUSTED)) !=
(1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL |
1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TRUSTED)) {
netif_err(efx, probe, efx->net_dev,
"This driver version only supports one function per port\n");
return -ENODEV;
}
if (was_attached != NULL) if (was_attached != NULL)
*was_attached = MCDI_DWORD(outbuf, DRV_ATTACH_OUT_OLD_STATE); *was_attached = MCDI_DWORD(outbuf, DRV_ATTACH_OUT_OLD_STATE);
return 0; return 0;
......
...@@ -2574,8 +2574,58 @@ ...@@ -2574,8 +2574,58 @@
#define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */ #define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */
#define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */ #define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */
#define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */ #define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */
#define MC_CMD_GMAC_DMABUF_START 0x40 /* enum */ /* enum: PM trunc_bb_overflow counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
#define MC_CMD_GMAC_DMABUF_END 0x5f /* enum */ * capability only.
*/
#define MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW 0x3c
/* enum: PM discard_bb_overflow counter. Valid for EF10 with
* PM_AND_RXDP_COUNTERS capability only.
*/
#define MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW 0x3d
/* enum: PM trunc_vfifo_full counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
* capability only.
*/
#define MC_CMD_MAC_PM_TRUNC_VFIFO_FULL 0x3e
/* enum: PM discard_vfifo_full counter. Valid for EF10 with
* PM_AND_RXDP_COUNTERS capability only.
*/
#define MC_CMD_MAC_PM_DISCARD_VFIFO_FULL 0x3f
/* enum: PM trunc_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
* capability only.
*/
#define MC_CMD_MAC_PM_TRUNC_QBB 0x40
/* enum: PM discard_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
* capability only.
*/
#define MC_CMD_MAC_PM_DISCARD_QBB 0x41
/* enum: PM discard_mapping counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
* capability only.
*/
#define MC_CMD_MAC_PM_DISCARD_MAPPING 0x42
/* enum: RXDP counter: Number of packets dropped due to the queue being
* disabled. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
*/
#define MC_CMD_MAC_RXDP_Q_DISABLED_PKTS 0x43
/* enum: RXDP counter: Number of packets dropped by the DICPU. Valid for EF10
* with PM_AND_RXDP_COUNTERS capability only.
*/
#define MC_CMD_MAC_RXDP_DI_DROPPED_PKTS 0x45
/* enum: RXDP counter: Number of non-host packets. Valid for EF10 with
* PM_AND_RXDP_COUNTERS capability only.
*/
#define MC_CMD_MAC_RXDP_STREAMING_PKTS 0x46
/* enum: RXDP counter: Number of times an emergency descriptor fetch was
* performed. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
*/
#define MC_CMD_MAC_RXDP_EMERGENCY_FETCH_CONDITIONS 0x47
/* enum: RXDP counter: Number of times the DPCPU waited for an existing
* descriptor fetch. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
*/
#define MC_CMD_MAC_RXDP_EMERGENCY_WAIT_CONDITIONS 0x48
/* enum: Start of GMAC stats buffer space, for Siena only. */
#define MC_CMD_GMAC_DMABUF_START 0x40
/* enum: End of GMAC stats buffer space, for Siena only. */
#define MC_CMD_GMAC_DMABUF_END 0x5f
#define MC_CMD_MAC_GENERATION_END 0x60 /* enum */ #define MC_CMD_MAC_GENERATION_END 0x60 /* enum */
#define MC_CMD_MAC_NSTATS 0x61 /* enum */ #define MC_CMD_MAC_NSTATS 0x61 /* enum */
...@@ -5065,6 +5115,8 @@ ...@@ -5065,6 +5115,8 @@
#define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_WIDTH 1 #define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_WIDTH 1
#define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_LBN 26 #define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_LBN 26
#define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_WIDTH 1 #define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_WIDTH 1
#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_LBN 27
#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
/* RxDPCPU firmware id. */ /* RxDPCPU firmware id. */
#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_OFST 4 #define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_OFST 4
#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_LEN 2 #define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_LEN 2
......
...@@ -469,8 +469,7 @@ size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, ...@@ -469,8 +469,7 @@ size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count,
* @count: Length of the @desc array * @count: Length of the @desc array
* @mask: Bitmask of which elements of @desc are enabled * @mask: Bitmask of which elements of @desc are enabled
* @stats: Buffer to update with the converted statistics. The length * @stats: Buffer to update with the converted statistics. The length
* of this array must be at least the number of set bits in the * of this array must be at least @count.
* first @count bits of @mask.
* @dma_buf: DMA buffer containing hardware statistics * @dma_buf: DMA buffer containing hardware statistics
* @accumulate: If set, the converted values will be added rather than * @accumulate: If set, the converted values will be added rather than
* directly stored to the corresponding elements of @stats * directly stored to the corresponding elements of @stats
...@@ -503,11 +502,9 @@ void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count, ...@@ -503,11 +502,9 @@ void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count,
} }
if (accumulate) if (accumulate)
*stats += val; stats[index] += val;
else else
*stats = val; stats[index] = val;
} }
++stats;
} }
} }
...@@ -386,6 +386,18 @@ enum { ...@@ -386,6 +386,18 @@ enum {
EF10_STAT_rx_align_error, EF10_STAT_rx_align_error,
EF10_STAT_rx_length_error, EF10_STAT_rx_length_error,
EF10_STAT_rx_nodesc_drops, EF10_STAT_rx_nodesc_drops,
EF10_STAT_rx_pm_trunc_bb_overflow,
EF10_STAT_rx_pm_discard_bb_overflow,
EF10_STAT_rx_pm_trunc_vfifo_full,
EF10_STAT_rx_pm_discard_vfifo_full,
EF10_STAT_rx_pm_trunc_qbb,
EF10_STAT_rx_pm_discard_qbb,
EF10_STAT_rx_pm_discard_mapping,
EF10_STAT_rx_dp_q_disabled_packets,
EF10_STAT_rx_dp_di_dropped_packets,
EF10_STAT_rx_dp_streaming_packets,
EF10_STAT_rx_dp_emerg_fetch,
EF10_STAT_rx_dp_emerg_wait,
EF10_STAT_COUNT EF10_STAT_COUNT
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment