Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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


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
Loading
Loading
Loading
Loading
+65 −22
Original line number Diff line number Diff line
@@ -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_length_error, RX_LENGTH_ERROR_PKTS),
	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) |		\
@@ -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) |	\
				  (1ULL << EF10_STAT_rx_length_error))

#if BITS_PER_LONG == 64
#define STAT_MASK_BITMAP(bits) (bits)
#else
#define STAT_MASK_BITMAP(bits) (bits) & 0xffffffff, (bits) >> 32
#endif

static const unsigned long *efx_ef10_stat_mask(struct efx_nic *efx)
{
	static const unsigned long hunt_40g_stat_mask[] = {
		STAT_MASK_BITMAP(HUNT_COMMON_STAT_MASK |
				 HUNT_40G_EXTRA_STAT_MASK)
	};
	static const unsigned long hunt_10g_only_stat_mask[] = {
		STAT_MASK_BITMAP(HUNT_COMMON_STAT_MASK |
				 HUNT_10G_ONLY_STAT_MASK)
	};
/* These statistics are only provided if the firmware supports the
 * capability PM_AND_RXDP_COUNTERS.
 */
#define HUNT_PM_AND_RXDP_STAT_MASK (					\
	(1ULL << EF10_STAT_rx_pm_trunc_bb_overflow) |			\
	(1ULL << EF10_STAT_rx_pm_discard_bb_overflow) |			\
	(1ULL << EF10_STAT_rx_pm_trunc_vfifo_full) |			\
	(1ULL << EF10_STAT_rx_pm_discard_vfifo_full) |			\
	(1ULL << EF10_STAT_rx_pm_trunc_qbb) |				\
	(1ULL << EF10_STAT_rx_pm_discard_qbb) |				\
	(1ULL << EF10_STAT_rx_pm_discard_mapping) |			\
	(1ULL << EF10_STAT_rx_dp_q_disabled_packets) |			\
	(1ULL << EF10_STAT_rx_dp_di_dropped_packets) |			\
	(1ULL << EF10_STAT_rx_dp_streaming_packets) |			\
	(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);
	struct efx_ef10_nic_data *nic_data = efx->nic_data;

	if (port_caps & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
		return hunt_40g_stat_mask;
		raw_mask |= HUNT_40G_EXTRA_STAT_MASK;
	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)
{
	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,
				      efx_ef10_stat_mask(efx), names);
				      mask, names);
}

static int efx_ef10_try_update_nic_stats(struct efx_nic *efx)
{
	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;
	u64 *stats = nic_data->stats;
	__le64 *dma_stats;

	efx_ef10_get_stat_mask(efx, mask);

	dma_stats = efx->stats_buffer.addr;
	nic_data = efx->nic_data;

@@ -543,8 +583,9 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx)
	if (generation_end == EFX_MC_STATS_GENERATION_INVALID)
		return 0;
	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);
	rmb();
	generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
	if (generation_end != generation_start)
		return -EAGAIN;
@@ -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,
				    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;
	u64 *stats = nic_data->stats;
	size_t stats_count = 0, index;
	int retry;

	efx_ef10_get_stat_mask(efx, mask);

	/* If we're unlucky enough to read statistics during the DMA, wait
	 * up to 10ms for it to finish (typically takes <500us)
	 */
+17 −1
Original line number Diff line number Diff line
@@ -963,7 +963,7 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
			       bool *was_attached)
{
	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;
	int rc;

@@ -981,6 +981,22 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
		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)
		*was_attached = MCDI_DWORD(outbuf, DRV_ATTACH_OUT_OLD_STATE);
	return 0;
+54 −2
Original line number Diff line number Diff line
@@ -2574,8 +2574,58 @@
#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_MATCH_FAULT  0x3b /* enum */
#define          MC_CMD_GMAC_DMABUF_START  0x40 /* enum */
#define          MC_CMD_GMAC_DMABUF_END    0x5f /* enum */
/* enum: PM trunc_bb_overflow counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
 * 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_NSTATS  0x61 /* enum */

@@ -5065,6 +5115,8 @@
#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_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. */
#define       MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_OFST 4
#define       MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_LEN 2
+3 −6
Original line number Diff line number Diff line
@@ -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
 * @mask: Bitmask of which elements of @desc are enabled
 * @stats: Buffer to update with the converted statistics.  The length
 *	of this array must be at least the number of set bits in the
 *	first @count bits of @mask.
 *	of this array must be at least @count.
 * @dma_buf: DMA buffer containing hardware statistics
 * @accumulate: If set, the converted values will be added rather than
 *	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,
			}

			if (accumulate)
				*stats += val;
				stats[index] += val;
			else
				*stats = val;
				stats[index] = val;
		}

		++stats;
	}
}
+12 −0
Original line number Diff line number Diff line
@@ -386,6 +386,18 @@ enum {
	EF10_STAT_rx_align_error,
	EF10_STAT_rx_length_error,
	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
};