DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 13/56] net/sfc: import libefx built-in selftest support
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

EFSYS_OPT_BIST should be enabled to use it.

>From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/base/ef10_impl.h  |  29 +++++
 drivers/net/sfc/efx/base/ef10_phy.c   | 153 +++++++++++++++++++++++++
 drivers/net/sfc/efx/base/efx.h        |  80 +++++++++++++
 drivers/net/sfc/efx/base/efx_check.h  |   7 ++
 drivers/net/sfc/efx/base/efx_impl.h   |  11 ++
 drivers/net/sfc/efx/base/efx_mcdi.c   | 115 +++++++++++++++++++
 drivers/net/sfc/efx/base/efx_mcdi.h   |  12 ++
 drivers/net/sfc/efx/base/efx_phy.c    | 140 +++++++++++++++++++++++
 drivers/net/sfc/efx/base/siena_impl.h |  25 +++++
 drivers/net/sfc/efx/base/siena_phy.c  | 205 ++++++++++++++++++++++++++++++++++
 10 files changed, 777 insertions(+)

diff --git a/drivers/net/sfc/efx/base/ef10_impl.h b/drivers/net/sfc/efx/base/ef10_impl.h
index 5bebbe9..5cbe6b1 100644
--- a/drivers/net/sfc/efx/base/ef10_impl.h
+++ b/drivers/net/sfc/efx/base/ef10_impl.h
@@ -345,6 +345,35 @@ ef10_phy_oui_get(
 	__in		efx_nic_t *enp,
 	__out		uint32_t *ouip);
 
+#if EFSYS_OPT_BIST
+
+extern	__checkReturn		efx_rc_t
+ef10_bist_enable_offline(
+	__in			efx_nic_t *enp);
+
+extern	__checkReturn		efx_rc_t
+ef10_bist_start(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type);
+
+extern	__checkReturn		efx_rc_t
+ef10_bist_poll(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type,
+	__out			efx_bist_result_t *resultp,
+	__out_opt __drv_when(count > 0, __notnull)
+	uint32_t	*value_maskp,
+	__out_ecount_opt(count)	__drv_when(count > 0, __notnull)
+	unsigned long	*valuesp,
+	__in			size_t count);
+
+extern				void
+ef10_bist_stop(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type);
+
+#endif	/* EFSYS_OPT_BIST */
+
 /* TX */
 
 extern	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/efx/base/ef10_phy.c b/drivers/net/sfc/efx/base/ef10_phy.c
index 36e2603..9e1b9c2 100644
--- a/drivers/net/sfc/efx/base/ef10_phy.c
+++ b/drivers/net/sfc/efx/base/ef10_phy.c
@@ -390,4 +390,157 @@ ef10_phy_oui_get(
 	return (ENOTSUP);
 }
 
+#if EFSYS_OPT_BIST
+
+	__checkReturn		efx_rc_t
+ef10_bist_enable_offline(
+	__in			efx_nic_t *enp)
+{
+	efx_rc_t rc;
+
+	if ((rc = efx_mcdi_bist_enable_offline(enp)) != 0)
+		goto fail1;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn		efx_rc_t
+ef10_bist_start(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type)
+{
+	efx_rc_t rc;
+
+	if ((rc = efx_mcdi_bist_start(enp, type)) != 0)
+		goto fail1;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn		efx_rc_t
+ef10_bist_poll(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type,
+	__out			efx_bist_result_t *resultp,
+	__out_opt __drv_when(count > 0, __notnull)
+	uint32_t *value_maskp,
+	__out_ecount_opt(count)	__drv_when(count > 0, __notnull)
+	unsigned long *valuesp,
+	__in			size_t count)
+{
+	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+	efx_mcdi_req_t req;
+	uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
+			    MCDI_CTL_SDU_LEN_MAX)];
+	uint32_t value_mask = 0;
+	uint32_t result;
+	efx_rc_t rc;
+
+	_NOTE(ARGUNUSED(type))
+
+	(void) memset(payload, 0, sizeof (payload));
+	req.emr_cmd = MC_CMD_POLL_BIST;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MCDI_CTL_SDU_LEN_MAX;
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail1;
+	}
+
+	if (req.emr_out_length_used < MC_CMD_POLL_BIST_OUT_RESULT_OFST + 4) {
+		rc = EMSGSIZE;
+		goto fail2;
+	}
+
+	if (count > 0)
+		(void) memset(valuesp, '\0', count * sizeof (unsigned long));
+
+	result = MCDI_OUT_DWORD(req, POLL_BIST_OUT_RESULT);
+
+	if (result == MC_CMD_POLL_BIST_FAILED &&
+	    req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MEM_LEN &&
+	    count > EFX_BIST_MEM_ECC_FATAL) {
+		if (valuesp != NULL) {
+			valuesp[EFX_BIST_MEM_TEST] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_TEST);
+			valuesp[EFX_BIST_MEM_ADDR] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ADDR);
+			valuesp[EFX_BIST_MEM_BUS] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_BUS);
+			valuesp[EFX_BIST_MEM_EXPECT] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_EXPECT);
+			valuesp[EFX_BIST_MEM_ACTUAL] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ACTUAL);
+			valuesp[EFX_BIST_MEM_ECC] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC);
+			valuesp[EFX_BIST_MEM_ECC_PARITY] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC_PARITY);
+			valuesp[EFX_BIST_MEM_ECC_FATAL] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC_FATAL);
+		}
+		value_mask |= (1 << EFX_BIST_MEM_TEST) |
+		    (1 << EFX_BIST_MEM_ADDR) |
+		    (1 << EFX_BIST_MEM_BUS) |
+		    (1 << EFX_BIST_MEM_EXPECT) |
+		    (1 << EFX_BIST_MEM_ACTUAL) |
+		    (1 << EFX_BIST_MEM_ECC) |
+		    (1 << EFX_BIST_MEM_ECC_PARITY) |
+		    (1 << EFX_BIST_MEM_ECC_FATAL);
+	} else if (result == MC_CMD_POLL_BIST_FAILED &&
+	    encp->enc_phy_type == EFX_PHY_XFI_FARMI &&
+	    req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MRSFP_LEN &&
+	    count > EFX_BIST_FAULT_CODE) {
+		if (valuesp != NULL)
+			valuesp[EFX_BIST_FAULT_CODE] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MRSFP_TEST);
+		value_mask |= 1 << EFX_BIST_FAULT_CODE;
+	}
+
+	if (value_maskp != NULL)
+		*value_maskp = value_mask;
+
+	EFSYS_ASSERT(resultp != NULL);
+	if (result == MC_CMD_POLL_BIST_RUNNING)
+		*resultp = EFX_BIST_RESULT_RUNNING;
+	else if (result == MC_CMD_POLL_BIST_PASSED)
+		*resultp = EFX_BIST_RESULT_PASSED;
+	else
+		*resultp = EFX_BIST_RESULT_FAILED;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+			void
+ef10_bist_stop(
+	__in		efx_nic_t *enp,
+	__in		efx_bist_type_t type)
+{
+	/* There is no way to stop BIST on EF10. */
+	_NOTE(ARGUNUSED(enp, type))
+}
+
+#endif	/* EFSYS_OPT_BIST */
+
 #endif	/* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/drivers/net/sfc/efx/base/efx.h b/drivers/net/sfc/efx/base/efx.h
index 4cabc79..15faf9d 100644
--- a/drivers/net/sfc/efx/base/efx.h
+++ b/drivers/net/sfc/efx/base/efx.h
@@ -549,6 +549,83 @@ efx_phy_module_get_info(
 	__out_bcount(len)		uint8_t *data);
 
 
+#if EFSYS_OPT_BIST
+
+typedef enum efx_bist_type_e {
+	EFX_BIST_TYPE_UNKNOWN,
+	EFX_BIST_TYPE_PHY_NORMAL,
+	EFX_BIST_TYPE_PHY_CABLE_SHORT,
+	EFX_BIST_TYPE_PHY_CABLE_LONG,
+	EFX_BIST_TYPE_MC_MEM,	/* Test the MC DMEM and IMEM */
+	EFX_BIST_TYPE_SAT_MEM,	/* Test the DMEM and IMEM of satellite cpus*/
+	EFX_BIST_TYPE_REG,	/* Test the register memories */
+	EFX_BIST_TYPE_NTYPES,
+} efx_bist_type_t;
+
+typedef enum efx_bist_result_e {
+	EFX_BIST_RESULT_UNKNOWN,
+	EFX_BIST_RESULT_RUNNING,
+	EFX_BIST_RESULT_PASSED,
+	EFX_BIST_RESULT_FAILED,
+} efx_bist_result_t;
+
+typedef enum efx_phy_cable_status_e {
+	EFX_PHY_CABLE_STATUS_OK,
+	EFX_PHY_CABLE_STATUS_INVALID,
+	EFX_PHY_CABLE_STATUS_OPEN,
+	EFX_PHY_CABLE_STATUS_INTRAPAIRSHORT,
+	EFX_PHY_CABLE_STATUS_INTERPAIRSHORT,
+	EFX_PHY_CABLE_STATUS_BUSY,
+} efx_phy_cable_status_t;
+
+typedef enum efx_bist_value_e {
+	EFX_BIST_PHY_CABLE_LENGTH_A,
+	EFX_BIST_PHY_CABLE_LENGTH_B,
+	EFX_BIST_PHY_CABLE_LENGTH_C,
+	EFX_BIST_PHY_CABLE_LENGTH_D,
+	EFX_BIST_PHY_CABLE_STATUS_A,
+	EFX_BIST_PHY_CABLE_STATUS_B,
+	EFX_BIST_PHY_CABLE_STATUS_C,
+	EFX_BIST_PHY_CABLE_STATUS_D,
+	EFX_BIST_FAULT_CODE,
+	/* Memory BIST specific values. These match to the MC_CMD_BIST_POLL
+	 * response. */
+	EFX_BIST_MEM_TEST,
+	EFX_BIST_MEM_ADDR,
+	EFX_BIST_MEM_BUS,
+	EFX_BIST_MEM_EXPECT,
+	EFX_BIST_MEM_ACTUAL,
+	EFX_BIST_MEM_ECC,
+	EFX_BIST_MEM_ECC_PARITY,
+	EFX_BIST_MEM_ECC_FATAL,
+	EFX_BIST_NVALUES,
+} efx_bist_value_t;
+
+extern	__checkReturn		efx_rc_t
+efx_bist_enable_offline(
+	__in			efx_nic_t *enp);
+
+extern	__checkReturn		efx_rc_t
+efx_bist_start(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type);
+
+extern	__checkReturn		efx_rc_t
+efx_bist_poll(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type,
+	__out			efx_bist_result_t *resultp,
+	__out_opt		uint32_t *value_maskp,
+	__out_ecount_opt(count)	unsigned long *valuesp,
+	__in			size_t count);
+
+extern				void
+efx_bist_stop(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type);
+
+#endif	/* EFSYS_OPT_BIST */
+
 #define	EFX_FEATURE_IPV6		0x00000001
 #define	EFX_FEATURE_LFSR_HASH_INSERT	0x00000002
 #define	EFX_FEATURE_LINK_EVENTS		0x00000004
@@ -594,6 +671,9 @@ typedef struct efx_nic_cfg_s {
 #if EFSYS_OPT_MCDI
 	uint8_t			enc_mcdi_mdio_channel;
 #endif	/* EFSYS_OPT_MCDI */
+#if EFSYS_OPT_BIST
+	uint32_t		enc_bist_mask;
+#endif	/* EFSYS_OPT_BIST */
 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
 	uint32_t		enc_pf;
 	uint32_t		enc_vf;
diff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h
index feaccd0..c78c5b6 100644
--- a/drivers/net/sfc/efx/base/efx_check.h
+++ b/drivers/net/sfc/efx/base/efx_check.h
@@ -214,6 +214,13 @@
 #  error "MCAST_FILTER_LIST is obsolete and is not supported"
 #endif
 
+#if EFSYS_OPT_BIST
+/* Support BIST */
+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)
+#  error "BIST requires SIENA or HUNTINGTON or MEDFORD"
+# endif
+#endif /* EFSYS_OPT_BIST */
+
 #if EFSYS_OPT_ALLOW_UNCONFIGURED_NIC
 /* Support adapters with missing static config (for factory use only) */
 # if !EFSYS_OPT_MEDFORD
diff --git a/drivers/net/sfc/efx/base/efx_impl.h b/drivers/net/sfc/efx/base/efx_impl.h
index a7c6b29..a6853b3 100644
--- a/drivers/net/sfc/efx/base/efx_impl.h
+++ b/drivers/net/sfc/efx/base/efx_impl.h
@@ -175,6 +175,14 @@ typedef struct efx_phy_ops_s {
 	efx_rc_t	(*epo_reconfigure)(efx_nic_t *);
 	efx_rc_t	(*epo_verify)(efx_nic_t *);
 	efx_rc_t	(*epo_oui_get)(efx_nic_t *, uint32_t *);
+#if EFSYS_OPT_BIST
+	efx_rc_t	(*epo_bist_enable_offline)(efx_nic_t *);
+	efx_rc_t	(*epo_bist_start)(efx_nic_t *, efx_bist_type_t);
+	efx_rc_t	(*epo_bist_poll)(efx_nic_t *, efx_bist_type_t,
+					 efx_bist_result_t *, uint32_t *,
+					 unsigned long *, size_t);
+	void		(*epo_bist_stop)(efx_nic_t *, efx_bist_type_t);
+#endif	/* EFSYS_OPT_BIST */
 } efx_phy_ops_t;
 
 #if EFSYS_OPT_FILTER
@@ -230,6 +238,9 @@ typedef struct efx_port_s {
 	uint32_t		ep_phy_cap_mask;
 	boolean_t		ep_mac_drain;
 	boolean_t		ep_mac_stats_pending;
+#if EFSYS_OPT_BIST
+	efx_bist_type_t		ep_current_bist;
+#endif
 	const efx_mac_ops_t	*ep_emop;
 	const efx_phy_ops_t	*ep_epop;
 } efx_port_t;
diff --git a/drivers/net/sfc/efx/base/efx_mcdi.c b/drivers/net/sfc/efx/base/efx_mcdi.c
index ef4e7ea..40cd456 100644
--- a/drivers/net/sfc/efx/base/efx_mcdi.c
+++ b/drivers/net/sfc/efx/base/efx_mcdi.c
@@ -1432,6 +1432,19 @@ efx_mcdi_get_phy_cfg(
 	encp->enc_mcdi_mdio_channel =
 		(uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_CHANNEL);
 
+#if EFSYS_OPT_BIST
+	encp->enc_bist_mask = 0;
+	if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
+	    GET_PHY_CFG_OUT_BIST_CABLE_SHORT))
+		encp->enc_bist_mask |= (1 << EFX_BIST_TYPE_PHY_CABLE_SHORT);
+	if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
+	    GET_PHY_CFG_OUT_BIST_CABLE_LONG))
+		encp->enc_bist_mask |= (1 << EFX_BIST_TYPE_PHY_CABLE_LONG);
+	if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
+	    GET_PHY_CFG_OUT_BIST))
+		encp->enc_bist_mask |= (1 << EFX_BIST_TYPE_PHY_NORMAL);
+#endif  /* EFSYS_OPT_BIST */
+
 	return (0);
 
 fail2:
@@ -1542,6 +1555,108 @@ efx_mcdi_mac_spoofing_supported(
 	return (rc);
 }
 
+#if EFSYS_OPT_BIST
+
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
+/*
+ * Enter bist offline mode. This is a fw mode which puts the NIC into a state
+ * where memory BIST tests can be run and not much else can interfere or happen.
+ * A reboot is required to exit this mode.
+ */
+	__checkReturn		efx_rc_t
+efx_mcdi_bist_enable_offline(
+	__in			efx_nic_t *enp)
+{
+	efx_mcdi_req_t req;
+	efx_rc_t rc;
+
+	EFX_STATIC_ASSERT(MC_CMD_ENABLE_OFFLINE_BIST_IN_LEN == 0);
+	EFX_STATIC_ASSERT(MC_CMD_ENABLE_OFFLINE_BIST_OUT_LEN == 0);
+
+	req.emr_cmd = MC_CMD_ENABLE_OFFLINE_BIST;
+	req.emr_in_buf = NULL;
+	req.emr_in_length = 0;
+	req.emr_out_buf = NULL;
+	req.emr_out_length = 0;
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail1;
+	}
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
+
+	__checkReturn		efx_rc_t
+efx_mcdi_bist_start(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type)
+{
+	efx_mcdi_req_t req;
+	uint8_t payload[MAX(MC_CMD_START_BIST_IN_LEN,
+			    MC_CMD_START_BIST_OUT_LEN)];
+	efx_rc_t rc;
+
+	(void) memset(payload, 0, sizeof (payload));
+	req.emr_cmd = MC_CMD_START_BIST;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_START_BIST_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_START_BIST_OUT_LEN;
+
+	switch (type) {
+	case EFX_BIST_TYPE_PHY_NORMAL:
+		MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE, MC_CMD_PHY_BIST);
+		break;
+	case EFX_BIST_TYPE_PHY_CABLE_SHORT:
+		MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+		    MC_CMD_PHY_BIST_CABLE_SHORT);
+		break;
+	case EFX_BIST_TYPE_PHY_CABLE_LONG:
+		MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+		    MC_CMD_PHY_BIST_CABLE_LONG);
+		break;
+	case EFX_BIST_TYPE_MC_MEM:
+		MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+		    MC_CMD_MC_MEM_BIST);
+		break;
+	case EFX_BIST_TYPE_SAT_MEM:
+		MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+		    MC_CMD_PORT_MEM_BIST);
+		break;
+	case EFX_BIST_TYPE_REG:
+		MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+		    MC_CMD_REG_BIST);
+		break;
+	default:
+		EFSYS_ASSERT(0);
+	}
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail1;
+	}
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+#endif /* EFSYS_OPT_BIST */
+
 
 /* Enable logging of some events (e.g. link state changes) */
 	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/efx/base/efx_mcdi.h b/drivers/net/sfc/efx/base/efx_mcdi.h
index a62e921..6e24313 100644
--- a/drivers/net/sfc/efx/base/efx_mcdi.h
+++ b/drivers/net/sfc/efx/base/efx_mcdi.h
@@ -180,6 +180,18 @@ efx_mcdi_mac_spoofing_supported(
 	__out			boolean_t *supportedp);
 
 
+#if EFSYS_OPT_BIST
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
+extern	__checkReturn		efx_rc_t
+efx_mcdi_bist_enable_offline(
+	__in			efx_nic_t *enp);
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
+extern	__checkReturn		efx_rc_t
+efx_mcdi_bist_start(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type);
+#endif /* EFSYS_OPT_BIST */
+
 extern	__checkReturn		efx_rc_t
 efx_mcdi_get_resource_limits(
 	__in			efx_nic_t *enp,
diff --git a/drivers/net/sfc/efx/base/efx_phy.c b/drivers/net/sfc/efx/base/efx_phy.c
index e7e915e..f07f127 100644
--- a/drivers/net/sfc/efx/base/efx_phy.c
+++ b/drivers/net/sfc/efx/base/efx_phy.c
@@ -39,6 +39,12 @@ static const efx_phy_ops_t	__efx_phy_siena_ops = {
 	siena_phy_reconfigure,		/* epo_reconfigure */
 	siena_phy_verify,		/* epo_verify */
 	siena_phy_oui_get,		/* epo_oui_get */
+#if EFSYS_OPT_BIST
+	NULL,				/* epo_bist_enable_offline */
+	siena_phy_bist_start,		/* epo_bist_start */
+	siena_phy_bist_poll,		/* epo_bist_poll */
+	siena_phy_bist_stop,		/* epo_bist_stop */
+#endif	/* EFSYS_OPT_BIST */
 };
 #endif	/* EFSYS_OPT_SIENA */
 
@@ -49,6 +55,12 @@ static const efx_phy_ops_t	__efx_phy_ef10_ops = {
 	ef10_phy_reconfigure,		/* epo_reconfigure */
 	ef10_phy_verify,		/* epo_verify */
 	ef10_phy_oui_get,		/* epo_oui_get */
+#if EFSYS_OPT_BIST
+	ef10_bist_enable_offline,	/* epo_bist_enable_offline */
+	ef10_bist_start,		/* epo_bist_start */
+	ef10_bist_poll,			/* epo_bist_poll */
+	ef10_bist_stop,			/* epo_bist_stop */
+#endif	/* EFSYS_OPT_BIST */
 };
 #endif	/* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
 
@@ -266,6 +278,134 @@ efx_phy_module_get_info(
 }
 
 
+#if EFSYS_OPT_BIST
+
+	__checkReturn		efx_rc_t
+efx_bist_enable_offline(
+	__in			efx_nic_t *enp)
+{
+	efx_port_t *epp = &(enp->en_port);
+	const efx_phy_ops_t *epop = epp->ep_epop;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+	if (epop->epo_bist_enable_offline == NULL) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
+		goto fail2;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+
+}
+
+	__checkReturn		efx_rc_t
+efx_bist_start(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type)
+{
+	efx_port_t *epp = &(enp->en_port);
+	const efx_phy_ops_t *epop = epp->ep_epop;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+	EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
+	EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
+	EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
+
+	if (epop->epo_bist_start == NULL) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if ((rc = epop->epo_bist_start(enp, type)) != 0)
+		goto fail2;
+
+	epp->ep_current_bist = type;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn		efx_rc_t
+efx_bist_poll(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type,
+	__out			efx_bist_result_t *resultp,
+	__out_opt		uint32_t *value_maskp,
+	__out_ecount_opt(count)	unsigned long *valuesp,
+	__in			size_t count)
+{
+	efx_port_t *epp = &(enp->en_port);
+	const efx_phy_ops_t *epop = epp->ep_epop;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+	EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
+	EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
+	EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
+
+	EFSYS_ASSERT(epop->epo_bist_poll != NULL);
+	if (epop->epo_bist_poll == NULL) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
+	    valuesp, count)) != 0)
+		goto fail2;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+			void
+efx_bist_stop(
+	__in		efx_nic_t *enp,
+	__in		efx_bist_type_t type)
+{
+	efx_port_t *epp = &(enp->en_port);
+	const efx_phy_ops_t *epop = epp->ep_epop;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+	EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
+	EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
+	EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
+
+	EFSYS_ASSERT(epop->epo_bist_stop != NULL);
+
+	if (epop->epo_bist_stop != NULL)
+		epop->epo_bist_stop(enp, type);
+
+	epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
+}
+
+#endif	/* EFSYS_OPT_BIST */
 			void
 efx_phy_unprobe(
 	__in	efx_nic_t *enp)
diff --git a/drivers/net/sfc/efx/base/siena_impl.h b/drivers/net/sfc/efx/base/siena_impl.h
index c316867..bdaa4a3 100644
--- a/drivers/net/sfc/efx/base/siena_impl.h
+++ b/drivers/net/sfc/efx/base/siena_impl.h
@@ -170,6 +170,31 @@ siena_phy_oui_get(
 	__in		efx_nic_t *enp,
 	__out		uint32_t *ouip);
 
+#if EFSYS_OPT_BIST
+
+extern	__checkReturn		efx_rc_t
+siena_phy_bist_start(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type);
+
+extern	__checkReturn		efx_rc_t
+siena_phy_bist_poll(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type,
+	__out			efx_bist_result_t *resultp,
+	__out_opt __drv_when(count > 0, __notnull)
+	uint32_t	*value_maskp,
+	__out_ecount_opt(count)	__drv_when(count > 0, __notnull)
+	unsigned long	*valuesp,
+	__in			size_t count);
+
+extern				void
+siena_phy_bist_stop(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type);
+
+#endif	/* EFSYS_OPT_BIST */
+
 extern	__checkReturn	efx_rc_t
 siena_mac_poll(
 	__in		efx_nic_t *enp,
diff --git a/drivers/net/sfc/efx/base/siena_phy.c b/drivers/net/sfc/efx/base/siena_phy.c
index 0e3fc34..d7e7d77 100644
--- a/drivers/net/sfc/efx/base/siena_phy.c
+++ b/drivers/net/sfc/efx/base/siena_phy.c
@@ -372,4 +372,209 @@ siena_phy_oui_get(
 	return (ENOTSUP);
 }
 
+#if EFSYS_OPT_BIST
+
+	__checkReturn		efx_rc_t
+siena_phy_bist_start(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type)
+{
+	efx_rc_t rc;
+
+	if ((rc = efx_mcdi_bist_start(enp, type)) != 0)
+		goto fail1;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+static	__checkReturn		unsigned long
+siena_phy_sft9001_bist_status(
+	__in			uint16_t code)
+{
+	switch (code) {
+	case MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY:
+		return (EFX_PHY_CABLE_STATUS_BUSY);
+	case MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT:
+		return (EFX_PHY_CABLE_STATUS_INTERPAIRSHORT);
+	case MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT:
+		return (EFX_PHY_CABLE_STATUS_INTRAPAIRSHORT);
+	case MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN:
+		return (EFX_PHY_CABLE_STATUS_OPEN);
+	case MC_CMD_POLL_BIST_SFT9001_PAIR_OK:
+		return (EFX_PHY_CABLE_STATUS_OK);
+	default:
+		return (EFX_PHY_CABLE_STATUS_INVALID);
+	}
+}
+
+	__checkReturn		efx_rc_t
+siena_phy_bist_poll(
+	__in			efx_nic_t *enp,
+	__in			efx_bist_type_t type,
+	__out			efx_bist_result_t *resultp,
+	__out_opt __drv_when(count > 0, __notnull)
+	uint32_t *value_maskp,
+	__out_ecount_opt(count)	__drv_when(count > 0, __notnull)
+	unsigned long *valuesp,
+	__in			size_t count)
+{
+	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+	uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
+			    MCDI_CTL_SDU_LEN_MAX)];
+	uint32_t value_mask = 0;
+	efx_mcdi_req_t req;
+	uint32_t result;
+	efx_rc_t rc;
+
+	(void) memset(payload, 0, sizeof (payload));
+	req.emr_cmd = MC_CMD_POLL_BIST;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MCDI_CTL_SDU_LEN_MAX;
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail1;
+	}
+
+	if (req.emr_out_length_used < MC_CMD_POLL_BIST_OUT_RESULT_OFST + 4) {
+		rc = EMSGSIZE;
+		goto fail2;
+	}
+
+	if (count > 0)
+		(void) memset(valuesp, '\0', count * sizeof (unsigned long));
+
+	result = MCDI_OUT_DWORD(req, POLL_BIST_OUT_RESULT);
+
+	/* Extract PHY specific results */
+	if (result == MC_CMD_POLL_BIST_PASSED &&
+	    encp->enc_phy_type == EFX_PHY_SFT9001B &&
+	    req.emr_out_length_used >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN &&
+	    (type == EFX_BIST_TYPE_PHY_CABLE_SHORT ||
+	    type == EFX_BIST_TYPE_PHY_CABLE_LONG)) {
+		uint16_t word;
+
+		if (count > EFX_BIST_PHY_CABLE_LENGTH_A) {
+			if (valuesp != NULL)
+				valuesp[EFX_BIST_PHY_CABLE_LENGTH_A] =
+				    MCDI_OUT_DWORD(req,
+				    POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
+			value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_A);
+		}
+
+		if (count > EFX_BIST_PHY_CABLE_LENGTH_B) {
+			if (valuesp != NULL)
+				valuesp[EFX_BIST_PHY_CABLE_LENGTH_B] =
+				    MCDI_OUT_DWORD(req,
+				    POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B);
+			value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_B);
+		}
+
+		if (count > EFX_BIST_PHY_CABLE_LENGTH_C) {
+			if (valuesp != NULL)
+				valuesp[EFX_BIST_PHY_CABLE_LENGTH_C] =
+				    MCDI_OUT_DWORD(req,
+				    POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C);
+			value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_C);
+		}
+
+		if (count > EFX_BIST_PHY_CABLE_LENGTH_D) {
+			if (valuesp != NULL)
+				valuesp[EFX_BIST_PHY_CABLE_LENGTH_D] =
+				    MCDI_OUT_DWORD(req,
+				    POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D);
+			value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_D);
+		}
+
+		if (count > EFX_BIST_PHY_CABLE_STATUS_A) {
+			if (valuesp != NULL) {
+				word = MCDI_OUT_WORD(req,
+				    POLL_BIST_OUT_SFT9001_CABLE_STATUS_A);
+				valuesp[EFX_BIST_PHY_CABLE_STATUS_A] =
+				    siena_phy_sft9001_bist_status(word);
+			}
+			value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_A);
+		}
+
+		if (count > EFX_BIST_PHY_CABLE_STATUS_B) {
+			if (valuesp != NULL) {
+				word = MCDI_OUT_WORD(req,
+				    POLL_BIST_OUT_SFT9001_CABLE_STATUS_B);
+				valuesp[EFX_BIST_PHY_CABLE_STATUS_B] =
+				    siena_phy_sft9001_bist_status(word);
+			}
+			value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_B);
+		}
+
+		if (count > EFX_BIST_PHY_CABLE_STATUS_C) {
+			if (valuesp != NULL) {
+				word = MCDI_OUT_WORD(req,
+				    POLL_BIST_OUT_SFT9001_CABLE_STATUS_C);
+				valuesp[EFX_BIST_PHY_CABLE_STATUS_C] =
+				    siena_phy_sft9001_bist_status(word);
+			}
+			value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_C);
+		}
+
+		if (count > EFX_BIST_PHY_CABLE_STATUS_D) {
+			if (valuesp != NULL) {
+				word = MCDI_OUT_WORD(req,
+				    POLL_BIST_OUT_SFT9001_CABLE_STATUS_D);
+				valuesp[EFX_BIST_PHY_CABLE_STATUS_D] =
+				    siena_phy_sft9001_bist_status(word);
+			}
+			value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_D);
+		}
+
+	} else if (result == MC_CMD_POLL_BIST_FAILED &&
+		    encp->enc_phy_type == EFX_PHY_QLX111V &&
+		    req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MRSFP_LEN &&
+		    count > EFX_BIST_FAULT_CODE) {
+		if (valuesp != NULL)
+			valuesp[EFX_BIST_FAULT_CODE] =
+			    MCDI_OUT_DWORD(req, POLL_BIST_OUT_MRSFP_TEST);
+		value_mask |= 1 << EFX_BIST_FAULT_CODE;
+	}
+
+	if (value_maskp != NULL)
+		*value_maskp = value_mask;
+
+	EFSYS_ASSERT(resultp != NULL);
+	if (result == MC_CMD_POLL_BIST_RUNNING)
+		*resultp = EFX_BIST_RESULT_RUNNING;
+	else if (result == MC_CMD_POLL_BIST_PASSED)
+		*resultp = EFX_BIST_RESULT_PASSED;
+	else
+		*resultp = EFX_BIST_RESULT_FAILED;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+			void
+siena_phy_bist_stop(
+	__in		efx_nic_t *enp,
+	__in		efx_bist_type_t type)
+{
+	/* There is no way to stop BIST on Siena */
+	_NOTE(ARGUNUSED(enp, type))
+}
+
+#endif	/* EFSYS_OPT_BIST */
+
 #endif	/* EFSYS_OPT_SIENA */
-- 
2.5.5

^ permalink raw reply related

* [PATCH 11/56] net/sfc: import libefx SFN8xxx family support
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

SFN8xxx is the second family based on EF10 architecture.

It has few differences from SFN7xxx adapters family.

EFSYS_OPT_MEDFORD should be enabled to use it.

>From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/base/ef10_impl.h    |   6 +-
 drivers/net/sfc/efx/base/efx_check.h    |   2 +
 drivers/net/sfc/efx/base/efx_ev.c       |   6 +
 drivers/net/sfc/efx/base/efx_filter.c   |   6 +
 drivers/net/sfc/efx/base/efx_impl.h     |   4 +
 drivers/net/sfc/efx/base/efx_intr.c     |   6 +
 drivers/net/sfc/efx/base/efx_mac.c      |   7 +
 drivers/net/sfc/efx/base/efx_mcdi.c     |   6 +
 drivers/net/sfc/efx/base/efx_nic.c      |  54 +++++
 drivers/net/sfc/efx/base/efx_phy.c      |   5 +
 drivers/net/sfc/efx/base/efx_rx.c       |   6 +
 drivers/net/sfc/efx/base/efx_tx.c       |  29 +++
 drivers/net/sfc/efx/base/medford_impl.h |  67 ++++++
 drivers/net/sfc/efx/base/medford_nic.c  | 398 ++++++++++++++++++++++++++++++++
 14 files changed, 601 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/sfc/efx/base/medford_impl.h
 create mode 100644 drivers/net/sfc/efx/base/medford_nic.c

diff --git a/drivers/net/sfc/efx/base/ef10_impl.h b/drivers/net/sfc/efx/base/ef10_impl.h
index 3183210..15d12d2 100644
--- a/drivers/net/sfc/efx/base/ef10_impl.h
+++ b/drivers/net/sfc/efx/base/ef10_impl.h
@@ -35,8 +35,12 @@
 extern "C" {
 #endif
 
-#if   EFSYS_OPT_HUNTINGTON
+#if (EFSYS_OPT_HUNTINGTON && EFSYS_OPT_MEDFORD)
+#define	EF10_MAX_PIOBUF_NBUFS	MAX(HUNT_PIOBUF_NBUFS, MEDFORD_PIOBUF_NBUFS)
+#elif EFSYS_OPT_HUNTINGTON
 #define	EF10_MAX_PIOBUF_NBUFS	HUNT_PIOBUF_NBUFS
+#elif EFSYS_OPT_MEDFORD
+#define	EF10_MAX_PIOBUF_NBUFS	MEDFORD_PIOBUF_NBUFS
 #endif
 
 /*
diff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h
index 63c809c..ef88645 100644
--- a/drivers/net/sfc/efx/base/efx_check.h
+++ b/drivers/net/sfc/efx/base/efx_check.h
@@ -209,7 +209,9 @@
 
 #if EFSYS_OPT_ALLOW_UNCONFIGURED_NIC
 /* Support adapters with missing static config (for factory use only) */
+# if !EFSYS_OPT_MEDFORD
 #  error "ALLOW_UNCONFIGURED_NIC requires MEDFORD"
+# endif
 #endif /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */
 
 #endif /* _SYS_EFX_CHECK_H */
diff --git a/drivers/net/sfc/efx/base/efx_ev.c b/drivers/net/sfc/efx/base/efx_ev.c
index 65094c1..8cb78be 100644
--- a/drivers/net/sfc/efx/base/efx_ev.c
+++ b/drivers/net/sfc/efx/base/efx_ev.c
@@ -134,6 +134,12 @@ efx_ev_init(
 		break;
 #endif /* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		eevop = &__efx_ev_ef10_ops;
+		break;
+#endif /* EFSYS_OPT_MEDFORD */
+
 	default:
 		EFSYS_ASSERT(0);
 		rc = ENOTSUP;
diff --git a/drivers/net/sfc/efx/base/efx_filter.c b/drivers/net/sfc/efx/base/efx_filter.c
index 5c4b74d..192f6f5 100644
--- a/drivers/net/sfc/efx/base/efx_filter.c
+++ b/drivers/net/sfc/efx/base/efx_filter.c
@@ -165,6 +165,12 @@ efx_filter_init(
 		break;
 #endif /* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		efop = &__efx_filter_ef10_ops;
+		break;
+#endif /* EFSYS_OPT_MEDFORD */
+
 	default:
 		EFSYS_ASSERT(0);
 		rc = ENOTSUP;
diff --git a/drivers/net/sfc/efx/base/efx_impl.h b/drivers/net/sfc/efx/base/efx_impl.h
index 10ab36b..97057e4 100644
--- a/drivers/net/sfc/efx/base/efx_impl.h
+++ b/drivers/net/sfc/efx/base/efx_impl.h
@@ -49,6 +49,10 @@
 #include "hunt_impl.h"
 #endif	/* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+#include "medford_impl.h"
+#endif	/* EFSYS_OPT_MEDFORD */
+
 #if (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)
 #include "ef10_impl.h"
 #endif	/* (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD) */
diff --git a/drivers/net/sfc/efx/base/efx_intr.c b/drivers/net/sfc/efx/base/efx_intr.c
index 50cf388..f0422d5 100644
--- a/drivers/net/sfc/efx/base/efx_intr.c
+++ b/drivers/net/sfc/efx/base/efx_intr.c
@@ -150,6 +150,12 @@ efx_intr_init(
 		break;
 #endif	/* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		eiop = &__efx_intr_ef10_ops;
+		break;
+#endif	/* EFSYS_OPT_MEDFORD */
+
 	default:
 		EFSYS_ASSERT(B_FALSE);
 		rc = ENOTSUP;
diff --git a/drivers/net/sfc/efx/base/efx_mac.c b/drivers/net/sfc/efx/base/efx_mac.c
index 1d50128..c10c79a 100644
--- a/drivers/net/sfc/efx/base/efx_mac.c
+++ b/drivers/net/sfc/efx/base/efx_mac.c
@@ -516,6 +516,13 @@ efx_mac_select(
 		break;
 #endif /* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		emop = &__efx_ef10_mac_ops;
+		type = EFX_MAC_MEDFORD;
+		break;
+#endif /* EFSYS_OPT_MEDFORD */
+
 	default:
 		rc = EINVAL;
 		goto fail1;
diff --git a/drivers/net/sfc/efx/base/efx_mcdi.c b/drivers/net/sfc/efx/base/efx_mcdi.c
index 4ad6da9..ef4e7ea 100644
--- a/drivers/net/sfc/efx/base/efx_mcdi.c
+++ b/drivers/net/sfc/efx/base/efx_mcdi.c
@@ -110,6 +110,12 @@ efx_mcdi_init(
 		break;
 #endif	/* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		emcop = &__efx_mcdi_ef10_ops;
+		break;
+#endif	/* EFSYS_OPT_MEDFORD */
+
 	default:
 		EFSYS_ASSERT(0);
 		rc = ENOTSUP;
diff --git a/drivers/net/sfc/efx/base/efx_nic.c b/drivers/net/sfc/efx/base/efx_nic.c
index 8db2625..5cc2910 100644
--- a/drivers/net/sfc/efx/base/efx_nic.c
+++ b/drivers/net/sfc/efx/base/efx_nic.c
@@ -74,6 +74,24 @@ efx_family(
 			return (0);
 #endif /* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+		case EFX_PCI_DEVID_MEDFORD_PF_UNINIT:
+			/*
+			 * Hardware default for PF0 of uninitialised Medford.
+			 * manftest must be able to cope with this device id.
+			 */
+			*efp = EFX_FAMILY_MEDFORD;
+			return (0);
+
+		case EFX_PCI_DEVID_MEDFORD:
+			*efp = EFX_FAMILY_MEDFORD;
+			return (0);
+
+		case EFX_PCI_DEVID_MEDFORD_VF:
+			*efp = EFX_FAMILY_MEDFORD;
+			return (0);
+#endif /* EFSYS_OPT_MEDFORD */
+
 		case EFX_PCI_DEVID_FALCON:	/* Obsolete, not supported */
 		default:
 			break;
@@ -188,6 +206,22 @@ static const efx_nic_ops_t	__efx_nic_hunt_ops = {
 
 #endif	/* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+
+static const efx_nic_ops_t	__efx_nic_medford_ops = {
+	ef10_nic_probe,			/* eno_probe */
+	medford_board_cfg,		/* eno_board_cfg */
+	ef10_nic_set_drv_limits,	/* eno_set_drv_limits */
+	ef10_nic_reset,			/* eno_reset */
+	ef10_nic_init,			/* eno_init */
+	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
+	ef10_nic_get_bar_region,	/* eno_get_bar_region */
+	ef10_nic_fini,			/* eno_fini */
+	ef10_nic_unprobe,		/* eno_unprobe */
+};
+
+#endif	/* EFSYS_OPT_MEDFORD */
+
 
 	__checkReturn	efx_rc_t
 efx_nic_create(
@@ -246,6 +280,26 @@ efx_nic_create(
 		break;
 #endif	/* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		enp->en_enop = &__efx_nic_medford_ops;
+		/*
+		 * FW_ASSISTED_TSO omitted as Medford only supports firmware
+		 * assisted TSO version 2, not the v1 scheme used on Huntington.
+		 */
+		enp->en_features =
+		    EFX_FEATURE_IPV6 |
+		    EFX_FEATURE_LINK_EVENTS |
+		    EFX_FEATURE_PERIODIC_MAC_STATS |
+		    EFX_FEATURE_MCDI |
+		    EFX_FEATURE_MAC_HEADER_FILTERS |
+		    EFX_FEATURE_MCDI_DMA |
+		    EFX_FEATURE_PIO_BUFFERS |
+		    EFX_FEATURE_FW_ASSISTED_TSO_V2 |
+		    EFX_FEATURE_PACKED_STREAM;
+		break;
+#endif	/* EFSYS_OPT_MEDFORD */
+
 	default:
 		rc = ENOTSUP;
 		goto fail2;
diff --git a/drivers/net/sfc/efx/base/efx_phy.c b/drivers/net/sfc/efx/base/efx_phy.c
index b663cf8..e7e915e 100644
--- a/drivers/net/sfc/efx/base/efx_phy.c
+++ b/drivers/net/sfc/efx/base/efx_phy.c
@@ -78,6 +78,11 @@ efx_phy_probe(
 		epop = &__efx_phy_ef10_ops;
 		break;
 #endif	/* EFSYS_OPT_HUNTINGTON */
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		epop = &__efx_phy_ef10_ops;
+		break;
+#endif	/* EFSYS_OPT_MEDFORD */
 	default:
 		rc = ENOTSUP;
 		goto fail1;
diff --git a/drivers/net/sfc/efx/base/efx_rx.c b/drivers/net/sfc/efx/base/efx_rx.c
index cf6ee3a..a2f9789 100644
--- a/drivers/net/sfc/efx/base/efx_rx.c
+++ b/drivers/net/sfc/efx/base/efx_rx.c
@@ -152,6 +152,12 @@ efx_rx_init(
 		break;
 #endif /* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		erxop = &__efx_rx_ef10_ops;
+		break;
+#endif /* EFSYS_OPT_MEDFORD */
+
 	default:
 		EFSYS_ASSERT(0);
 		rc = ENOTSUP;
diff --git a/drivers/net/sfc/efx/base/efx_tx.c b/drivers/net/sfc/efx/base/efx_tx.c
index ed66695..16834af 100644
--- a/drivers/net/sfc/efx/base/efx_tx.c
+++ b/drivers/net/sfc/efx/base/efx_tx.c
@@ -152,6 +152,29 @@ static const efx_tx_ops_t	__efx_tx_hunt_ops = {
 };
 #endif /* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+static const efx_tx_ops_t	__efx_tx_medford_ops = {
+	ef10_tx_init,				/* etxo_init */
+	ef10_tx_fini,				/* etxo_fini */
+	ef10_tx_qcreate,			/* etxo_qcreate */
+	ef10_tx_qdestroy,			/* etxo_qdestroy */
+	ef10_tx_qpost,				/* etxo_qpost */
+	ef10_tx_qpush,				/* etxo_qpush */
+	ef10_tx_qpace,				/* etxo_qpace */
+	ef10_tx_qflush,				/* etxo_qflush */
+	ef10_tx_qenable,			/* etxo_qenable */
+	ef10_tx_qpio_enable,			/* etxo_qpio_enable */
+	ef10_tx_qpio_disable,			/* etxo_qpio_disable */
+	ef10_tx_qpio_write,			/* etxo_qpio_write */
+	ef10_tx_qpio_post,			/* etxo_qpio_post */
+	ef10_tx_qdesc_post,			/* etxo_qdesc_post */
+	ef10_tx_qdesc_dma_create,		/* etxo_qdesc_dma_create */
+	NULL,					/* etxo_qdesc_tso_create */
+	ef10_tx_qdesc_tso2_create,		/* etxo_qdesc_tso2_create */
+	ef10_tx_qdesc_vlantci_create,		/* etxo_qdesc_vlantci_create */
+};
+#endif /* EFSYS_OPT_MEDFORD */
+
 	__checkReturn	efx_rc_t
 efx_tx_init(
 	__in		efx_nic_t *enp)
@@ -185,6 +208,12 @@ efx_tx_init(
 		break;
 #endif /* EFSYS_OPT_HUNTINGTON */
 
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		etxop = &__efx_tx_medford_ops;
+		break;
+#endif /* EFSYS_OPT_MEDFORD */
+
 	default:
 		EFSYS_ASSERT(0);
 		rc = ENOTSUP;
diff --git a/drivers/net/sfc/efx/base/medford_impl.h b/drivers/net/sfc/efx/base/medford_impl.h
new file mode 100644
index 0000000..de2f5cf
--- /dev/null
+++ b/drivers/net/sfc/efx/base/medford_impl.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#ifndef	_SYS_MEDFORD_IMPL_H
+#define	_SYS_MEDFORD_IMPL_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* Alignment requirement for value written to RX WPTR:
+ *  the WPTR must be aligned to an 8 descriptor boundary
+ *
+ * FIXME: Is this the same on Medford as Huntington?
+ */
+#define	MEDFORD_RX_WPTR_ALIGN	8
+
+
+
+#ifndef	ER_EZ_TX_PIOBUF_SIZE
+#define	ER_EZ_TX_PIOBUF_SIZE	4096
+#endif
+
+
+#define	MEDFORD_PIOBUF_NBUFS	(16)
+#define	MEDFORD_PIOBUF_SIZE	(ER_EZ_TX_PIOBUF_SIZE)
+
+#define	MEDFORD_MIN_PIO_ALLOC_SIZE	(MEDFORD_PIOBUF_SIZE / 32)
+
+
+extern	__checkReturn	efx_rc_t
+medford_board_cfg(
+	__in		efx_nic_t *enp);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_MEDFORD_IMPL_H */
diff --git a/drivers/net/sfc/efx/base/medford_nic.c b/drivers/net/sfc/efx/base/medford_nic.c
new file mode 100644
index 0000000..6ad68c6
--- /dev/null
+++ b/drivers/net/sfc/efx/base/medford_nic.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2015-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_MEDFORD
+
+static	__checkReturn	efx_rc_t
+efx_mcdi_get_rxdp_config(
+	__in		efx_nic_t *enp,
+	__out		uint32_t *end_paddingp)
+{
+	efx_mcdi_req_t req;
+	uint8_t payload[MAX(MC_CMD_GET_RXDP_CONFIG_IN_LEN,
+			    MC_CMD_GET_RXDP_CONFIG_OUT_LEN)];
+	uint32_t end_padding;
+	efx_rc_t rc;
+
+	memset(payload, 0, sizeof (payload));
+	req.emr_cmd = MC_CMD_GET_RXDP_CONFIG;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_GET_RXDP_CONFIG_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_GET_RXDP_CONFIG_OUT_LEN;
+
+	efx_mcdi_execute(enp, &req);
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail1;
+	}
+
+	if (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA,
+				    GET_RXDP_CONFIG_OUT_PAD_HOST_DMA) == 0) {
+		/* RX DMA end padding is disabled */
+		end_padding = 0;
+	} else {
+		switch (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA,
+					    GET_RXDP_CONFIG_OUT_PAD_HOST_LEN)) {
+		case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_64:
+			end_padding = 64;
+			break;
+		case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_128:
+			end_padding = 128;
+			break;
+		case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_256:
+			end_padding = 256;
+			break;
+		default:
+			rc = ENOTSUP;
+			goto fail2;
+		}
+	}
+
+	*end_paddingp = end_padding;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+static	__checkReturn	efx_rc_t
+medford_nic_get_required_pcie_bandwidth(
+	__in		efx_nic_t *enp,
+	__out		uint32_t *bandwidth_mbpsp)
+{
+	uint32_t port_modes;
+	uint32_t current_mode;
+	uint32_t bandwidth;
+	efx_rc_t rc;
+
+	if ((rc = efx_mcdi_get_port_modes(enp, &port_modes,
+				    &current_mode)) != 0) {
+		/* No port mode info available. */
+		bandwidth = 0;
+		goto out;
+	}
+
+	if ((rc = ef10_nic_get_port_mode_bandwidth(current_mode,
+						    &bandwidth)) != 0)
+		goto fail1;
+
+out:
+	*bandwidth_mbpsp = bandwidth;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+medford_board_cfg(
+	__in		efx_nic_t *enp)
+{
+	efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+	uint8_t mac_addr[6] = { 0 };
+	uint32_t board_type = 0;
+	ef10_link_state_t els;
+	efx_port_t *epp = &(enp->en_port);
+	uint32_t port;
+	uint32_t pf;
+	uint32_t vf;
+	uint32_t mask;
+	uint32_t sysclk, dpcpu_clk;
+	uint32_t base, nvec;
+	uint32_t end_padding;
+	uint32_t bandwidth;
+	efx_rc_t rc;
+
+	/*
+	 * FIXME: Likely to be incomplete and incorrect.
+	 * Parts of this should be shared with Huntington.
+	 */
+
+	if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0)
+		goto fail1;
+
+	/*
+	 * NOTE: The MCDI protocol numbers ports from zero.
+	 * The common code MCDI interface numbers ports from one.
+	 */
+	emip->emi_port = port + 1;
+
+	if ((rc = ef10_external_port_mapping(enp, port,
+		    &encp->enc_external_port)) != 0)
+		goto fail2;
+
+	/*
+	 * Get PCIe function number from firmware (used for
+	 * per-function privilege and dynamic config info).
+	 *  - PCIe PF: pf = PF number, vf = 0xffff.
+	 *  - PCIe VF: pf = parent PF, vf = VF number.
+	 */
+	if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0)
+		goto fail3;
+
+	encp->enc_pf = pf;
+	encp->enc_vf = vf;
+
+	/* MAC address for this function */
+	if (EFX_PCI_FUNCTION_IS_PF(encp)) {
+		rc = efx_mcdi_get_mac_address_pf(enp, mac_addr);
+#if EFSYS_OPT_ALLOW_UNCONFIGURED_NIC
+		/* Disable static config checking for Medford NICs, ONLY
+		 * for manufacturing test and setup at the factory, to
+		 * allow the static config to be installed.
+		 */
+#else /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */
+		if ((rc == 0) && (mac_addr[0] & 0x02)) {
+			/*
+			 * If the static config does not include a global MAC
+			 * address pool then the board may return a locally
+			 * administered MAC address (this should only happen on
+			 * incorrectly programmed boards).
+			 */
+			rc = EINVAL;
+		}
+#endif /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */
+	} else {
+		rc = efx_mcdi_get_mac_address_vf(enp, mac_addr);
+	}
+	if (rc != 0)
+		goto fail4;
+
+	EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
+
+	/* Board configuration */
+	rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL);
+	if (rc != 0) {
+		/* Unprivileged functions may not be able to read board cfg */
+		if (rc == EACCES)
+			board_type = 0;
+		else
+			goto fail5;
+	}
+
+	encp->enc_board_type = board_type;
+	encp->enc_clk_mult = 1; /* not used for Medford */
+
+	/* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
+	if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
+		goto fail6;
+
+	/* Obtain the default PHY advertised capabilities */
+	if ((rc = ef10_phy_get_link(enp, &els)) != 0)
+		goto fail7;
+	epp->ep_default_adv_cap_mask = els.els_adv_cap_mask;
+	epp->ep_adv_cap_mask = els.els_adv_cap_mask;
+
+	/*
+	 * Enable firmware workarounds for hardware errata.
+	 * Expected responses are:
+	 *  - 0 (zero):
+	 *	Success: workaround enabled or disabled as requested.
+	 *  - MC_CMD_ERR_ENOSYS (reported as ENOTSUP):
+	 *	Firmware does not support the MC_CMD_WORKAROUND request.
+	 *	(assume that the workaround is not supported).
+	 *  - MC_CMD_ERR_ENOENT (reported as ENOENT):
+	 *	Firmware does not support the requested workaround.
+	 *  - MC_CMD_ERR_EPERM  (reported as EACCES):
+	 *	Unprivileged function cannot enable/disable workarounds.
+	 *
+	 * See efx_mcdi_request_errcode() for MCDI error translations.
+	 */
+
+
+	if (EFX_PCI_FUNCTION_IS_VF(encp)) {
+		/*
+		 * Interrupt testing does not work for VFs. See bug50084.
+		 * FIXME: Does this still  apply to Medford?
+		 */
+		encp->enc_bug41750_workaround = B_TRUE;
+	}
+
+	/* Chained multicast is always enabled on Medford */
+	encp->enc_bug26807_workaround = B_TRUE;
+
+	/*
+	 * If the bug61265 workaround is enabled, then interrupt holdoff timers
+	 * cannot be controlled by timer table writes, so MCDI must be used
+	 * (timer table writes can still be used for wakeup timers).
+	 */
+	rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG61265, B_TRUE,
+	    NULL);
+	if ((rc == 0) || (rc == EACCES))
+		encp->enc_bug61265_workaround = B_TRUE;
+	else if ((rc == ENOTSUP) || (rc == ENOENT))
+		encp->enc_bug61265_workaround = B_FALSE;
+	else
+		goto fail8;
+
+	/* Get clock frequencies (in MHz). */
+	if ((rc = efx_mcdi_get_clock(enp, &sysclk, &dpcpu_clk)) != 0)
+		goto fail9;
+
+	/*
+	 * The Medford timer quantum is 1536 dpcpu_clk cycles, documented for
+	 * the EV_TMR_VAL field of EV_TIMER_TBL. Scale for MHz and ns units.
+	 */
+	encp->enc_evq_timer_quantum_ns = 1536000UL / dpcpu_clk; /* 1536 cycles */
+	encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
+		    FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
+
+	/* Check capabilities of running datapath firmware */
+	if ((rc = ef10_get_datapath_caps(enp)) != 0)
+		goto fail10;
+
+	/* Alignment for receive packet DMA buffers */
+	encp->enc_rx_buf_align_start = 1;
+
+	/* Get the RX DMA end padding alignment configuration */
+	if ((rc = efx_mcdi_get_rxdp_config(enp, &end_padding)) != 0) {
+		if (rc != EACCES)
+			goto fail11;
+
+		/* Assume largest tail padding size supported by hardware */
+		end_padding = 256;
+	}
+	encp->enc_rx_buf_align_end = end_padding;
+
+	/* Alignment for WPTR updates */
+	encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN;
+
+	/*
+	 * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
+	 * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
+	 * resources (allocated to this PCIe function), which is zero until
+	 * after we have allocated VIs.
+	 */
+	encp->enc_evq_limit = 1024;
+	encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
+	encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
+
+	/*
+	 * The maximum supported transmit queue size is 2048. TXQs with 4096
+	 * descriptors are not supported as the top bit is used for vfifo
+	 * stuffing.
+	 */
+	encp->enc_txq_max_ndescs = 2048;
+
+	encp->enc_buftbl_limit = 0xFFFFFFFF;
+
+	encp->enc_piobuf_limit = MEDFORD_PIOBUF_NBUFS;
+	encp->enc_piobuf_size = MEDFORD_PIOBUF_SIZE;
+	encp->enc_piobuf_min_alloc_size = MEDFORD_MIN_PIO_ALLOC_SIZE;
+
+	/*
+	 * Get the current privilege mask. Note that this may be modified
+	 * dynamically, so this value is informational only. DO NOT use
+	 * the privilege mask to check for sufficient privileges, as that
+	 * can result in time-of-check/time-of-use bugs.
+	 */
+	if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0)
+		goto fail12;
+	encp->enc_privilege_mask = mask;
+
+	/* Get interrupt vector limits */
+	if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) {
+		if (EFX_PCI_FUNCTION_IS_PF(encp))
+			goto fail13;
+
+		/* Ignore error (cannot query vector limits from a VF). */
+		base = 0;
+		nvec = 1024;
+	}
+	encp->enc_intr_vec_base = base;
+	encp->enc_intr_limit = nvec;
+
+	/*
+	 * Maximum number of bytes into the frame the TCP header can start for
+	 * firmware assisted TSO to work.
+	 */
+	encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT;
+
+	/*
+	 * Medford stores a single global copy of VPD, not per-PF as on
+	 * Huntington.
+	 */
+	encp->enc_vpd_is_global = B_TRUE;
+
+	rc = medford_nic_get_required_pcie_bandwidth(enp, &bandwidth);
+	if (rc != 0)
+		goto fail14;
+	encp->enc_required_pcie_bandwidth_mbps = bandwidth;
+	encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN3;
+
+	return (0);
+
+fail14:
+	EFSYS_PROBE(fail14);
+fail13:
+	EFSYS_PROBE(fail13);
+fail12:
+	EFSYS_PROBE(fail12);
+fail11:
+	EFSYS_PROBE(fail11);
+fail10:
+	EFSYS_PROBE(fail10);
+fail9:
+	EFSYS_PROBE(fail9);
+fail8:
+	EFSYS_PROBE(fail8);
+fail7:
+	EFSYS_PROBE(fail7);
+fail6:
+	EFSYS_PROBE(fail6);
+fail5:
+	EFSYS_PROBE(fail5);
+fail4:
+	EFSYS_PROBE(fail4);
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+#endif	/* EFSYS_OPT_MEDFORD */
-- 
2.5.5

^ permalink raw reply related

* [PATCH 01/56] net/sfc: libefx-based PMD stub sufficient to build and init
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

The PMD is put into the sfc/efx subdirectory to have a place for
the second PMD and library shared by both.

Enable the PMD by default on supported configuratons.

Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 MAINTAINERS                                     |   6 ++
 config/common_base                              |   6 ++
 config/defconfig_arm-armv7a-linuxapp-gcc        |   1 +
 config/defconfig_arm64-armv8a-linuxapp-gcc      |   1 +
 config/defconfig_i686-native-linuxapp-gcc       |   5 +
 config/defconfig_i686-native-linuxapp-icc       |   5 +
 config/defconfig_ppc_64-power8-linuxapp-gcc     |   1 +
 config/defconfig_tile-tilegx-linuxapp-gcc       |   1 +
 config/defconfig_x86_64-native-linuxapp-icc     |   5 +
 config/defconfig_x86_x32-native-linuxapp-gcc    |   5 +
 doc/guides/nics/features/sfc_efx.ini            |  10 ++
 doc/guides/nics/index.rst                       |   1 +
 doc/guides/nics/sfc_efx.rst                     | 109 +++++++++++++++++++++
 drivers/net/Makefile                            |   1 +
 drivers/net/sfc/Makefile                        |  33 +++++++
 drivers/net/sfc/efx/Makefile                    |  81 ++++++++++++++++
 drivers/net/sfc/efx/rte_pmd_sfc_efx_version.map |   4 +
 drivers/net/sfc/efx/sfc.h                       |  53 +++++++++++
 drivers/net/sfc/efx/sfc_debug.h                 |  45 +++++++++
 drivers/net/sfc/efx/sfc_ethdev.c                | 120 ++++++++++++++++++++++++
 drivers/net/sfc/efx/sfc_kvargs.c                | 108 +++++++++++++++++++++
 drivers/net/sfc/efx/sfc_kvargs.h                |  58 ++++++++++++
 drivers/net/sfc/efx/sfc_log.h                   |  72 ++++++++++++++
 mk/rte.app.mk                                   |   1 +
 24 files changed, 732 insertions(+)
 create mode 100644 doc/guides/nics/features/sfc_efx.ini
 create mode 100644 doc/guides/nics/sfc_efx.rst
 create mode 100644 drivers/net/sfc/Makefile
 create mode 100644 drivers/net/sfc/efx/Makefile
 create mode 100644 drivers/net/sfc/efx/rte_pmd_sfc_efx_version.map
 create mode 100644 drivers/net/sfc/efx/sfc.h
 create mode 100644 drivers/net/sfc/efx/sfc_debug.h
 create mode 100644 drivers/net/sfc/efx/sfc_ethdev.c
 create mode 100644 drivers/net/sfc/efx/sfc_kvargs.c
 create mode 100644 drivers/net/sfc/efx/sfc_kvargs.h
 create mode 100644 drivers/net/sfc/efx/sfc_log.h

diff --git a/MAINTAINERS b/MAINTAINERS
index d6bb8f8..63fab48 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -364,6 +364,12 @@ M: Sony Chacko <sony.chacko@qlogic.com>
 F: drivers/net/qede/
 F: doc/guides/nics/qede.rst
 
+Solarflare sfc_efx
+M: Andrew Rybchenko <arybchenko@solarflare.com>
+F: drivers/net/sfc/
+F: doc/guides/nics/sfc_efx.rst
+F: doc/guides/nics/features/sfc_efx.ini
+
 RedHat virtio
 M: Huawei Xie <huawei.xie@intel.com>
 M: Yuanhan Liu <yuanhan.liu@linux.intel.com>
diff --git a/config/common_base b/config/common_base
index 4bff83a..1eb8eea 100644
--- a/config/common_base
+++ b/config/common_base
@@ -338,6 +338,12 @@ CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
 
 #
+# Compile burst-oriented Solarflare libefx-based PMD
+#
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=y
+CONFIG_RTE_LIBRTE_SFC_EFX_DEBUG=n
+
+#
 # Compile null PMD
 #
 CONFIG_RTE_LIBRTE_PMD_NULL=y
diff --git a/config/defconfig_arm-armv7a-linuxapp-gcc b/config/defconfig_arm-armv7a-linuxapp-gcc
index bde6acd..d99bd0f 100644
--- a/config/defconfig_arm-armv7a-linuxapp-gcc
+++ b/config/defconfig_arm-armv7a-linuxapp-gcc
@@ -75,3 +75,4 @@ CONFIG_RTE_LIBRTE_VMXNET3_PMD=n
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
 CONFIG_RTE_LIBRTE_PMD_BNX2X=n
 CONFIG_RTE_LIBRTE_QEDE_PMD=n
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
diff --git a/config/defconfig_arm64-armv8a-linuxapp-gcc b/config/defconfig_arm64-armv8a-linuxapp-gcc
index 6321884..aef5431 100644
--- a/config/defconfig_arm64-armv8a-linuxapp-gcc
+++ b/config/defconfig_arm64-armv8a-linuxapp-gcc
@@ -45,5 +45,6 @@ CONFIG_RTE_TOOLCHAIN_GCC=y
 CONFIG_RTE_EAL_IGB_UIO=n
 
 CONFIG_RTE_LIBRTE_FM10K_PMD=n
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
 
 CONFIG_RTE_SCHED_VECTOR=n
diff --git a/config/defconfig_i686-native-linuxapp-gcc b/config/defconfig_i686-native-linuxapp-gcc
index 576d543..5875ecd 100644
--- a/config/defconfig_i686-native-linuxapp-gcc
+++ b/config/defconfig_i686-native-linuxapp-gcc
@@ -67,6 +67,11 @@ CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n
 CONFIG_RTE_LIBRTE_PMD_KASUMI=n
 
 #
+# Solarflare PMD is not supported on 32-bit
+#
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
+
+#
 # ZUC PMD is not supported on 32-bit
 #
 CONFIG_RTE_LIBRTE_PMD_ZUC=n
diff --git a/config/defconfig_i686-native-linuxapp-icc b/config/defconfig_i686-native-linuxapp-icc
index 6c902a3..7be476b 100644
--- a/config/defconfig_i686-native-linuxapp-icc
+++ b/config/defconfig_i686-native-linuxapp-icc
@@ -67,6 +67,11 @@ CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n
 CONFIG_RTE_LIBRTE_PMD_KASUMI=n
 
 #
+# Solarflare PMD is not supported on 32-bit
+#
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
+
+#
 # ZUC PMD is not supported on 32-bit
 #
 CONFIG_RTE_LIBRTE_PMD_ZUC=n
diff --git a/config/defconfig_ppc_64-power8-linuxapp-gcc b/config/defconfig_ppc_64-power8-linuxapp-gcc
index f953e61..35f7fb6 100644
--- a/config/defconfig_ppc_64-power8-linuxapp-gcc
+++ b/config/defconfig_ppc_64-power8-linuxapp-gcc
@@ -55,4 +55,5 @@ CONFIG_RTE_LIBRTE_VMXNET3_PMD=n
 CONFIG_RTE_LIBRTE_PMD_BOND=n
 CONFIG_RTE_LIBRTE_ENIC_PMD=n
 CONFIG_RTE_LIBRTE_FM10K_PMD=n
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
 
diff --git a/config/defconfig_tile-tilegx-linuxapp-gcc b/config/defconfig_tile-tilegx-linuxapp-gcc
index 5a50793..44add62 100644
--- a/config/defconfig_tile-tilegx-linuxapp-gcc
+++ b/config/defconfig_tile-tilegx-linuxapp-gcc
@@ -71,3 +71,4 @@ CONFIG_RTE_LIBRTE_PORT=n
 CONFIG_RTE_LIBRTE_TABLE=n
 CONFIG_RTE_LIBRTE_PIPELINE=n
 CONFIG_RTE_LIBRTE_CXGBE_PMD=n
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
diff --git a/config/defconfig_x86_64-native-linuxapp-icc b/config/defconfig_x86_64-native-linuxapp-icc
index bfa8a3d..872d1a1 100644
--- a/config/defconfig_x86_64-native-linuxapp-icc
+++ b/config/defconfig_x86_64-native-linuxapp-icc
@@ -41,3 +41,8 @@ CONFIG_RTE_ARCH_64=y
 
 CONFIG_RTE_TOOLCHAIN="icc"
 CONFIG_RTE_TOOLCHAIN_ICC=y
+
+#
+# Solarflare PMD build is not supported using icc toolchain
+#
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
diff --git a/config/defconfig_x86_x32-native-linuxapp-gcc b/config/defconfig_x86_x32-native-linuxapp-gcc
index 0c26857..3e55c5c 100644
--- a/config/defconfig_x86_x32-native-linuxapp-gcc
+++ b/config/defconfig_x86_x32-native-linuxapp-gcc
@@ -45,3 +45,8 @@ CONFIG_RTE_TOOLCHAIN_GCC=y
 # KNI is not supported on 32-bit
 #
 CONFIG_RTE_LIBRTE_KNI=n
+
+#
+# Solarflare PMD is not supported on 32-bit
+#
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
new file mode 100644
index 0000000..59eb830
--- /dev/null
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -0,0 +1,10 @@
+;
+; Supported features of the 'sfc_efx' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+BSD nic_uio          = Y
+Linux UIO            = Y
+Linux VFIO           = Y
+x86-64               = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 92d56a5..5ea8b1a 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -50,6 +50,7 @@ Network Interface Controller Drivers
     mlx5
     nfp
     qede
+    sfc_efx
     szedata2
     thunderx
     virtio
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
new file mode 100644
index 0000000..2eebcd7
--- /dev/null
+++ b/doc/guides/nics/sfc_efx.rst
@@ -0,0 +1,109 @@
+..  BSD LICENSE
+    Copyright (c) 2016 Solarflare Communications Inc.
+    All rights reserved.
+
+    This software was jointly developed between OKTET Labs (under contract
+    for Solarflare) and Solarflare Communications, Inc.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice,
+       this list of conditions and the following disclaimer in the documentation
+       and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+    OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+    EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Solarflare libefx-based Poll Mode Driver
+========================================
+
+The SFC EFX PMD (**librte_pmd_sfc_efx**) provides poll mode driver support
+for **Solarflare SFN7xxx and SFN8xxx** family of 10/40 Gbps adapters.
+SFC EFX PMD has support for the latest Linux and FreeBSD operating systems.
+
+More information can be found at `Solarflare Communications website
+<http://solarflare.com>`_.
+
+
+Supported NICs
+--------------
+
+- Solarflare Flareon [Ultra] Server Adapters:
+
+   - Solarflare SFN8522 Dual Port SFP+ Server Adapter
+
+   - Solarflare SFN8542 Dual Port QSFP+ Server Adapter
+
+   - Solarflare SFN7002F Dual Port SFP+ Server Adapter
+
+   - Solarflare SFN7004F Quad Port SFP+ Server Adapter
+
+   - Solarflare SFN7042Q Dual Port QSFP+ Server Adapter
+
+   - Solarflare SFN7122F Dual Port SFP+ Server Adapter
+
+   - Solarflare SFN7124F Quad Port SFP+ Server Adapter
+
+   - Solarflare SFN7142Q Dual Port QSFP+ Server Adapter
+
+   - Solarflare SFN7322F Precision Time Synchronization Server Adapter
+
+
+Prerequisites
+-------------
+
+- Requires firmware version:
+
+   - SFN7xxx: **4.7.1.1001** or higher
+
+   - SFN8xxx: **6.0.2.1004** or higher
+
+Visit `Solarflare Support Downloads <https://support.solarflare.com>`_ to get
+Solarflare Utilities (either Linux or FreeBSD) with the latest firmware.
+Follow instructions from Solarflare Server Adapter User's Guide to
+update firmware and configure the adapter.
+
+
+Pre-Installation Configuration
+------------------------------
+
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``.config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_SFC_EFX_PMD`` (default **y**)
+
+  Enable compilation of Solarflare libefx-based poll-mode driver.
+
+- ``CONFIG_RTE_LIBRTE_SFC_EFX_DEBUG`` (default **n**)
+
+  Enable compilation of the extra run-time consistency checks.
+
+
+Per-Device Parameters
+~~~~~~~~~~~~~~~~~~~~~
+
+The following per-device parameters can be passed via EAL PCI device
+whitelist option like "-w 02:00.0,arg1=value1,...".
+
+Case-insensitive 1/y/yes/on or 0/n/no/off may be used to specify
+boolean parameters value.
+
+- ``debug_init`` [bool] (default **n**)
+
+  Enable extra logging during device intialization and startup.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index bc93230..ccf464a 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -50,6 +50,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += null
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += pcap
 DIRS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += ring
+DIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += szedata2
 DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
new file mode 100644
index 0000000..bdfe2ea
--- /dev/null
+++ b/drivers/net/sfc/Makefile
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2016 Solarflare Communications Inc.
+# All rights reserved.
+#
+# This software was jointly developed between OKTET Labs (under contract
+# for Solarflare) and Solarflare Communications, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+#    this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+DIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/net/sfc/efx/Makefile b/drivers/net/sfc/efx/Makefile
new file mode 100644
index 0000000..71f07ca
--- /dev/null
+++ b/drivers/net/sfc/efx/Makefile
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2016 Solarflare Communications Inc.
+# All rights reserved.
+#
+# This software was jointly developed between OKTET Labs (under contract
+# for Solarflare) and Solarflare Communications, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+#    this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_sfc_efx.a
+
+CFLAGS += -O3
+
+# Enable basic warnings but disable some which are accepted
+CFLAGS += -Wall
+CFLAGS += -Wno-strict-aliasing
+
+# Enable extra warnings but disable some which are accepted
+CFLAGS += -Wextra
+CFLAGS += -Wno-empty-body
+CFLAGS += -Wno-sign-compare
+CFLAGS += -Wno-type-limits
+CFLAGS += -Wno-unused-parameter
+
+# More warnings not enabled by above aggregators
+CFLAGS += -Waggregate-return
+CFLAGS += -Wbad-function-cast
+CFLAGS += -Wcast-qual
+CFLAGS += -Wdisabled-optimization
+CFLAGS += -Wmissing-declarations
+CFLAGS += -Wmissing-prototypes
+CFLAGS += -Wnested-externs
+CFLAGS += -Wold-style-definition
+CFLAGS += -Wpointer-arith
+CFLAGS += -Wstrict-prototypes
+CFLAGS += -Wundef
+CFLAGS += -Wwrite-strings
+
+EXPORT_MAP := rte_pmd_sfc_efx_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_kvargs.c
+
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_kvargs
+DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_mbuf
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/sfc/efx/rte_pmd_sfc_efx_version.map b/drivers/net/sfc/efx/rte_pmd_sfc_efx_version.map
new file mode 100644
index 0000000..1901bcb
--- /dev/null
+++ b/drivers/net/sfc/efx/rte_pmd_sfc_efx_version.map
@@ -0,0 +1,4 @@
+DPDK_16.07 {
+
+	local: *;
+};
diff --git a/drivers/net/sfc/efx/sfc.h b/drivers/net/sfc/efx/sfc.h
new file mode 100644
index 0000000..16fd2bb
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SFC_H
+#define	_SFC_H
+
+#include <stdbool.h>
+
+#include <rte_ethdev.h>
+#include <rte_kvargs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Adapter private data */
+struct sfc_adapter {
+	struct rte_eth_dev		*eth_dev;
+	struct rte_kvargs		*kvargs;
+	bool				debug_init;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _SFC_H */
diff --git a/drivers/net/sfc/efx/sfc_debug.h b/drivers/net/sfc/efx/sfc_debug.h
new file mode 100644
index 0000000..de3ec61
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_debug.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SFC_DEBUG_H_
+#define	_SFC_DEBUG_H_
+
+#include <rte_debug.h>
+
+#ifdef RTE_LIBRTE_SFC_EFX_DEBUG
+/* Avoid dependency from RTE_LOG_LEVEL to be able to enable debug check
+ * in the driver only.
+ */
+#define	SFC_ASSERT(exp)			RTE_VERIFY(exp)
+#else
+/* If the driver debug is not enabled, follow DPDK debug/non-debug */
+#define	SFC_ASSERT(exp)			RTE_ASSERT(exp)
+#endif
+
+#endif /* _SFC_DEBUG_H_ */
diff --git a/drivers/net/sfc/efx/sfc_ethdev.c b/drivers/net/sfc/efx/sfc_ethdev.c
new file mode 100644
index 0000000..ff20a13
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_ethdev.c
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_dev.h>
+#include <rte_ethdev.h>
+#include <rte_pci.h>
+
+#include "sfc.h"
+#include "sfc_debug.h"
+#include "sfc_log.h"
+#include "sfc_kvargs.h"
+
+
+static const struct eth_dev_ops sfc_eth_dev_ops = {
+	/* Just dummy init to avoid build-time warning */
+	.dev_configure			= NULL,
+};
+
+static int
+sfc_eth_dev_init(struct rte_eth_dev *dev)
+{
+	struct sfc_adapter *sa = dev->data->dev_private;
+	struct rte_pci_device *pci_dev = dev->pci_dev;
+	int rc;
+
+	/* Required for logging */
+	sa->eth_dev = dev;
+
+	/* Copy PCI device info to the dev->data */
+	rte_eth_copy_pci_info(dev, pci_dev);
+
+	rc = sfc_kvargs_parse(sa);
+	if (rc != 0)
+		goto fail_kvargs_parse;
+
+	rc = sfc_kvargs_process(sa, SFC_KVARG_DEBUG_INIT,
+				sfc_kvarg_bool_handler, &sa->debug_init);
+	if (rc != 0)
+		goto fail_kvarg_debug_init;
+
+	sfc_log_init(sa, "entry");
+
+	dev->dev_ops = &sfc_eth_dev_ops;
+
+	sfc_log_init(sa, "done");
+	return 0;
+
+fail_kvarg_debug_init:
+	sfc_kvargs_cleanup(sa);
+
+fail_kvargs_parse:
+	sfc_log_init(sa, "failed %d", rc);
+	SFC_ASSERT(rc > 0);
+	return -rc;
+}
+
+static int
+sfc_eth_dev_uninit(struct rte_eth_dev *dev)
+{
+	struct sfc_adapter *sa = dev->data->dev_private;
+
+	sfc_log_init(sa, "entry");
+
+	dev->dev_ops = NULL;
+
+	sfc_kvargs_cleanup(sa);
+
+	sfc_log_init(sa, "done");
+
+	/* Required for logging, so cleanup last */
+	sa->eth_dev = NULL;
+	return 0;
+}
+
+static const struct rte_pci_id pci_id_sfc_efx_map[] = {
+	{ .vendor_id = 0 /* sentinel */ }
+};
+
+static struct eth_driver sfc_efx_pmd = {
+	.pci_drv = {
+		.id_table = pci_id_sfc_efx_map,
+		.drv_flags = 0,
+		.probe = rte_eth_dev_pci_probe,
+		.remove = rte_eth_dev_pci_remove,
+	},
+	.eth_dev_init = sfc_eth_dev_init,
+	.eth_dev_uninit = sfc_eth_dev_uninit,
+	.dev_private_size = sizeof(struct sfc_adapter),
+};
+
+RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv);
+RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map);
+RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx,
+	SFC_KVARG_DEBUG_INIT "=" SFC_KVARG_VALUES_BOOL);
diff --git a/drivers/net/sfc/efx/sfc_kvargs.c b/drivers/net/sfc/efx/sfc_kvargs.c
new file mode 100644
index 0000000..3e8baa4
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_kvargs.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdbool.h>
+#include <strings.h>
+
+#include <rte_devargs.h>
+#include <rte_kvargs.h>
+
+#include "sfc.h"
+#include "sfc_kvargs.h"
+
+int
+sfc_kvargs_parse(struct sfc_adapter *sa)
+{
+	struct rte_devargs *devargs = sa->eth_dev->pci_dev->device.devargs;
+	const char **params = (const char *[]){
+		SFC_KVARG_DEBUG_INIT,
+		NULL,
+	};
+
+	if (devargs == NULL)
+		return 0;
+
+	sa->kvargs = rte_kvargs_parse(devargs->args, params);
+	if (sa->kvargs == NULL)
+		return EINVAL;
+
+	return 0;
+}
+
+void
+sfc_kvargs_cleanup(struct sfc_adapter *sa)
+{
+	rte_kvargs_free(sa->kvargs);
+}
+
+static int
+sfc_kvarg_match_value(const char *value, const char * const *values,
+		      unsigned int n_values)
+{
+	unsigned int i;
+
+	for (i = 0; i < n_values; ++i)
+		if (strcasecmp(value, values[i]) == 0)
+			return 1;
+
+	return 0;
+}
+
+int
+sfc_kvargs_process(struct sfc_adapter *sa, const char *key_match,
+		   arg_handler_t handler, void *opaque_arg)
+{
+	if (sa->kvargs == NULL)
+		return 0;
+
+	return -rte_kvargs_process(sa->kvargs, key_match, handler, opaque_arg);
+}
+
+int
+sfc_kvarg_bool_handler(const char *key, const char *value_str, void *opaque)
+{
+	const char * const true_strs[] = {
+		"1", "y", "yes", "on", "true"
+	};
+	const char * const false_strs[] = {
+		"0", "n", "no", "off", "false"
+	};
+	bool *value = opaque;
+
+	if (sfc_kvarg_match_value(value_str, true_strs,
+				  RTE_DIM(true_strs)))
+		*value = true;
+	else if (sfc_kvarg_match_value(value_str, false_strs,
+				       RTE_DIM(false_strs)))
+		*value = false;
+	else
+		return -EINVAL;
+
+	return 0;
+}
diff --git a/drivers/net/sfc/efx/sfc_kvargs.h b/drivers/net/sfc/efx/sfc_kvargs.h
new file mode 100644
index 0000000..a757e3d
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_kvargs.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SFC_KVARGS_H
+#define	_SFC_KVARGS_H
+
+#include <rte_kvargs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	SFC_KVARG_VALUES_BOOL		"[1|y|yes|on|0|n|no|off]"
+
+#define	SFC_KVARG_DEBUG_INIT		"debug_init"
+
+struct sfc_adapter;
+
+int sfc_kvargs_parse(struct sfc_adapter *sa);
+void sfc_kvargs_cleanup(struct sfc_adapter *sa);
+
+int sfc_kvargs_process(struct sfc_adapter *sa, const char *key_match,
+		       arg_handler_t handler, void *opaque_arg);
+
+int sfc_kvarg_bool_handler(const char *key, const char *value_str,
+			   void *opaque);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _SFC_KVARGS_H */
diff --git a/drivers/net/sfc/efx/sfc_log.h b/drivers/net/sfc/efx/sfc_log.h
new file mode 100644
index 0000000..06df181
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_log.h
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SFC_LOG_H_
+#define	_SFC_LOG_H_
+
+/* Log PMD message, automatically add prefix and \n */
+#define	SFC_LOG(sa, level, ...) \
+	do {								\
+		const struct rte_eth_dev *_dev = (sa)->eth_dev;		\
+		const struct rte_pci_device *_pci_dev = _dev->pci_dev;	\
+									\
+		RTE_LOG(level, PMD,					\
+			RTE_FMT("sfc_efx " PCI_PRI_FMT " #%" PRIu8 ": "	\
+				RTE_FMT_HEAD(__VA_ARGS__,) "\n",	\
+				_pci_dev->addr.domain,			\
+				_pci_dev->addr.bus,			\
+				_pci_dev->addr.devid,			\
+				_pci_dev->addr.function,		\
+				_dev->data->port_id,			\
+				RTE_FMT_TAIL(__VA_ARGS__,)));		\
+	} while (0)
+
+#define	sfc_err(sa, ...) \
+	SFC_LOG(sa, ERR, __VA_ARGS__)
+
+#define	sfc_warn(sa, ...) \
+	SFC_LOG(sa, WARNING, __VA_ARGS__)
+
+#define	sfc_notice(sa, ...) \
+	SFC_LOG(sa, NOTICE, __VA_ARGS__)
+
+#define	sfc_info(sa, ...) \
+	SFC_LOG(sa, INFO, __VA_ARGS__)
+
+#define	sfc_log_init(sa, ...) \
+	do {								\
+		if (sa->debug_init)					\
+			SFC_LOG(sa, INFO,				\
+				RTE_FMT("%s(): "			\
+					RTE_FMT_HEAD(__VA_ARGS__,),	\
+					__func__,			\
+					RTE_FMT_TAIL(__VA_ARGS__,)));	\
+	} while (0)
+
+#endif /* _SFC_LOG_H_ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index f75f0e2..52ae046 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -123,6 +123,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL)       += -lrte_pmd_null
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lrte_pmd_pcap -lpcap
 _LDLIBS-$(CONFIG_RTE_LIBRTE_QEDE_PMD)       += -lrte_pmd_qede
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING)       += -lrte_pmd_ring
+_LDLIBS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD)    += -lrte_pmd_sfc_efx
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2)   += -lrte_pmd_szedata2 -lsze2
 _LDLIBS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += -lrte_pmd_thunderx_nicvf -lm
 _LDLIBS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD)     += -lrte_pmd_virtio
-- 
2.5.5

^ permalink raw reply related

* [PATCH 14/56] net/sfc: import libefx software per-queue statistics support
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

EFSYS_OPT_QSTATS should be enabled to use it.

>From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/base/ef10_ev.c   |  25 ++++++++
 drivers/net/sfc/efx/base/ef10_impl.h |  16 +++++
 drivers/net/sfc/efx/base/ef10_tx.c   |  26 ++++++++
 drivers/net/sfc/efx/base/efx.h       |  97 ++++++++++++++++++++++++++++++
 drivers/net/sfc/efx/base/efx_check.h |   7 +++
 drivers/net/sfc/efx/base/efx_ev.c    | 112 +++++++++++++++++++++++++++++++++++
 drivers/net/sfc/efx/base/efx_impl.h  |  13 ++++
 drivers/net/sfc/efx/base/efx_tx.c    |  80 +++++++++++++++++++++++++
 8 files changed, 376 insertions(+)

diff --git a/drivers/net/sfc/efx/base/ef10_ev.c b/drivers/net/sfc/efx/base/ef10_ev.c
index 46ecd42..b4fe9a7 100644
--- a/drivers/net/sfc/efx/base/ef10_ev.c
+++ b/drivers/net/sfc/efx/base/ef10_ev.c
@@ -33,7 +33,15 @@
 
 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
 
+#if EFSYS_OPT_QSTATS
+#define	EFX_EV_QSTAT_INCR(_eep, _stat)					\
+	do {								\
+		(_eep)->ee_stat[_stat]++;				\
+	_NOTE(CONSTANTCONDITION)					\
+	} while (B_FALSE)
+#else
 #define	EFX_EV_QSTAT_INCR(_eep, _stat)
+#endif
 
 /*
  * Non-interrupting event queue requires interrrupting event queue to
@@ -731,6 +739,23 @@ ef10_ev_qmoderate(
 }
 
 
+#if EFSYS_OPT_QSTATS
+			void
+ef10_ev_qstats_update(
+	__in				efx_evq_t *eep,
+	__inout_ecount(EV_NQSTATS)	efsys_stat_t *stat)
+{
+	unsigned int id;
+
+	for (id = 0; id < EV_NQSTATS; id++) {
+		efsys_stat_t *essp = &stat[id];
+
+		EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
+		eep->ee_stat[id] = 0;
+	}
+}
+#endif /* EFSYS_OPT_QSTATS */
+
 static	__checkReturn	boolean_t
 ef10_ev_rx(
 	__in		efx_evq_t *eep,
diff --git a/drivers/net/sfc/efx/base/ef10_impl.h b/drivers/net/sfc/efx/base/ef10_impl.h
index 5cbe6b1..e1d2903 100644
--- a/drivers/net/sfc/efx/base/ef10_impl.h
+++ b/drivers/net/sfc/efx/base/ef10_impl.h
@@ -105,6 +105,13 @@ ef10_ev_qmoderate(
 	__in		efx_evq_t *eep,
 	__in		unsigned int us);
 
+#if EFSYS_OPT_QSTATS
+			void
+ef10_ev_qstats_update(
+	__in				efx_evq_t *eep,
+	__inout_ecount(EV_NQSTATS)	efsys_stat_t *stat);
+#endif /* EFSYS_OPT_QSTATS */
+
 		void
 ef10_ev_rxlabel_init(
 	__in		efx_evq_t *eep,
@@ -490,6 +497,15 @@ ef10_tx_qdesc_vlantci_create(
 	__out	efx_desc_t *edp);
 
 
+#if EFSYS_OPT_QSTATS
+
+extern			void
+ef10_tx_qstats_update(
+	__in				efx_txq_t *etp,
+	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat);
+
+#endif /* EFSYS_OPT_QSTATS */
+
 typedef uint32_t	efx_piobuf_handle_t;
 
 #define	EFX_PIOBUF_HANDLE_INVALID	((efx_piobuf_handle_t) -1)
diff --git a/drivers/net/sfc/efx/base/ef10_tx.c b/drivers/net/sfc/efx/base/ef10_tx.c
index 59343a3..aa19cce 100644
--- a/drivers/net/sfc/efx/base/ef10_tx.c
+++ b/drivers/net/sfc/efx/base/ef10_tx.c
@@ -34,7 +34,15 @@
 
 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
 
+#if EFSYS_OPT_QSTATS
+#define	EFX_TX_QSTAT_INCR(_etp, _stat)					\
+	do {								\
+		(_etp)->et_stat[_stat]++;				\
+	_NOTE(CONSTANTCONDITION)					\
+	} while (B_FALSE)
+#else
 #define	EFX_TX_QSTAT_INCR(_etp, _stat)
+#endif
 
 static	__checkReturn	efx_rc_t
 efx_mcdi_init_txq(
@@ -680,4 +688,22 @@ ef10_tx_qenable(
 	/* FIXME */
 }
 
+#if EFSYS_OPT_QSTATS
+			void
+ef10_tx_qstats_update(
+	__in				efx_txq_t *etp,
+	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat)
+{
+	unsigned int id;
+
+	for (id = 0; id < TX_NQSTATS; id++) {
+		efsys_stat_t *essp = &stat[id];
+
+		EFSYS_STAT_INCR(essp, etp->et_stat[id]);
+		etp->et_stat[id] = 0;
+	}
+}
+
+#endif /* EFSYS_OPT_QSTATS */
+
 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/drivers/net/sfc/efx/base/efx.h b/drivers/net/sfc/efx/base/efx.h
index 15faf9d..c2587ca 100644
--- a/drivers/net/sfc/efx/base/efx.h
+++ b/drivers/net/sfc/efx/base/efx.h
@@ -823,6 +823,54 @@ efx_sram_buf_tbl_clear(
 
 typedef struct efx_evq_s	efx_evq_t;
 
+#if EFSYS_OPT_QSTATS
+
+/* START MKCONFIG GENERATED EfxHeaderEventQueueBlock 6f3843f5fe7cc843 */
+typedef enum efx_ev_qstat_e {
+	EV_ALL,
+	EV_RX,
+	EV_RX_OK,
+	EV_RX_FRM_TRUNC,
+	EV_RX_TOBE_DISC,
+	EV_RX_PAUSE_FRM_ERR,
+	EV_RX_BUF_OWNER_ID_ERR,
+	EV_RX_IPV4_HDR_CHKSUM_ERR,
+	EV_RX_TCP_UDP_CHKSUM_ERR,
+	EV_RX_ETH_CRC_ERR,
+	EV_RX_IP_FRAG_ERR,
+	EV_RX_MCAST_PKT,
+	EV_RX_MCAST_HASH_MATCH,
+	EV_RX_TCP_IPV4,
+	EV_RX_TCP_IPV6,
+	EV_RX_UDP_IPV4,
+	EV_RX_UDP_IPV6,
+	EV_RX_OTHER_IPV4,
+	EV_RX_OTHER_IPV6,
+	EV_RX_NON_IP,
+	EV_RX_BATCH,
+	EV_TX,
+	EV_TX_WQ_FF_FULL,
+	EV_TX_PKT_ERR,
+	EV_TX_PKT_TOO_BIG,
+	EV_TX_UNEXPECTED,
+	EV_GLOBAL,
+	EV_GLOBAL_MNT,
+	EV_DRIVER,
+	EV_DRIVER_SRM_UPD_DONE,
+	EV_DRIVER_TX_DESCQ_FLS_DONE,
+	EV_DRIVER_RX_DESCQ_FLS_DONE,
+	EV_DRIVER_RX_DESCQ_FLS_FAILED,
+	EV_DRIVER_RX_DSC_ERROR,
+	EV_DRIVER_TX_DSC_ERROR,
+	EV_DRV_GEN,
+	EV_MCDI_RESPONSE,
+	EV_NQSTATS
+} efx_ev_qstat_t;
+
+/* END MKCONFIG GENERATED EfxHeaderEventQueueBlock */
+
+#endif	/* EFSYS_OPT_QSTATS */
+
 extern	__checkReturn	efx_rc_t
 efx_ev_init(
 	__in		efx_nic_t *enp);
@@ -1014,6 +1062,24 @@ efx_ev_qprime(
 	__in		efx_evq_t *eep,
 	__in		unsigned int count);
 
+#if EFSYS_OPT_QSTATS
+
+#if EFSYS_OPT_NAMES
+
+extern		const char *
+efx_ev_qstat_name(
+	__in	efx_nic_t *enp,
+	__in	unsigned int id);
+
+#endif	/* EFSYS_OPT_NAMES */
+
+extern					void
+efx_ev_qstats_update(
+	__in				efx_evq_t *eep,
+	__inout_ecount(EV_NQSTATS)	efsys_stat_t *stat);
+
+#endif	/* EFSYS_OPT_QSTATS */
+
 extern		void
 efx_ev_qdestroy(
 	__in	efx_evq_t *eep);
@@ -1106,6 +1172,19 @@ efx_rx_qdestroy(
 
 typedef struct efx_txq_s	efx_txq_t;
 
+#if EFSYS_OPT_QSTATS
+
+/* START MKCONFIG GENERATED EfxHeaderTransmitQueueBlock 12dff8778598b2db */
+typedef enum efx_tx_qstat_e {
+	TX_POST,
+	TX_POST_PIO,
+	TX_NQSTATS
+} efx_tx_qstat_t;
+
+/* END MKCONFIG GENERATED EfxHeaderTransmitQueueBlock */
+
+#endif	/* EFSYS_OPT_QSTATS */
+
 extern	__checkReturn	efx_rc_t
 efx_tx_init(
 	__in		efx_nic_t *enp);
@@ -1234,6 +1313,24 @@ efx_tx_qdesc_vlantci_create(
 	__in	uint16_t tci,
 	__out	efx_desc_t *edp);
 
+#if EFSYS_OPT_QSTATS
+
+#if EFSYS_OPT_NAMES
+
+extern		const char *
+efx_tx_qstat_name(
+	__in	efx_nic_t *etp,
+	__in	unsigned int id);
+
+#endif	/* EFSYS_OPT_NAMES */
+
+extern					void
+efx_tx_qstats_update(
+	__in				efx_txq_t *etp,
+	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat);
+
+#endif	/* EFSYS_OPT_QSTATS */
+
 extern		void
 efx_tx_qdestroy(
 	__in	efx_txq_t *etp);
diff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h
index c78c5b6..6f0c216 100644
--- a/drivers/net/sfc/efx/base/efx_check.h
+++ b/drivers/net/sfc/efx/base/efx_check.h
@@ -198,6 +198,13 @@
 # error "PHY_TXC43128 is obsolete and is not supported."
 #endif
 
+#if EFSYS_OPT_QSTATS
+/* Support EVQ/RXQ/TXQ statistics */
+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)
+#  error "QSTATS requires SIENA or HUNTINGTON or MEDFORD"
+# endif
+#endif /* EFSYS_OPT_QSTATS */
+
 #ifdef EFSYS_OPT_RX_HDR_SPLIT
 # error "RX_HDR_SPLIT is obsolete and is not supported"
 #endif
diff --git a/drivers/net/sfc/efx/base/efx_ev.c b/drivers/net/sfc/efx/base/efx_ev.c
index 8cb78be..c7c5fa8 100644
--- a/drivers/net/sfc/efx/base/efx_ev.c
+++ b/drivers/net/sfc/efx/base/efx_ev.c
@@ -31,7 +31,15 @@
 #include "efx.h"
 #include "efx_impl.h"
 
+#if EFSYS_OPT_QSTATS
+#define	EFX_EV_QSTAT_INCR(_eep, _stat)					\
+	do {								\
+		(_eep)->ee_stat[_stat]++;				\
+	_NOTE(CONSTANTCONDITION)					\
+	} while (B_FALSE)
+#else
 #define	EFX_EV_QSTAT_INCR(_eep, _stat)
+#endif
 
 #define	EFX_EV_PRESENT(_qword)						\
 	(EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff &&	\
@@ -79,6 +87,14 @@ siena_ev_qmoderate(
 	__in		efx_evq_t *eep,
 	__in		unsigned int us);
 
+#if EFSYS_OPT_QSTATS
+static			void
+siena_ev_qstats_update(
+	__in				efx_evq_t *eep,
+	__inout_ecount(EV_NQSTATS)	efsys_stat_t *stat);
+
+#endif
+
 #endif /* EFSYS_OPT_SIENA */
 
 #if EFSYS_OPT_SIENA
@@ -90,6 +106,9 @@ static const efx_ev_ops_t	__efx_ev_siena_ops = {
 	siena_ev_qprime,			/* eevo_qprime */
 	siena_ev_qpost,				/* eevo_qpost */
 	siena_ev_qmoderate,			/* eevo_qmoderate */
+#if EFSYS_OPT_QSTATS
+	siena_ev_qstats_update,			/* eevo_qstats_update */
+#endif
 };
 #endif /* EFSYS_OPT_SIENA */
 
@@ -102,6 +121,9 @@ static const efx_ev_ops_t	__efx_ev_ef10_ops = {
 	ef10_ev_qprime,				/* eevo_qprime */
 	ef10_ev_qpost,				/* eevo_qpost */
 	ef10_ev_qmoderate,			/* eevo_qmoderate */
+#if EFSYS_OPT_QSTATS
+	ef10_ev_qstats_update,			/* eevo_qstats_update */
+#endif
 };
 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
 
@@ -524,6 +546,22 @@ efx_ev_qmoderate(
 	return (rc);
 }
 
+#if EFSYS_OPT_QSTATS
+					void
+efx_ev_qstats_update(
+	__in				efx_evq_t *eep,
+	__inout_ecount(EV_NQSTATS)	efsys_stat_t *stat)
+
+{	efx_nic_t *enp = eep->ee_enp;
+	const efx_ev_ops_t *eevop = enp->en_eevop;
+
+	EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+	eevop->eevo_qstats_update(eep, stat);
+}
+
+#endif	/* EFSYS_OPT_QSTATS */
+
 #if EFSYS_OPT_SIENA
 
 static	__checkReturn	efx_rc_t
@@ -1220,8 +1258,82 @@ siena_ev_qcreate(
 
 #endif /* EFSYS_OPT_SIENA */
 
+#if EFSYS_OPT_QSTATS
+#if EFSYS_OPT_NAMES
+/* START MKCONFIG GENERATED EfxEventQueueStatNamesBlock c0f3bc5083b40532 */
+static const char * const __efx_ev_qstat_name[] = {
+	"all",
+	"rx",
+	"rx_ok",
+	"rx_frm_trunc",
+	"rx_tobe_disc",
+	"rx_pause_frm_err",
+	"rx_buf_owner_id_err",
+	"rx_ipv4_hdr_chksum_err",
+	"rx_tcp_udp_chksum_err",
+	"rx_eth_crc_err",
+	"rx_ip_frag_err",
+	"rx_mcast_pkt",
+	"rx_mcast_hash_match",
+	"rx_tcp_ipv4",
+	"rx_tcp_ipv6",
+	"rx_udp_ipv4",
+	"rx_udp_ipv6",
+	"rx_other_ipv4",
+	"rx_other_ipv6",
+	"rx_non_ip",
+	"rx_batch",
+	"tx",
+	"tx_wq_ff_full",
+	"tx_pkt_err",
+	"tx_pkt_too_big",
+	"tx_unexpected",
+	"global",
+	"global_mnt",
+	"driver",
+	"driver_srm_upd_done",
+	"driver_tx_descq_fls_done",
+	"driver_rx_descq_fls_done",
+	"driver_rx_descq_fls_failed",
+	"driver_rx_dsc_error",
+	"driver_tx_dsc_error",
+	"drv_gen",
+	"mcdi_response",
+};
+/* END MKCONFIG GENERATED EfxEventQueueStatNamesBlock */
+
+		const char *
+efx_ev_qstat_name(
+	__in	efx_nic_t *enp,
+	__in	unsigned int id)
+{
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(id, <, EV_NQSTATS);
+
+	return (__efx_ev_qstat_name[id]);
+}
+#endif	/* EFSYS_OPT_NAMES */
+#endif	/* EFSYS_OPT_QSTATS */
+
 #if EFSYS_OPT_SIENA
 
+#if EFSYS_OPT_QSTATS
+static					void
+siena_ev_qstats_update(
+	__in				efx_evq_t *eep,
+	__inout_ecount(EV_NQSTATS)	efsys_stat_t *stat)
+{
+	unsigned int id;
+
+	for (id = 0; id < EV_NQSTATS; id++) {
+		efsys_stat_t *essp = &stat[id];
+
+		EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
+		eep->ee_stat[id] = 0;
+	}
+}
+#endif	/* EFSYS_OPT_QSTATS */
+
 static		void
 siena_ev_qdestroy(
 	__in	efx_evq_t *eep)
diff --git a/drivers/net/sfc/efx/base/efx_impl.h b/drivers/net/sfc/efx/base/efx_impl.h
index a6853b3..f776656 100644
--- a/drivers/net/sfc/efx/base/efx_impl.h
+++ b/drivers/net/sfc/efx/base/efx_impl.h
@@ -97,6 +97,9 @@ typedef struct efx_ev_ops_s {
 	efx_rc_t	(*eevo_qprime)(efx_evq_t *, unsigned int);
 	void		(*eevo_qpost)(efx_evq_t *, uint16_t);
 	efx_rc_t	(*eevo_qmoderate)(efx_evq_t *, unsigned int);
+#if EFSYS_OPT_QSTATS
+	void		(*eevo_qstats_update)(efx_evq_t *, efsys_stat_t *);
+#endif
 } efx_ev_ops_t;
 
 typedef struct efx_tx_ops_s {
@@ -136,6 +139,10 @@ typedef struct efx_tx_ops_s {
 						efx_desc_t *, int);
 	void		(*etxo_qdesc_vlantci_create)(efx_txq_t *, uint16_t,
 						efx_desc_t *);
+#if EFSYS_OPT_QSTATS
+	void		(*etxo_qstats_update)(efx_txq_t *,
+					      efsys_stat_t *);
+#endif
 } efx_tx_ops_t;
 
 typedef struct efx_rx_ops_s {
@@ -479,6 +486,9 @@ struct efx_evq_s {
 	unsigned int			ee_index;
 	unsigned int			ee_mask;
 	efsys_mem_t			*ee_esmp;
+#if EFSYS_OPT_QSTATS
+	uint32_t			ee_stat[EV_NQSTATS];
+#endif	/* EFSYS_OPT_QSTATS */
 
 	efx_ev_handler_t		ee_rx;
 	efx_ev_handler_t		ee_tx;
@@ -523,6 +533,9 @@ struct efx_txq_s {
 	uint32_t			et_pio_offset;
 	size_t				et_pio_size;
 #endif
+#if EFSYS_OPT_QSTATS
+	uint32_t			et_stat[TX_NQSTATS];
+#endif	/* EFSYS_OPT_QSTATS */
 };
 
 #define	EFX_TXQ_MAGIC	0x05092005
diff --git a/drivers/net/sfc/efx/base/efx_tx.c b/drivers/net/sfc/efx/base/efx_tx.c
index 16834af..0d47390 100644
--- a/drivers/net/sfc/efx/base/efx_tx.c
+++ b/drivers/net/sfc/efx/base/efx_tx.c
@@ -31,7 +31,15 @@
 #include "efx.h"
 #include "efx_impl.h"
 
+#if EFSYS_OPT_QSTATS
+#define	EFX_TX_QSTAT_INCR(_etp, _stat)					\
+	do {								\
+		(_etp)->et_stat[_stat]++;				\
+	_NOTE(CONSTANTCONDITION)					\
+	} while (B_FALSE)
+#else
 #define	EFX_TX_QSTAT_INCR(_etp, _stat)
+#endif
 
 #if EFSYS_OPT_SIENA
 
@@ -103,6 +111,13 @@ siena_tx_qdesc_dma_create(
 	__in	boolean_t eop,
 	__out	efx_desc_t *edp);
 
+#if EFSYS_OPT_QSTATS
+static			void
+siena_tx_qstats_update(
+	__in				efx_txq_t *etp,
+	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat);
+#endif
+
 #endif /* EFSYS_OPT_SIENA */
 
 
@@ -126,6 +141,9 @@ static const efx_tx_ops_t	__efx_tx_siena_ops = {
 	NULL,					/* etxo_qdesc_tso_create */
 	NULL,					/* etxo_qdesc_tso2_create */
 	NULL,					/* etxo_qdesc_vlantci_create */
+#if EFSYS_OPT_QSTATS
+	siena_tx_qstats_update,			/* etxo_qstats_update */
+#endif
 };
 #endif /* EFSYS_OPT_SIENA */
 
@@ -149,6 +167,9 @@ static const efx_tx_ops_t	__efx_tx_hunt_ops = {
 	ef10_tx_qdesc_tso_create,		/* etxo_qdesc_tso_create */
 	ef10_tx_qdesc_tso2_create,		/* etxo_qdesc_tso2_create */
 	ef10_tx_qdesc_vlantci_create,		/* etxo_qdesc_vlantci_create */
+#if EFSYS_OPT_QSTATS
+	ef10_tx_qstats_update,			/* etxo_qstats_update */
+#endif
 };
 #endif /* EFSYS_OPT_HUNTINGTON */
 
@@ -172,6 +193,9 @@ static const efx_tx_ops_t	__efx_tx_medford_ops = {
 	NULL,					/* etxo_qdesc_tso_create */
 	ef10_tx_qdesc_tso2_create,		/* etxo_qdesc_tso2_create */
 	ef10_tx_qdesc_vlantci_create,		/* etxo_qdesc_vlantci_create */
+#if EFSYS_OPT_QSTATS
+	ef10_tx_qstats_update,			/* etxo_qstats_update */
+#endif
 };
 #endif /* EFSYS_OPT_MEDFORD */
 
@@ -619,6 +643,22 @@ efx_tx_qdesc_vlantci_create(
 }
 
 
+#if EFSYS_OPT_QSTATS
+			void
+efx_tx_qstats_update(
+	__in				efx_txq_t *etp,
+	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat)
+{
+	efx_nic_t *enp = etp->et_enp;
+	const efx_tx_ops_t *etxop = enp->en_etxop;
+
+	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+	etxop->etxo_qstats_update(etp, stat);
+}
+#endif
+
+
 #if EFSYS_OPT_SIENA
 
 static	__checkReturn	efx_rc_t
@@ -983,8 +1023,48 @@ siena_tx_qdesc_dma_create(
 
 #endif /* EFSYS_OPT_SIENA */
 
+#if EFSYS_OPT_QSTATS
+#if EFSYS_OPT_NAMES
+/* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 2866874ecd7a363b */
+static const char * const __efx_tx_qstat_name[] = {
+	"post",
+	"post_pio",
+};
+/* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */
+
+		const char *
+efx_tx_qstat_name(
+	__in	efx_nic_t *enp,
+	__in	unsigned int id)
+{
+	_NOTE(ARGUNUSED(enp))
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(id, <, TX_NQSTATS);
+
+	return (__efx_tx_qstat_name[id]);
+}
+#endif	/* EFSYS_OPT_NAMES */
+#endif /* EFSYS_OPT_QSTATS */
+
 #if EFSYS_OPT_SIENA
 
+#if EFSYS_OPT_QSTATS
+static					void
+siena_tx_qstats_update(
+	__in				efx_txq_t *etp,
+	__inout_ecount(TX_NQSTATS)	efsys_stat_t *stat)
+{
+	unsigned int id;
+
+	for (id = 0; id < TX_NQSTATS; id++) {
+		efsys_stat_t *essp = &stat[id];
+
+		EFSYS_STAT_INCR(essp, etp->et_stat[id]);
+		etp->et_stat[id] = 0;
+	}
+}
+#endif	/* EFSYS_OPT_QSTATS */
+
 static		void
 siena_tx_qdestroy(
 	__in	efx_txq_t *etp)
-- 
2.5.5

^ permalink raw reply related

* [PATCH 08/56] net/sfc: import libefx MCDI proxy authorization support
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

MCDI proxy authorization may be used if priviledged PCI
function (physical function) would like to intercept and
authorize MCDI requests done by unprivileged (e.g. virtual)
PCI function. It may be used to control unpriviledged
function Rx mode (e.g. promicsuous, all-multicast), MTU
and default MAC address change requests etc.

Current libefx support is limited to client-side which
is required to work when function requests need to be
authorized.

Server side support required to request and do the
authorization is not implemented yet.

EFSYS_OPT_MCDI_PROXY_AUTH should be enabled to use it.

>From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/base/efx.h       |  3 ++
 drivers/net/sfc/efx/base/efx_check.h |  7 ++++
 drivers/net/sfc/efx/base/efx_mcdi.c  | 74 ++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/efx/base/efx_mcdi.h  | 17 +++++++++
 4 files changed, 101 insertions(+)

diff --git a/drivers/net/sfc/efx/base/efx.h b/drivers/net/sfc/efx/base/efx.h
index 0ca0156..3899580 100644
--- a/drivers/net/sfc/efx/base/efx.h
+++ b/drivers/net/sfc/efx/base/efx.h
@@ -209,6 +209,9 @@ typedef struct efx_mcdi_transport_s {
 	void		(*emt_logger)(void *, efx_log_msg_t,
 					void *, size_t, void *, size_t);
 #endif /* EFSYS_OPT_MCDI_LOGGING */
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+	void		(*emt_ev_proxy_response)(void *, uint32_t, efx_rc_t);
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
 } efx_mcdi_transport_t;
 
 extern	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h
index 228b42c..470f73c 100644
--- a/drivers/net/sfc/efx/base/efx_check.h
+++ b/drivers/net/sfc/efx/base/efx_check.h
@@ -84,6 +84,13 @@
 # endif
 #endif /* EFSYS_OPT_MCDI_LOGGING */
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+/* Support MCDI proxy authorization */
+# if !EFSYS_OPT_MCDI
+#  error "MCDI_PROXY_AUTH requires MCDI"
+# endif
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
 #ifdef EFSYS_OPT_MON_LM87
 # error "MON_LM87 is obsolete and is not supported."
 #endif
diff --git a/drivers/net/sfc/efx/base/efx_mcdi.c b/drivers/net/sfc/efx/base/efx_mcdi.c
index 59a16fc..7b82096 100644
--- a/drivers/net/sfc/efx/base/efx_mcdi.c
+++ b/drivers/net/sfc/efx/base/efx_mcdi.c
@@ -352,6 +352,21 @@ efx_mcdi_read_response_header(
 		emrp->emr_err_code = err_code;
 		emrp->emr_err_arg = err_arg;
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+		if ((err_code == MC_CMD_ERR_PROXY_PENDING) &&
+		    (err_len == sizeof (err))) {
+			/*
+			 * The MCDI request would normally fail with EPERM, but
+			 * firmware has forwarded it to an authorization agent
+			 * attached to a privileged PF.
+			 *
+			 * Save the authorization request handle. The client
+			 * must wait for a PROXY_RESPONSE event, or timeout.
+			 */
+			emrp->emr_proxy_handle = err_arg;
+		}
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
 #if EFSYS_OPT_MCDI_LOGGING
 		if (emtp->emt_logger != NULL) {
 			emtp->emt_logger(emtp->emt_context,
@@ -372,6 +387,9 @@ efx_mcdi_read_response_header(
 
 	emrp->emr_rc = 0;
 	emrp->emr_out_length_used = data_len;
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+	emrp->emr_proxy_handle = 0;
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
 	return;
 
 fail3:
@@ -732,6 +750,62 @@ efx_mcdi_ev_cpl(
 	emtp->emt_ev_cpl(emtp->emt_context);
 }
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+
+	__checkReturn	efx_rc_t
+efx_mcdi_get_proxy_handle(
+	__in		efx_nic_t *enp,
+	__in		efx_mcdi_req_t *emrp,
+	__out		uint32_t *handlep)
+{
+	efx_rc_t rc;
+
+	/*
+	 * Return proxy handle from MCDI request that returned with error
+	 * MC_MCD_ERR_PROXY_PENDING. This handle is used to wait for a matching
+	 * PROXY_RESPONSE event.
+	 */
+	if ((emrp == NULL) || (handlep == NULL)) {
+		rc = EINVAL;
+		goto fail1;
+	}
+	if ((emrp->emr_rc != 0) &&
+	    (emrp->emr_err_code == MC_CMD_ERR_PROXY_PENDING)) {
+		*handlep = emrp->emr_proxy_handle;
+		rc = 0;
+	} else {
+		*handlep = 0;
+		rc = ENOENT;
+	}
+	return (rc);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+			void
+efx_mcdi_ev_proxy_response(
+	__in		efx_nic_t *enp,
+	__in		unsigned int handle,
+	__in		unsigned int status)
+{
+	const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+	efx_rc_t rc;
+
+	/*
+	 * Handle results of an authorization request for a privileged MCDI
+	 * command. If authorization was granted then we must re-issue the
+	 * original MCDI request. If authorization failed or timed out,
+	 * then the original MCDI request should be completed with the
+	 * result code from this event.
+	 */
+	rc = (status == 0) ? 0 : efx_mcdi_request_errcode(status);
+
+	emtp->emt_ev_proxy_response(emtp->emt_context, handle, rc);
+}
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
 			void
 efx_mcdi_ev_death(
 	__in		efx_nic_t *enp,
diff --git a/drivers/net/sfc/efx/base/efx_mcdi.h b/drivers/net/sfc/efx/base/efx_mcdi.h
index a408b5b..a62e921 100644
--- a/drivers/net/sfc/efx/base/efx_mcdi.h
+++ b/drivers/net/sfc/efx/base/efx_mcdi.h
@@ -59,6 +59,9 @@ struct efx_mcdi_req_s {
 	/* Internals: low level transport details */
 	unsigned int	emr_err_code;
 	unsigned int	emr_err_arg;
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+	uint32_t	emr_proxy_handle;
+#endif
 };
 
 typedef struct efx_mcdi_iface_s {
@@ -90,6 +93,20 @@ efx_mcdi_ev_cpl(
 	__in		unsigned int outlen,
 	__in		int errcode);
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+extern	__checkReturn	efx_rc_t
+efx_mcdi_get_proxy_handle(
+	__in		efx_nic_t *enp,
+	__in		efx_mcdi_req_t *emrp,
+	__out		uint32_t *handlep);
+
+extern			void
+efx_mcdi_ev_proxy_response(
+	__in		efx_nic_t *enp,
+	__in		unsigned int handle,
+	__in		unsigned int status);
+#endif
+
 extern			void
 efx_mcdi_ev_death(
 	__in		efx_nic_t *enp,
-- 
2.5.5

^ permalink raw reply related

* [PATCH 15/56] net/sfc: import libefx PHY flags control support
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

EFSYS_OPT_PHY_FLAGS should be enabled to use it.

>From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/base/ef10_phy.c  | 4 ++++
 drivers/net/sfc/efx/base/efx.h       | 3 +++
 drivers/net/sfc/efx/base/efx_check.h | 7 +++++++
 drivers/net/sfc/efx/base/efx_impl.h  | 3 +++
 drivers/net/sfc/efx/base/efx_mcdi.c  | 3 +++
 drivers/net/sfc/efx/base/siena_phy.c | 4 ++++
 6 files changed, 24 insertions(+)

diff --git a/drivers/net/sfc/efx/base/ef10_phy.c b/drivers/net/sfc/efx/base/ef10_phy.c
index 9e1b9c2..c7e584b 100644
--- a/drivers/net/sfc/efx/base/ef10_phy.c
+++ b/drivers/net/sfc/efx/base/ef10_phy.c
@@ -293,7 +293,11 @@ ef10_phy_reconfigure(
 	speed = 0;
 	MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed);
 
+#if EFSYS_OPT_PHY_FLAGS
+	MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, epp->ep_phy_flags);
+#else
 	MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0);
+#endif	/* EFSYS_OPT_PHY_FLAGS */
 
 	efx_mcdi_execute(enp, &req);
 
diff --git a/drivers/net/sfc/efx/base/efx.h b/drivers/net/sfc/efx/base/efx.h
index c2587ca..6dd5a8e 100644
--- a/drivers/net/sfc/efx/base/efx.h
+++ b/drivers/net/sfc/efx/base/efx.h
@@ -668,6 +668,9 @@ typedef struct efx_nic_cfg_s {
 	uint32_t		enc_rx_prefix_size;
 	uint32_t		enc_rx_buf_align_start;
 	uint32_t		enc_rx_buf_align_end;
+#if EFSYS_OPT_PHY_FLAGS
+	uint32_t		enc_phy_flags_mask;
+#endif	/* EFSYS_OPT_PHY_FLAGS */
 #if EFSYS_OPT_MCDI
 	uint8_t			enc_mcdi_mdio_channel;
 #endif	/* EFSYS_OPT_MCDI */
diff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h
index 6f0c216..68c01f3 100644
--- a/drivers/net/sfc/efx/base/efx_check.h
+++ b/drivers/net/sfc/efx/base/efx_check.h
@@ -166,6 +166,13 @@
 # error "PHY_BIST is obsolete (replaced by BIST)."
 #endif
 
+#if EFSYS_OPT_PHY_FLAGS
+/* Support PHY flags */
+# if !EFSYS_OPT_SIENA
+#  error "PHY_FLAGS requires SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_FLAGS */
+
 #ifdef EFSYS_OPT_PHY_NULL
 # error "PHY_NULL is obsolete and is not supported."
 #endif
diff --git a/drivers/net/sfc/efx/base/efx_impl.h b/drivers/net/sfc/efx/base/efx_impl.h
index f776656..489fcbc 100644
--- a/drivers/net/sfc/efx/base/efx_impl.h
+++ b/drivers/net/sfc/efx/base/efx_impl.h
@@ -237,6 +237,9 @@ typedef struct efx_port_s {
 	uint8_t			ep_mulcst_addr_list[EFX_MAC_ADDR_LEN *
 						    EFX_MAC_MULTICAST_LIST_MAX];
 	uint32_t		ep_mulcst_addr_count;
+#if EFSYS_OPT_PHY_FLAGS
+	uint32_t		ep_phy_flags;
+#endif	/* EFSYS_OPT_PHY_FLAGS */
 	efx_phy_media_type_t	ep_fixed_port_type;
 	efx_phy_media_type_t	ep_module_type;
 	uint32_t		ep_adv_cap_mask;
diff --git a/drivers/net/sfc/efx/base/efx_mcdi.c b/drivers/net/sfc/efx/base/efx_mcdi.c
index 40cd456..b070887 100644
--- a/drivers/net/sfc/efx/base/efx_mcdi.c
+++ b/drivers/net/sfc/efx/base/efx_mcdi.c
@@ -1425,6 +1425,9 @@ efx_mcdi_get_phy_cfg(
 
 	epp->ep_phy_cap_mask =
 		MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_SUPPORTED_CAP);
+#if EFSYS_OPT_PHY_FLAGS
+	encp->enc_phy_flags_mask = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_FLAGS);
+#endif	/* EFSYS_OPT_PHY_FLAGS */
 
 	encp->enc_port = (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_PRT);
 
diff --git a/drivers/net/sfc/efx/base/siena_phy.c b/drivers/net/sfc/efx/base/siena_phy.c
index d7e7d77..6451298 100644
--- a/drivers/net/sfc/efx/base/siena_phy.c
+++ b/drivers/net/sfc/efx/base/siena_phy.c
@@ -277,7 +277,11 @@ siena_phy_reconfigure(
 	speed = 0;
 	MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed);
 
+#if EFSYS_OPT_PHY_FLAGS
+	MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, epp->ep_phy_flags);
+#else
 	MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0);
+#endif	/* EFSYS_OPT_PHY_FLAGS */
 
 	efx_mcdi_execute(enp, &req);
 
-- 
2.5.5

^ permalink raw reply related

* [PATCH 04/56] net/sfc: import libefx filters support
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

Filtering capabilities depend on NIC family and used firmware
variant. Provided API allows to get supported filter types
(in a priority order), add/delete individual filters and
restore entire filter table after, for example, NIC management
CPU reboot.

Rx filters allow to redirect matching flow to specified Rx queue.

Tx filters allow to control generated traffic (e.g. to implement
virtual function anti-spoofing control).

EFSYS_OPT_FILTER should be enabled to use it. It is required
for SFN7xxx and SFN8xxx adapter families support.

>From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/base/efx.h        | 157 ++++++++++++++++
 drivers/net/sfc/efx/base/efx_check.h  |   5 +
 drivers/net/sfc/efx/base/efx_filter.c | 332 ++++++++++++++++++++++++++++++++++
 drivers/net/sfc/efx/base/efx_impl.h   |  38 ++++
 4 files changed, 532 insertions(+)
 create mode 100644 drivers/net/sfc/efx/base/efx_filter.c

diff --git a/drivers/net/sfc/efx/base/efx.h b/drivers/net/sfc/efx/base/efx.h
index 79c6fdc..485ce51 100644
--- a/drivers/net/sfc/efx/base/efx.h
+++ b/drivers/net/sfc/efx/base/efx.h
@@ -1044,6 +1044,163 @@ efx_tx_qdestroy(
 
 /* FILTER */
 
+#if EFSYS_OPT_FILTER
+
+#define	EFX_ETHER_TYPE_IPV4 0x0800
+#define	EFX_ETHER_TYPE_IPV6 0x86DD
+
+#define	EFX_IPPROTO_TCP 6
+#define	EFX_IPPROTO_UDP 17
+
+typedef enum efx_filter_flag_e {
+	EFX_FILTER_FLAG_RX_RSS = 0x01,		/* use RSS to spread across
+						 * multiple queues */
+	EFX_FILTER_FLAG_RX_SCATTER = 0x02,	/* enable RX scatter */
+	EFX_FILTER_FLAG_RX_OVER_AUTO = 0x04,	/* Override an automatic filter
+						 * (priority EFX_FILTER_PRI_AUTO).
+						 * May only be set by the filter
+						 * implementation for each type.
+						 * A removal request will
+						 * restore the automatic filter
+						 * in its place. */
+	EFX_FILTER_FLAG_RX = 0x08,		/* Filter is for RX */
+	EFX_FILTER_FLAG_TX = 0x10,		/* Filter is for TX */
+} efx_filter_flag_t;
+
+typedef enum efx_filter_match_flags_e {
+	EFX_FILTER_MATCH_REM_HOST = 0x0001,	/* Match by remote IP host
+						 * address */
+	EFX_FILTER_MATCH_LOC_HOST = 0x0002,	/* Match by local IP host
+						 * address */
+	EFX_FILTER_MATCH_REM_MAC = 0x0004,	/* Match by remote MAC address */
+	EFX_FILTER_MATCH_REM_PORT = 0x0008,	/* Match by remote TCP/UDP port */
+	EFX_FILTER_MATCH_LOC_MAC = 0x0010,	/* Match by remote TCP/UDP port */
+	EFX_FILTER_MATCH_LOC_PORT = 0x0020,	/* Match by local TCP/UDP port */
+	EFX_FILTER_MATCH_ETHER_TYPE = 0x0040,	/* Match by Ether-type */
+	EFX_FILTER_MATCH_INNER_VID = 0x0080,	/* Match by inner VLAN ID */
+	EFX_FILTER_MATCH_OUTER_VID = 0x0100,	/* Match by outer VLAN ID */
+	EFX_FILTER_MATCH_IP_PROTO = 0x0200,	/* Match by IP transport
+						 * protocol */
+	EFX_FILTER_MATCH_LOC_MAC_IG = 0x0400,	/* Match by local MAC address
+						 * I/G bit. Used for RX default
+						 * unicast and multicast/
+						 * broadcast filters. */
+} efx_filter_match_flags_t;
+
+typedef enum efx_filter_priority_s {
+	EFX_FILTER_PRI_HINT = 0,	/* Performance hint */
+	EFX_FILTER_PRI_AUTO,		/* Automatic filter based on device
+					 * address list or hardware
+					 * requirements. This may only be used
+					 * by the filter implementation for
+					 * each NIC type. */
+	EFX_FILTER_PRI_MANUAL,		/* Manually configured filter */
+	EFX_FILTER_PRI_REQUIRED,	/* Required for correct behaviour of the
+					 * client (e.g. SR-IOV, HyperV VMQ etc.)
+					 */
+} efx_filter_priority_t;
+
+/*
+ * FIXME: All these fields are assumed to be in little-endian byte order.
+ * It may be better for some to be big-endian. See bug42804.
+ */
+
+typedef struct efx_filter_spec_s {
+	uint32_t	efs_match_flags:12;
+	uint32_t	efs_priority:2;
+	uint32_t	efs_flags:6;
+	uint32_t	efs_dmaq_id:12;
+	uint32_t	efs_rss_context;
+	uint16_t	efs_outer_vid;
+	uint16_t	efs_inner_vid;
+	uint8_t		efs_loc_mac[EFX_MAC_ADDR_LEN];
+	uint8_t		efs_rem_mac[EFX_MAC_ADDR_LEN];
+	uint16_t	efs_ether_type;
+	uint8_t		efs_ip_proto;
+	uint16_t	efs_loc_port;
+	uint16_t	efs_rem_port;
+	efx_oword_t	efs_rem_host;
+	efx_oword_t	efs_loc_host;
+} efx_filter_spec_t;
+
+
+/* Default values for use in filter specifications */
+#define	EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT	0xffffffff
+#define	EFX_FILTER_SPEC_RX_DMAQ_ID_DROP		0xfff
+#define	EFX_FILTER_SPEC_VID_UNSPEC		0xffff
+
+extern	__checkReturn	efx_rc_t
+efx_filter_init(
+	__in		efx_nic_t *enp);
+
+extern			void
+efx_filter_fini(
+	__in		efx_nic_t *enp);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_insert(
+	__in		efx_nic_t *enp,
+	__inout		efx_filter_spec_t *spec);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_remove(
+	__in		efx_nic_t *enp,
+	__inout		efx_filter_spec_t *spec);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_restore(
+	__in		efx_nic_t *enp);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_supported_filters(
+	__in		efx_nic_t *enp,
+	__out		uint32_t *list,
+	__out		size_t *length);
+
+extern			void
+efx_filter_spec_init_rx(
+	__out		efx_filter_spec_t *spec,
+	__in		efx_filter_priority_t priority,
+	__in		efx_filter_flag_t flags,
+	__in		efx_rxq_t *erp);
+
+extern			void
+efx_filter_spec_init_tx(
+	__out		efx_filter_spec_t *spec,
+	__in		efx_txq_t *etp);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_ipv4_local(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint8_t proto,
+	__in		uint32_t host,
+	__in		uint16_t port);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_ipv4_full(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint8_t proto,
+	__in		uint32_t lhost,
+	__in		uint16_t lport,
+	__in		uint32_t rhost,
+	__in		uint16_t rport);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_eth_local(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint16_t vid,
+	__in		const uint8_t *addr);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_uc_def(
+	__inout		efx_filter_spec_t *spec);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_mc_def(
+	__inout		efx_filter_spec_t *spec);
+
+#endif	/* EFSYS_OPT_FILTER */
+
 /* HASH */
 
 extern	__checkReturn		uint32_t
diff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h
index 78cfd8e..555c184 100644
--- a/drivers/net/sfc/efx/base/efx_check.h
+++ b/drivers/net/sfc/efx/base/efx_check.h
@@ -59,6 +59,11 @@
 # error "FALCON_NIC_CFG_OVERRIDE is obsolete and is not supported."
 #endif
 
+#if EFSYS_OPT_FILTER
+/* Support hardware packet filters */
+#  error "FILTER requires SIENA or HUNTINGTON or MEDFORD"
+#endif /* EFSYS_OPT_FILTER */
+
 #ifdef EFSYS_OPT_MAC_FALCON_GMAC
 # error "MAC_FALCON_GMAC is obsolete and is not supported."
 #endif
diff --git a/drivers/net/sfc/efx/base/efx_filter.c b/drivers/net/sfc/efx/base/efx_filter.c
new file mode 100644
index 0000000..8ae865f
--- /dev/null
+++ b/drivers/net/sfc/efx/base/efx_filter.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_FILTER
+
+	__checkReturn	efx_rc_t
+efx_filter_insert(
+	__in		efx_nic_t *enp,
+	__inout		efx_filter_spec_t *spec)
+{
+	const efx_filter_ops_t *efop = enp->en_efop;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+	return (efop->efo_add(enp, spec, B_FALSE));
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_remove(
+	__in		efx_nic_t *enp,
+	__inout		efx_filter_spec_t *spec)
+{
+	const efx_filter_ops_t *efop = enp->en_efop;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+	return (efop->efo_delete(enp, spec));
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_restore(
+	__in		efx_nic_t *enp)
+{
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+	if ((rc = enp->en_efop->efo_restore(enp)) != 0)
+		goto fail1;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_init(
+	__in		efx_nic_t *enp)
+{
+	const efx_filter_ops_t *efop;
+	efx_rc_t rc;
+
+	/* Check that efx_filter_spec_t is 64 bytes. */
+	EFX_STATIC_ASSERT(sizeof (efx_filter_spec_t) == 64);
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_FILTER));
+
+	switch (enp->en_family) {
+
+	default:
+		EFSYS_ASSERT(0);
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if ((rc = efop->efo_init(enp)) != 0)
+		goto fail2;
+
+	enp->en_efop = efop;
+	enp->en_mod_flags |= EFX_MOD_FILTER;
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	enp->en_efop = NULL;
+	enp->en_mod_flags &= ~EFX_MOD_FILTER;
+	return (rc);
+}
+
+			void
+efx_filter_fini(
+	__in		efx_nic_t *enp)
+{
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+	enp->en_efop->efo_fini(enp);
+
+	enp->en_efop = NULL;
+	enp->en_mod_flags &= ~EFX_MOD_FILTER;
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_supported_filters(
+	__in		efx_nic_t *enp,
+	__out		uint32_t *list,
+	__out		size_t *length)
+{
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+	EFSYS_ASSERT(enp->en_efop->efo_supported_filters != NULL);
+
+	if ((rc = enp->en_efop->efo_supported_filters(enp, list, length)) != 0)
+		goto fail1;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_reconfigure(
+	__in				efx_nic_t *enp,
+	__in_ecount(6)			uint8_t const *mac_addr,
+	__in				boolean_t all_unicst,
+	__in				boolean_t mulcst,
+	__in				boolean_t all_mulcst,
+	__in				boolean_t brdcst,
+	__in_ecount(6*count)		uint8_t const *addrs,
+	__in				uint32_t count)
+{
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+	if (enp->en_efop->efo_reconfigure != NULL) {
+		if ((rc = enp->en_efop->efo_reconfigure(enp, mac_addr,
+							all_unicst, mulcst,
+							all_mulcst, brdcst,
+							addrs, count)) != 0)
+			goto fail1;
+	}
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+		void
+efx_filter_spec_init_rx(
+	__out		efx_filter_spec_t *spec,
+	__in		efx_filter_priority_t priority,
+	__in		efx_filter_flag_t flags,
+	__in		efx_rxq_t *erp)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3P(erp, !=, NULL);
+	EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
+				EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+
+	memset(spec, 0, sizeof (*spec));
+	spec->efs_priority = priority;
+	spec->efs_flags = EFX_FILTER_FLAG_RX | flags;
+	spec->efs_rss_context = EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT;
+	spec->efs_dmaq_id = (uint16_t)erp->er_index;
+}
+
+		void
+efx_filter_spec_init_tx(
+	__out		efx_filter_spec_t *spec,
+	__in		efx_txq_t *etp)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3P(etp, !=, NULL);
+
+	memset(spec, 0, sizeof (*spec));
+	spec->efs_priority = EFX_FILTER_PRI_REQUIRED;
+	spec->efs_flags = EFX_FILTER_FLAG_TX;
+	spec->efs_dmaq_id = (uint16_t)etp->et_index;
+}
+
+
+/*
+ *  Specify IPv4 host, transport protocol and port in a filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_ipv4_local(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint8_t proto,
+	__in		uint32_t host,
+	__in		uint16_t port)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+
+	spec->efs_match_flags |=
+		EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+		EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT;
+	spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
+	spec->efs_ip_proto = proto;
+	spec->efs_loc_host.eo_u32[0] = host;
+	spec->efs_loc_port = port;
+	return (0);
+}
+
+/*
+ * Specify IPv4 hosts, transport protocol and ports in a filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_ipv4_full(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint8_t proto,
+	__in		uint32_t lhost,
+	__in		uint16_t lport,
+	__in		uint32_t rhost,
+	__in		uint16_t rport)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+
+	spec->efs_match_flags |=
+		EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+		EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+		EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
+	spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
+	spec->efs_ip_proto = proto;
+	spec->efs_loc_host.eo_u32[0] = lhost;
+	spec->efs_loc_port = lport;
+	spec->efs_rem_host.eo_u32[0] = rhost;
+	spec->efs_rem_port = rport;
+	return (0);
+}
+
+/*
+ * Specify local Ethernet address and/or VID in filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_eth_local(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint16_t vid,
+	__in		const uint8_t *addr)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3P(addr, !=, NULL);
+
+	if (vid == EFX_FILTER_SPEC_VID_UNSPEC && addr == NULL)
+		return (EINVAL);
+
+	if (vid != EFX_FILTER_SPEC_VID_UNSPEC) {
+		spec->efs_match_flags |= EFX_FILTER_MATCH_OUTER_VID;
+		spec->efs_outer_vid = vid;
+	}
+	if (addr != NULL) {
+		spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC;
+		memcpy(spec->efs_loc_mac, addr, EFX_MAC_ADDR_LEN);
+	}
+	return (0);
+}
+
+/*
+ * Specify matching otherwise-unmatched unicast in a filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_uc_def(
+	__inout		efx_filter_spec_t *spec)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+
+	spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
+	return (0);
+}
+
+/*
+ * Specify matching otherwise-unmatched multicast in a filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_mc_def(
+	__inout		efx_filter_spec_t *spec)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+
+	spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
+	spec->efs_loc_mac[0] = 1;
+	return (0);
+}
+
+
+
+#endif /* EFSYS_OPT_FILTER */
diff --git a/drivers/net/sfc/efx/base/efx_impl.h b/drivers/net/sfc/efx/base/efx_impl.h
index 15bca37..47d4819 100644
--- a/drivers/net/sfc/efx/base/efx_impl.h
+++ b/drivers/net/sfc/efx/base/efx_impl.h
@@ -161,6 +161,33 @@ typedef struct efx_phy_ops_s {
 	efx_rc_t	(*epo_oui_get)(efx_nic_t *, uint32_t *);
 } efx_phy_ops_t;
 
+#if EFSYS_OPT_FILTER
+typedef struct efx_filter_ops_s {
+	efx_rc_t	(*efo_init)(efx_nic_t *);
+	void		(*efo_fini)(efx_nic_t *);
+	efx_rc_t	(*efo_restore)(efx_nic_t *);
+	efx_rc_t	(*efo_add)(efx_nic_t *, efx_filter_spec_t *,
+				   boolean_t may_replace);
+	efx_rc_t	(*efo_delete)(efx_nic_t *, efx_filter_spec_t *);
+	efx_rc_t	(*efo_supported_filters)(efx_nic_t *, uint32_t *, size_t *);
+	efx_rc_t	(*efo_reconfigure)(efx_nic_t *, uint8_t const *, boolean_t,
+				   boolean_t, boolean_t, boolean_t,
+				   uint8_t const *, uint32_t);
+} efx_filter_ops_t;
+
+extern	__checkReturn	efx_rc_t
+efx_filter_reconfigure(
+	__in				efx_nic_t *enp,
+	__in_ecount(6)			uint8_t const *mac_addr,
+	__in				boolean_t all_unicst,
+	__in				boolean_t mulcst,
+	__in				boolean_t all_mulcst,
+	__in				boolean_t brdcst,
+	__in_ecount(6*count)		uint8_t const *addrs,
+	__in				uint32_t count);
+
+#endif /* EFSYS_OPT_FILTER */
+
 
 typedef struct efx_port_s {
 	efx_mac_type_t		ep_mac_type;
@@ -245,6 +272,13 @@ typedef struct efx_nic_ops_s {
 #define	EFX_RXQ_DC_SIZE 3 /* 64 descriptors */
 #endif
 
+#if EFSYS_OPT_FILTER
+
+typedef struct efx_filter_s {
+} efx_filter_t;
+
+#endif	/* EFSYS_OPT_FILTER */
+
 typedef struct efx_drv_cfg_s {
 	uint32_t		edc_min_vi_count;
 	uint32_t		edc_max_vi_count;
@@ -274,6 +308,10 @@ struct efx_nic_s {
 	const efx_ev_ops_t	*en_eevop;
 	const efx_tx_ops_t	*en_etxop;
 	const efx_rx_ops_t	*en_erxop;
+#if EFSYS_OPT_FILTER
+	efx_filter_t		en_filter;
+	const efx_filter_ops_t	*en_efop;
+#endif	/* EFSYS_OPT_FILTER */
 	uint32_t		en_vport_id;
 	union {
 		int	enu_unused;
-- 
2.5.5

^ permalink raw reply related

* [PATCH 07/56] net/sfc: import libefx MCDI logging support
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

Driver can provide a function to be called to log MCDI
requests and responses to help with debugging.

Solarflare netlogdecode cross-platform tool may be used
to decode these logs.

EFSYS_OPT_MCDI_LOGGING should be enabled to use it.

>From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/base/efx.h       | 12 ++++++++++++
 drivers/net/sfc/efx/base/efx_check.h |  7 +++++++
 drivers/net/sfc/efx/base/efx_mcdi.c  | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)

diff --git a/drivers/net/sfc/efx/base/efx.h b/drivers/net/sfc/efx/base/efx.h
index 8b9d4d1..0ca0156 100644
--- a/drivers/net/sfc/efx/base/efx.h
+++ b/drivers/net/sfc/efx/base/efx.h
@@ -191,12 +191,24 @@ typedef enum efx_mcdi_exception_e {
 	EFX_MCDI_EXCEPTION_MC_BADASSERT,
 } efx_mcdi_exception_t;
 
+#if EFSYS_OPT_MCDI_LOGGING
+typedef enum efx_log_msg_e {
+	EFX_LOG_INVALID,
+	EFX_LOG_MCDI_REQUEST,
+	EFX_LOG_MCDI_RESPONSE,
+} efx_log_msg_t;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
 typedef struct efx_mcdi_transport_s {
 	void		*emt_context;
 	efsys_mem_t	*emt_dma_mem;
 	void		(*emt_execute)(void *, efx_mcdi_req_t *);
 	void		(*emt_ev_cpl)(void *);
 	void		(*emt_exception)(void *, efx_mcdi_exception_t);
+#if EFSYS_OPT_MCDI_LOGGING
+	void		(*emt_logger)(void *, efx_log_msg_t,
+					void *, size_t, void *, size_t);
+#endif /* EFSYS_OPT_MCDI_LOGGING */
 } efx_mcdi_transport_t;
 
 extern	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h
index 9d0e988..228b42c 100644
--- a/drivers/net/sfc/efx/base/efx_check.h
+++ b/drivers/net/sfc/efx/base/efx_check.h
@@ -77,6 +77,13 @@
 #  error "MCDI requires SIENA or HUNTINGTON or MEDFORD"
 #endif /* EFSYS_OPT_MCDI */
 
+#if EFSYS_OPT_MCDI_LOGGING
+/* Support MCDI logging */
+# if !EFSYS_OPT_MCDI
+#  error "MCDI_LOGGING requires MCDI"
+# endif
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
 #ifdef EFSYS_OPT_MON_LM87
 # error "MON_LM87 is obsolete and is not supported."
 #endif
diff --git a/drivers/net/sfc/efx/base/efx_mcdi.c b/drivers/net/sfc/efx/base/efx_mcdi.c
index 643ba6a..59a16fc 100644
--- a/drivers/net/sfc/efx/base/efx_mcdi.c
+++ b/drivers/net/sfc/efx/base/efx_mcdi.c
@@ -192,6 +192,9 @@ efx_mcdi_request_start(
 	__in		efx_mcdi_req_t *emrp,
 	__in		boolean_t ev_cpl)
 {
+#if EFSYS_OPT_MCDI_LOGGING
+	const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif
 	efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
 	efx_dword_t hdr[2];
 	size_t hdr_len;
@@ -268,6 +271,14 @@ efx_mcdi_request_start(
 		    MCDI_HEADER_XFLAGS, xflags);
 	}
 
+#if EFSYS_OPT_MCDI_LOGGING
+	if (emtp->emt_logger != NULL) {
+		emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST,
+		    &hdr[0], hdr_len,
+		    emrp->emr_in_buf, emrp->emr_in_length);
+	}
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
 	efx_mcdi_send_request(enp, &hdr[0], hdr_len,
 	    emrp->emr_in_buf, emrp->emr_in_length);
 }
@@ -278,6 +289,9 @@ efx_mcdi_read_response_header(
 	__in		efx_nic_t *enp,
 	__inout		efx_mcdi_req_t *emrp)
 {
+#if EFSYS_OPT_MCDI_LOGGING
+	const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
 	efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
 	efx_dword_t hdr[2];
 	unsigned int hdr_len;
@@ -338,6 +352,15 @@ efx_mcdi_read_response_header(
 		emrp->emr_err_code = err_code;
 		emrp->emr_err_arg = err_arg;
 
+#if EFSYS_OPT_MCDI_LOGGING
+		if (emtp->emt_logger != NULL) {
+			emtp->emt_logger(emtp->emt_context,
+			    EFX_LOG_MCDI_RESPONSE,
+			    &hdr[0], hdr_len,
+			    &err[0], err_len);
+		}
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
 		if (!emrp->emr_quiet) {
 			EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd,
 			    int, err_code, int, err_arg);
@@ -363,6 +386,9 @@ efx_mcdi_finish_response(
 	__in		efx_nic_t *enp,
 	__in		efx_mcdi_req_t *emrp)
 {
+#if EFSYS_OPT_MCDI_LOGGING
+	const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
 	efx_dword_t hdr[2];
 	unsigned int hdr_len;
 	size_t bytes;
@@ -389,6 +415,14 @@ efx_mcdi_finish_response(
 	bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length);
 	efx_mcdi_read_response(enp, emrp->emr_out_buf, hdr_len, bytes);
 
+#if EFSYS_OPT_MCDI_LOGGING
+	if (emtp->emt_logger != NULL) {
+		emtp->emt_logger(emtp->emt_context,
+		    EFX_LOG_MCDI_RESPONSE,
+		    &hdr[0], hdr_len,
+		    emrp->emr_out_buf, bytes);
+	}
+#endif /* EFSYS_OPT_MCDI_LOGGING */
 }
 
 
-- 
2.5.5

^ permalink raw reply related

* [PATCH 00/56] Solarflare libefx-based PMD
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev

The patch series adds Solarflare libefx-based network PMD.

This version of the driver supports Solarflare SFN7xxx and SFN8xxx
families of 10/40 Gbps adapters.

libefx is a platform-independent library to implement drivers for
Solarflare network adapters. It provides unified adapter family
independent interface (if possible). FreeBSD [1] and illumos [2]
drivers are built on top of the library.

The patch series could be logically structured into 5 sub-series:
 1. (1) add the driver skeleton including documentation
 2. (2-30) import libefx and include it in build with the latest patch
 3. (31-43) implement minimal device level operations in steps
 4. (44-51) implement Rx subsystem
 5. (52-56) implement Tx subsystem

Functional driver with multi-queue support capable to send and receive
traffic appears with the last patch in the series.

The following design decisions are made during development:

 1. Since libefx uses positive errno return codes, positive errno
    return codes are used inside the driver and coversion to negative
    is done on return from eth_dev_ops callbacks. We think that it
    is the less error-prone way.

 2. Another Solarflare PMD with in-kernel part (for control operations)
    is considered and could be added in the future. Code for data path
    should be shared by these two drivers. libefx-based PMD is put into
    'efx' subdirectory to have a space for another PMD and shared code.

 3. Own event queue (a way to deliver events from HW to host CPU) is
    used for house-keeping (e.g. link status notifications), each Tx
    and each Rx queue. No locks on datapath are requires in this case.

 4. Alarm is used to periodically poll house-keeping event queue.
    The event queue is used to deliver link status change notifications,
    Rx/Tx queue flush events, SRAM events. It is not used on datapath.
    The event queue polling is protected using spin-lock since
    concurrent access from different contexts is possible (e.g. device
    stop when polling alarm is running).

[1] https://svnweb.freebsd.org/base/head/sys/dev/sfxge/common/
[2] https://github.com/illumos/illumos-gate/tree/master/usr/src/uts/common/io/sfxge/common/

---

Andrew Rybchenko (49):
  net/sfc: libefx-based PMD stub sufficient to build and init
  net/sfc: import libefx base
  net/sfc: import libefx register definitions
  net/sfc: import libefx filters support
  net/sfc: import libefx MCDI definition
  net/sfc: import libefx MCDI implementation
  net/sfc: import libefx MCDI logging support
  net/sfc: import libefx MCDI proxy authorization support
  net/sfc: import libefx 5xxx/6xxx family support
  net/sfc: import libefx SFN7xxx family support
  net/sfc: import libefx SFN8xxx family support
  net/sfc: import libefx diagnostics support
  net/sfc: import libefx built-in selftest support
  net/sfc: import libefx software per-queue statistics support
  net/sfc: import libefx PHY flags control support
  net/sfc: import libefx PHY statistics support
  net/sfc: import libefx PHY LEDs control support
  net/sfc: import libefx MAC statistics support
  net/sfc: import libefx event prefetch support
  net/sfc: import libefx Rx scatter support
  net/sfc: import libefx RSS support
  net/sfc: import libefx loopback control support
  net/sfc: import libefx monitors statistics support
  net/sfc: import libefx support to access monitors via MCDI
  net/sfc: import libefx support for Rx packed stream mode
  net/sfc: import libefx NVRAM support
  net/sfc: import libefx VPD support
  net/sfc: import libefx bootrom configuration support
  net/sfc: import libefx licensing support
  net/sfc: implement dummy callback to get device information
  net/sfc: implement driver operation to init device on attach
  net/sfc: add device configure and close stubs
  net/sfc: add device configuration checks
  net/sfc: implement device start and stop operations
  net/sfc: make available resources estimation and allocation
  net/sfc: interrupts support sufficient for event queue init
  net/sfc: implement event queue support
  net/sfc: implement EVQ dummy exception handling
  net/sfc: maintain management event queue
  net/sfc: periodic management EVQ polling using alarm
  net/sfc: minimum port control sufficient to receive traffic
  net/sfc: implement Rx subsystem stubs
  net/sfc: check configured rxmode
  net/sfc: implement Rx queue setup release operations
  net/sfc: calculate Rx buffer size which may be used
  net/sfc: validate Rx queue buffers setup
  net/sfc: implement Rx queue start and stop operations
  net/sfc: implement device callback to Rx burst of packets
  net/sfc: discard scattered packet on Rx correctly

Artem Andreev (2):
  net/sfc: include libefx in build
  net/sfc: implement device operation to retrieve link info

Ivan Malov (5):
  net/sfc: provide basic stubs for Tx subsystem
  net/sfc: add function to check configured Tx mode
  net/sfc: add callbacks to set up and release Tx queues
  net/sfc: implement transmit path start / stop
  net/sfc: add callback to send bursts of packets

 MAINTAINERS                                     |     6 +
 config/common_base                              |     6 +
 config/defconfig_arm-armv7a-linuxapp-gcc        |     1 +
 config/defconfig_arm64-armv8a-linuxapp-gcc      |     1 +
 config/defconfig_i686-native-linuxapp-gcc       |     5 +
 config/defconfig_i686-native-linuxapp-icc       |     5 +
 config/defconfig_ppc_64-power8-linuxapp-gcc     |     1 +
 config/defconfig_tile-tilegx-linuxapp-gcc       |     1 +
 config/defconfig_x86_64-native-linuxapp-icc     |     5 +
 config/defconfig_x86_x32-native-linuxapp-gcc    |     5 +
 doc/guides/nics/features/sfc_efx.ini            |    13 +
 doc/guides/nics/index.rst                       |     1 +
 doc/guides/nics/sfc_efx.rst                     |   157 +
 drivers/net/Makefile                            |     1 +
 drivers/net/sfc/Makefile                        |    33 +
 drivers/net/sfc/efx/Makefile                    |   142 +
 drivers/net/sfc/efx/base/README                 |    36 +
 drivers/net/sfc/efx/base/ef10_ev.c              |  1401 ++
 drivers/net/sfc/efx/base/ef10_filter.c          |  1479 ++
 drivers/net/sfc/efx/base/ef10_impl.h            |  1182 ++
 drivers/net/sfc/efx/base/ef10_intr.c            |   197 +
 drivers/net/sfc/efx/base/ef10_mac.c             |   897 ++
 drivers/net/sfc/efx/base/ef10_mcdi.c            |   342 +
 drivers/net/sfc/efx/base/ef10_nic.c             |  1833 +++
 drivers/net/sfc/efx/base/ef10_nvram.c           |  2385 ++++
 drivers/net/sfc/efx/base/ef10_phy.c             |   631 +
 drivers/net/sfc/efx/base/ef10_rx.c              |   965 ++
 drivers/net/sfc/efx/base/ef10_tlv_layout.h      |   941 ++
 drivers/net/sfc/efx/base/ef10_tx.c              |   709 +
 drivers/net/sfc/efx/base/ef10_vpd.c             |   463 +
 drivers/net/sfc/efx/base/efx.h                  |  2503 ++++
 drivers/net/sfc/efx/base/efx_bootcfg.c          |   563 +
 drivers/net/sfc/efx/base/efx_check.h            |   346 +
 drivers/net/sfc/efx/base/efx_crc32.c            |   122 +
 drivers/net/sfc/efx/base/efx_ev.c               |  1470 ++
 drivers/net/sfc/efx/base/efx_filter.c           |  1402 ++
 drivers/net/sfc/efx/base/efx_hash.c             |   328 +
 drivers/net/sfc/efx/base/efx_impl.h             |  1206 ++
 drivers/net/sfc/efx/base/efx_intr.c             |   572 +
 drivers/net/sfc/efx/base/efx_lic.c              |  1751 +++
 drivers/net/sfc/efx/base/efx_mac.c              |   926 ++
 drivers/net/sfc/efx/base/efx_mcdi.c             |  2269 ++++
 drivers/net/sfc/efx/base/efx_mcdi.h             |   406 +
 drivers/net/sfc/efx/base/efx_mon.c              |   255 +
 drivers/net/sfc/efx/base/efx_nic.c              |  1062 ++
 drivers/net/sfc/efx/base/efx_nvram.c            |  1044 ++
 drivers/net/sfc/efx/base/efx_phy.c              |   561 +
 drivers/net/sfc/efx/base/efx_phy_ids.h          |    51 +
 drivers/net/sfc/efx/base/efx_port.c             |   252 +
 drivers/net/sfc/efx/base/efx_regs.h             |  3870 ++++++
 drivers/net/sfc/efx/base/efx_regs_ef10.h        |   571 +
 drivers/net/sfc/efx/base/efx_regs_mcdi.h        | 15690 ++++++++++++++++++++++
 drivers/net/sfc/efx/base/efx_regs_pci.h         |  2356 ++++
 drivers/net/sfc/efx/base/efx_rx.c               |  1315 ++
 drivers/net/sfc/efx/base/efx_sram.c             |   331 +
 drivers/net/sfc/efx/base/efx_tx.c               |  1089 ++
 drivers/net/sfc/efx/base/efx_types.h            |  1647 +++
 drivers/net/sfc/efx/base/efx_vpd.c              |  1016 ++
 drivers/net/sfc/efx/base/hunt_impl.h            |    74 +
 drivers/net/sfc/efx/base/hunt_nic.c             |   398 +
 drivers/net/sfc/efx/base/mcdi_mon.c             |   565 +
 drivers/net/sfc/efx/base/mcdi_mon.h             |    74 +
 drivers/net/sfc/efx/base/medford_impl.h         |    67 +
 drivers/net/sfc/efx/base/medford_nic.c          |   398 +
 drivers/net/sfc/efx/base/siena_flash.h          |   215 +
 drivers/net/sfc/efx/base/siena_impl.h           |   431 +
 drivers/net/sfc/efx/base/siena_mac.c            |   476 +
 drivers/net/sfc/efx/base/siena_mcdi.c           |   263 +
 drivers/net/sfc/efx/base/siena_nic.c            |   581 +
 drivers/net/sfc/efx/base/siena_nvram.c          |   734 +
 drivers/net/sfc/efx/base/siena_phy.c            |   797 ++
 drivers/net/sfc/efx/base/siena_sram.c           |   178 +
 drivers/net/sfc/efx/base/siena_vpd.c            |   618 +
 drivers/net/sfc/efx/efsys.h                     |   767 ++
 drivers/net/sfc/efx/rte_pmd_sfc_efx_version.map |     4 +
 drivers/net/sfc/efx/sfc.c                       |   571 +
 drivers/net/sfc/efx/sfc.h                       |   236 +
 drivers/net/sfc/efx/sfc_debug.h                 |    57 +
 drivers/net/sfc/efx/sfc_ethdev.c                |   465 +
 drivers/net/sfc/efx/sfc_ev.c                    |   688 +
 drivers/net/sfc/efx/sfc_ev.h                    |   144 +
 drivers/net/sfc/efx/sfc_intr.c                  |   129 +
 drivers/net/sfc/efx/sfc_kvargs.c                |   108 +
 drivers/net/sfc/efx/sfc_kvargs.h                |    58 +
 drivers/net/sfc/efx/sfc_log.h                   |    72 +
 drivers/net/sfc/efx/sfc_mcdi.c                  |   197 +
 drivers/net/sfc/efx/sfc_port.c                  |   189 +
 drivers/net/sfc/efx/sfc_rx.c                    |   803 ++
 drivers/net/sfc/efx/sfc_rx.h                    |   145 +
 drivers/net/sfc/efx/sfc_tweak.h                 |    51 +
 drivers/net/sfc/efx/sfc_tx.c                    |   646 +
 drivers/net/sfc/efx/sfc_tx.h                    |   124 +
 mk/rte.app.mk                                   |     1 +
 93 files changed, 70142 insertions(+)
 create mode 100644 doc/guides/nics/features/sfc_efx.ini
 create mode 100644 doc/guides/nics/sfc_efx.rst
 create mode 100644 drivers/net/sfc/Makefile
 create mode 100644 drivers/net/sfc/efx/Makefile
 create mode 100644 drivers/net/sfc/efx/base/README
 create mode 100644 drivers/net/sfc/efx/base/ef10_ev.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_filter.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_impl.h
 create mode 100644 drivers/net/sfc/efx/base/ef10_intr.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_mac.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_mcdi.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_nic.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_nvram.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_phy.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_rx.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_tlv_layout.h
 create mode 100644 drivers/net/sfc/efx/base/ef10_tx.c
 create mode 100644 drivers/net/sfc/efx/base/ef10_vpd.c
 create mode 100644 drivers/net/sfc/efx/base/efx.h
 create mode 100644 drivers/net/sfc/efx/base/efx_bootcfg.c
 create mode 100644 drivers/net/sfc/efx/base/efx_check.h
 create mode 100644 drivers/net/sfc/efx/base/efx_crc32.c
 create mode 100644 drivers/net/sfc/efx/base/efx_ev.c
 create mode 100644 drivers/net/sfc/efx/base/efx_filter.c
 create mode 100644 drivers/net/sfc/efx/base/efx_hash.c
 create mode 100644 drivers/net/sfc/efx/base/efx_impl.h
 create mode 100644 drivers/net/sfc/efx/base/efx_intr.c
 create mode 100644 drivers/net/sfc/efx/base/efx_lic.c
 create mode 100644 drivers/net/sfc/efx/base/efx_mac.c
 create mode 100644 drivers/net/sfc/efx/base/efx_mcdi.c
 create mode 100644 drivers/net/sfc/efx/base/efx_mcdi.h
 create mode 100644 drivers/net/sfc/efx/base/efx_mon.c
 create mode 100644 drivers/net/sfc/efx/base/efx_nic.c
 create mode 100644 drivers/net/sfc/efx/base/efx_nvram.c
 create mode 100644 drivers/net/sfc/efx/base/efx_phy.c
 create mode 100644 drivers/net/sfc/efx/base/efx_phy_ids.h
 create mode 100644 drivers/net/sfc/efx/base/efx_port.c
 create mode 100644 drivers/net/sfc/efx/base/efx_regs.h
 create mode 100644 drivers/net/sfc/efx/base/efx_regs_ef10.h
 create mode 100644 drivers/net/sfc/efx/base/efx_regs_mcdi.h
 create mode 100644 drivers/net/sfc/efx/base/efx_regs_pci.h
 create mode 100644 drivers/net/sfc/efx/base/efx_rx.c
 create mode 100644 drivers/net/sfc/efx/base/efx_sram.c
 create mode 100644 drivers/net/sfc/efx/base/efx_tx.c
 create mode 100644 drivers/net/sfc/efx/base/efx_types.h
 create mode 100644 drivers/net/sfc/efx/base/efx_vpd.c
 create mode 100644 drivers/net/sfc/efx/base/hunt_impl.h
 create mode 100644 drivers/net/sfc/efx/base/hunt_nic.c
 create mode 100644 drivers/net/sfc/efx/base/mcdi_mon.c
 create mode 100644 drivers/net/sfc/efx/base/mcdi_mon.h
 create mode 100644 drivers/net/sfc/efx/base/medford_impl.h
 create mode 100644 drivers/net/sfc/efx/base/medford_nic.c
 create mode 100644 drivers/net/sfc/efx/base/siena_flash.h
 create mode 100644 drivers/net/sfc/efx/base/siena_impl.h
 create mode 100644 drivers/net/sfc/efx/base/siena_mac.c
 create mode 100644 drivers/net/sfc/efx/base/siena_mcdi.c
 create mode 100644 drivers/net/sfc/efx/base/siena_nic.c
 create mode 100644 drivers/net/sfc/efx/base/siena_nvram.c
 create mode 100644 drivers/net/sfc/efx/base/siena_phy.c
 create mode 100644 drivers/net/sfc/efx/base/siena_sram.c
 create mode 100644 drivers/net/sfc/efx/base/siena_vpd.c
 create mode 100644 drivers/net/sfc/efx/efsys.h
 create mode 100644 drivers/net/sfc/efx/rte_pmd_sfc_efx_version.map
 create mode 100644 drivers/net/sfc/efx/sfc.c
 create mode 100644 drivers/net/sfc/efx/sfc.h
 create mode 100644 drivers/net/sfc/efx/sfc_debug.h
 create mode 100644 drivers/net/sfc/efx/sfc_ethdev.c
 create mode 100644 drivers/net/sfc/efx/sfc_ev.c
 create mode 100644 drivers/net/sfc/efx/sfc_ev.h
 create mode 100644 drivers/net/sfc/efx/sfc_intr.c
 create mode 100644 drivers/net/sfc/efx/sfc_kvargs.c
 create mode 100644 drivers/net/sfc/efx/sfc_kvargs.h
 create mode 100644 drivers/net/sfc/efx/sfc_log.h
 create mode 100644 drivers/net/sfc/efx/sfc_mcdi.c
 create mode 100644 drivers/net/sfc/efx/sfc_port.c
 create mode 100644 drivers/net/sfc/efx/sfc_rx.c
 create mode 100644 drivers/net/sfc/efx/sfc_rx.h
 create mode 100644 drivers/net/sfc/efx/sfc_tweak.h
 create mode 100644 drivers/net/sfc/efx/sfc_tx.c
 create mode 100644 drivers/net/sfc/efx/sfc_tx.h

-- 
2.5.5

^ permalink raw reply

* Re: [PATCH v2] nfp: report link speed using hardware info
From: Alejandro Lucero @ 2016-11-21 14:47 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev
In-Reply-To: <c50c9f50-5391-6d02-34c6-17abe1e2fb51@intel.com>

On Mon, Nov 21, 2016 at 11:18 AM, Ferruh Yigit <ferruh.yigit@intel.com>
wrote:

> On 11/18/2016 4:06 PM, Alejandro Lucero wrote:
> > Previous reported speed was hardcoded.
> >
> > Signed-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>
> > ---
> >  drivers/net/nfp/nfp_net.c      | 28 ++++++++++++++++++++++++++--
> >  drivers/net/nfp/nfp_net_ctrl.h | 13 +++++++++++++
> >  2 files changed, 39 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
> > index c6b1587..24f3164 100644
> > --- a/drivers/net/nfp/nfp_net.c
> > +++ b/drivers/net/nfp/nfp_net.c
> > @@ -816,6 +816,17 @@ static void nfp_net_read_mac(struct nfp_net_hw *hw)
> >       struct rte_eth_link link, old;
> >       uint32_t nn_link_status;
> >
> > +     static const uint32_t ls_to_ethtool[] = {
> > +             [NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] =
> ETH_SPEED_NUM_NONE,
> > +             [NFP_NET_CFG_STS_LINK_RATE_UNKNOWN]     =
> ETH_SPEED_NUM_NONE,
> > +             [NFP_NET_CFG_STS_LINK_RATE_1G]          = ETH_SPEED_NUM_1G,
> > +             [NFP_NET_CFG_STS_LINK_RATE_10G]         =
> ETH_SPEED_NUM_10G,
> > +             [NFP_NET_CFG_STS_LINK_RATE_25G]         =
> ETH_SPEED_NUM_25G,
> > +             [NFP_NET_CFG_STS_LINK_RATE_40G]         =
> ETH_SPEED_NUM_40G,
> > +             [NFP_NET_CFG_STS_LINK_RATE_50G]         =
> ETH_SPEED_NUM_50G,
> > +             [NFP_NET_CFG_STS_LINK_RATE_100G]        =
> ETH_SPEED_NUM_100G,
> > +     };
> > +
> >       PMD_DRV_LOG(DEBUG, "Link update\n");
> >
> >       hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> > @@ -831,8 +842,21 @@ static void nfp_net_read_mac(struct nfp_net_hw *hw)
> >               link.link_status = ETH_LINK_UP;
> >
> >       link.link_duplex = ETH_LINK_FULL_DUPLEX;
> > -     /* Other cards can limit the tx and rx rate per VF */
> > -     link.link_speed = ETH_SPEED_NUM_40G;
> > +
> > +     nn_link_status = (nn_link_status >> NFP_NET_CFG_STS_LINK_RATE_SHIFT)
> &
> > +                      NFP_NET_CFG_STS_LINK_RATE_MASK;
> > +
> > +     if ((NFD_CFG_MAJOR_VERSION_of(hw->ver) < 4) ||
> > +         ((NFD_CFG_MINOR_VERSION_of(hw->ver) == 4) &&
> > +         (NFD_CFG_MINOR_VERSION_of(hw->ver) == 0)))
> > +             link.link_speed = ETH_SPEED_NUM_40G;
>
> For specific firmware version, speed is still hardcoded to 40G, can you
> please mention from this and if possible its reason in commit log?
>
> > +     else {
> > +             if (nn_link_status == NFP_NET_CFG_STS_LINK_RATE_UNKNOWN ||
>
> This check can be redundant, since
> ls_to_ethtool[NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] => ETH_SPEED_NUM_NONE
>
>
This is for checking any wrong value from firmware/hardware.


> > +                 nn_link_status >= RTE_DIM(ls_to_ethtool))
> > +                     link.link_speed = ETH_SPEED_NUM_NONE;
> > +             else
> > +                     link.link_speed = ls_to_ethtool[nn_link_status];
> > +     }
> >
> >       if (old.link_status != link.link_status) {
> >               nfp_net_dev_atomic_write_link_status(dev, &link);
> > diff --git a/drivers/net/nfp/nfp_net_ctrl.h b/drivers/net/nfp/nfp_net_
> ctrl.h
> > index fce8251..f9aaba3 100644
> > --- a/drivers/net/nfp/nfp_net_ctrl.h
> > +++ b/drivers/net/nfp/nfp_net_ctrl.h
> > @@ -157,6 +157,19 @@
> >  #define   NFP_NET_CFG_VERSION_MINOR(x)    (((x) & 0xff) <<  0)
> >  #define NFP_NET_CFG_STS                 0x0034
> >  #define   NFP_NET_CFG_STS_LINK            (0x1 << 0) /* Link up or down
> */
> > +/* Link rate */
> > +#define   NFP_NET_CFG_STS_LINK_RATE_SHIFT 1
> > +#define   NFP_NET_CFG_STS_LINK_RATE_MASK  0xF
> > +#define   NFP_NET_CFG_STS_LINK_RATE       \
> > +       (NFP_NET_CFG_STS_LINK_RATE_MASK << NFP_NET_CFG_STS_LINK_RATE_
> SHIFT)
>
> This macro is not used at all, just fyi.
>
>
Thanks. I think I can remove it.


> > +#define   NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED   0
> > +#define   NFP_NET_CFG_STS_LINK_RATE_UNKNOWN       1
> > +#define   NFP_NET_CFG_STS_LINK_RATE_1G            2
> > +#define   NFP_NET_CFG_STS_LINK_RATE_10G           3
> > +#define   NFP_NET_CFG_STS_LINK_RATE_25G           4
> > +#define   NFP_NET_CFG_STS_LINK_RATE_40G           5
> > +#define   NFP_NET_CFG_STS_LINK_RATE_50G           6
> > +#define   NFP_NET_CFG_STS_LINK_RATE_100G          7
> >  #define NFP_NET_CFG_CAP                 0x0038
> >  #define NFP_NET_CFG_MAX_TXRINGS         0x003c
> >  #define NFP_NET_CFG_MAX_RXRINGS         0x0040
> >
>
>

^ permalink raw reply

* Re: Adding API to force freeing consumed buffers in TX ring
From: Wiles, Keith @ 2016-11-21 14:33 UTC (permalink / raw)
  To: Damjan Marion (damarion); +Cc: dev@dpdk.org
In-Reply-To: <7E8AE555-F016-4F33-B046-A5DA86F493F3@cisco.com>


> On Nov 21, 2016, at 4:48 AM, Damjan Marion (damarion) <damarion@cisco.com> wrote:
> 
> 
> Hi,
> 
> Currently in VPP we do memcpy of whole packet when we need to do 
> replication as we cannot know if specific buffer is transmitted
> from tx ring before we update it again (i.e. l2 header rewrite).
> 
> Unless there is already a way to address this issue in DPDK which I’m not aware
> of my proposal is that we provide mechanism for polling TX ring 
> for consumed buffers. This can be either completely new API or 
> extension of rte_etx_tx_burst (i.e. special case when nb_pkts=0).
> 
> This will allows us to start polling tx ring when we expect some 
> mbuf back, instead of waiting for next tx burst (which we don’t know
> when it will happen) and hoping that we will reach free_threshold soon.

+1

In Pktgen I have the problem of not being able to reclaim all of the TX mbufs to update them for the next set of packets to send. I know this is not a common case, but I do see the case where the application needs its mbufs freed off the TX ring. Currently you need to have at least a TX ring size of mbufs on hand to make sure you can send to a TX ring. If you allocate too few you run into a deadlock case as the number of mbufs  on a TX ring does not hit the flush mark. If you are sending to multiple TX rings on the same numa node from the a single TX pool you have to understand the total number of mbufs you need to have allocated to hit the TX flush on each ring. Not a clean way to handle the problems as you may have limited memory or require some logic to add more mbufs for dynamic ports.

Anyway it would be great to require a way to clean up the TX done ring, using nb_pkts == 0 is the simplest way, but a new API is fine too.
> 
> Any thoughts?
> 
> Thanks,
> 
> Damjan
> 
> 
> 

Regards,
Keith


^ permalink raw reply

* Re: [PATCH v3] ntnic: add PMD driver
From: Finn Christensen @ 2016-11-21 13:55 UTC (permalink / raw)
  To: Ferruh Yigit, Thomas Monjalon
  Cc: Neil Horman, dev@dpdk.org, stephen@networkplumber.org
In-Reply-To: <bb63f27f-2cbd-7326-3118-f18b53dbad64@intel.com>

I have changed the state to rejected. Sorry for not doing this earlier.

Finn Christensen


-----Original Message-----
From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
Sent: 21. november 2016 14:48
To: Finn Christensen <fc@napatech.com>; Thomas Monjalon <thomas.monjalon@6wind.com>
Cc: Neil Horman <nhorman@tuxdriver.com>; dev@dpdk.org; stephen@networkplumber.org
Subject: Re: [dpdk-dev] [PATCH v3] ntnic: add PMD driver

On 9/12/2016 8:34 AM, fc at napatech.com (Finn Christensen) wrote:
>> -----Original Message-----
>> From: Thomas Monjalon [mailto:thomas.monjalon at 6wind.com]
>> Sent: 10. september 2016 10:20
>> To: Finn Christensen <fc at napatech.com>
>> Cc: Neil Horman <nhorman at tuxdriver.com>; dev at dpdk.org; stephen
>> at networkplumber.org
>> Subject: Re: [PATCH v3] ntnic: add PMD driver
>>
>> 2016-09-10 07:58, Finn Christensen:
>>> From: Neil Horman [mailto:nhorman at tuxdriver.com]
>>>> On Fri, Sep 09, 2016 at 12:48:38PM +0000, Finn Christensen wrote:
>>>>> This is the Napatech NTNIC Poll Mode Driver (PMD) for DPDK.
>>>>>
>>>>> This patch adds support for Napatech NICs to DPDK. This is the
>>>>> initial implementation.
>>>>>
>>>>> Signed-off-by: Finn Christensen <fc at napatech.com>
>>>>> ---
>>>>> v3:
>>>>>   * Removed the need for binary libraries on build
>>>>> v2:
>>>>>   * Added information how to build the PMD without NIC
>>>>>     Board Support Package
>>>>>   * Fixed some formatting issues
>>>>
>>>> So, this is a step in the right direction, but I think its solving
>>>> the wrong problem.  If you have a dependency on an external
>>>> library, thats ok, and accessing it via dlopen makes it possible to
>>>> build the library without having that library present, but it not
>>>> really in keeping with the spirit of what I meant.  This driver is
>>>> still effectively dependent on a binary blob that we have no
>>>> visibility into.  The better solution is releasing the source for
>>>> the ntnic and ntos libraries.  The license file in the referenced
>>>> git tree indicates its BSD licensed, so I don't think there should
>>>> be a problem in
>> doing that.
>>>>
>>>> Neil
>>>>
>>> No, unfortunately the ntapi is not BSD licensed, only the header
>>> files that you can freely download are.
>>> We are building this NT NIC by using parts or our technology from
>>> our capture adapters and that is using closed source software.
>>>
>>> We are new to opensource and we want to go that way, but we haven't
>>> yet a complete stand-alone driver ready that we can put into the
>>> DPDK PMD to have a complete self contained and open sourced DPDK
>>> PMD, that only needs the actual HW NIC plugged in to run.
>>> Therefore this version is implemented as a virtual device, exactly
>>> like the PCAP PMD driver is, and it runs on top of a driver that
>>> follows the
>> NIC itself.
>>>
>>> In regards to the DPDK functionality we do not see that anything is missing.
>>> I cannot either see where we should add source code, because it is
>>> not part of the DPDK package and it should not be either.
>>>
>>> One of the things I really liked about the DPDK open source project
>>> is that it uses BSD licensing not GPL. Therefore, I must admit, we
>>> completely failed to see that the "spirit" of the DPDK community is
>>> not really BSD. Our view of this community was that the main driving
>>> force of it was to be able to make DPDK run on everything anywhere
>>> effectively, in a global contributing community, without  any
>>> legally
>> constrains prohibiting us to do so.
>>
>> It is difficult to define what is the spirit of a community,
>> especially only after few mail exchanges.
>> I agree that running on everything anywhere is a nice goal.
>> Here Neil, as a RedHat developer, is probably concerned about
>> enabling your driver in a distribution. It seems your model is not
>> compatible with the "anywhere goal" and will be disabled in that case, until it is fully open.
>
> The ntnic PMD is not enabled by default and I think it should not be
> either. To enable it in a distribution for general purposes seems
> wrong. In that respect we see no difference between the PCAP PMD and this ntnic PMD.
>
>>> However, this is our standing, and I don't know what else to do.
>>> Please advise or NAK this PMD.
>>
>> I do not remember having already seen such model in DPDK.
>> So we need to think about the implications a bit more.
>> (Comments/discussions are welcome)
>> Thanks for your patience.
>
> Thanks. I will be happy to discuss this further, so that we can get to a conclusion.
> If the outcome is that the majority of the community does not like the
> idea that upstream supported PMDs has external linking dependencies to
> closed source libraries, then it is ok with us(a pity though). But
> then it might be a good idea to make that decision clear to everybody
> else by putting in a clause into the contribution section of the DPDK guide, or somewhere else in the guide.
>
> In our opinion, the inclusion of the ntnic PMD into upstream DPDK,
> does not seem to be any different than that of the PCAP PMD, since
> that is also dependent on external header files and externally built libraries.
> Of course we see the difference in open source vs close source
> library. But we cannot see that is has any influence in the usage or functionality of the DPDK.
>
> Thanks for this discussion!
>

The patch is still waiting in the patchwork.

This requires a high level discussion. Any suggestion on how to proceed?

Disclaimer: This email and any files transmitted with it may contain confidential information intended for the addressee(s) only. The information is not to be surrendered or copied to unauthorized persons. If you have received this communication in error, please notify the sender immediately and delete this e-mail from your system.

^ permalink raw reply

* Re: [PATCH RFC 0/2] Allow vectorized Rx with 4096 desc ring size on Intel NICs.
From: Ferruh Yigit @ 2016-11-21 13:53 UTC (permalink / raw)
  To: Ilya Maximets, dev, Helin Zhang, Konstantin Ananyev, Jingjing Wu
  Cc: Dyasly Sergey, Heetae Ahn, Bruce Richardson, Wenzhuo Lu
In-Reply-To: <1e91c159-3075-2564-c32c-86dae4ee7916@intel.com>

On 10/19/2016 3:30 PM, Ferruh Yigit wrote:
> On 10/19/2016 3:07 PM, Ilya Maximets wrote:
>> Ilya Maximets (2):
>>   net/i40e: allow bulk alloc for the max size desc ring
>>   net/ixgbe: allow bulk alloc for the max size desc ring
>>
>>  drivers/net/i40e/i40e_rxtx.c   | 24 +++++++++++++-----------
>>  drivers/net/ixgbe/ixgbe_rxtx.c | 17 +----------------
>>  drivers/net/ixgbe/ixgbe_rxtx.h |  2 +-
>>  3 files changed, 15 insertions(+), 28 deletions(-)
>>
> 
> Hi Ilya,
> 
> Thank you for the patch, we are in post rc1 phase and this is a new
> feature, so this patchset will be considered for next release (v17.02).
> 

Reminder for this patch (RFC) which has been sent in 16.11 time frame
and we postponed to 17.02 release.

Thanks,
ferruh

^ permalink raw reply

* Re: [PATCH v3] ntnic: add PMD driver
From: Ferruh Yigit @ 2016-11-21 13:47 UTC (permalink / raw)
  To: Finn Christensen, Thomas Monjalon; +Cc: Neil Horman, dev, stephen
In-Reply-To: <9b58ce3a52404addaa2f1d972f345097@napatech.com>

On 9/12/2016 8:34 AM, fc at napatech.com (Finn Christensen) wrote:
>> -----Original Message-----
>> From: Thomas Monjalon [mailto:thomas.monjalon at 6wind.com]
>> Sent: 10. september 2016 10:20
>> To: Finn Christensen <fc at napatech.com>
>> Cc: Neil Horman <nhorman at tuxdriver.com>; dev at dpdk.org;
>> stephen at networkplumber.org
>> Subject: Re: [PATCH v3] ntnic: add PMD driver
>>
>> 2016-09-10 07:58, Finn Christensen:
>>> From: Neil Horman [mailto:nhorman at tuxdriver.com]
>>>> On Fri, Sep 09, 2016 at 12:48:38PM +0000, Finn Christensen wrote:
>>>>> This is the Napatech NTNIC Poll Mode Driver (PMD) for DPDK.
>>>>>
>>>>> This patch adds support for Napatech NICs to DPDK. This is the
>>>>> initial implementation.
>>>>>
>>>>> Signed-off-by: Finn Christensen <fc at napatech.com>
>>>>> ---
>>>>> v3:
>>>>>   * Removed the need for binary libraries on build
>>>>> v2:
>>>>>   * Added information how to build the PMD without NIC
>>>>>     Board Support Package
>>>>>   * Fixed some formatting issues
>>>>
>>>> So, this is a step in the right direction, but I think its solving
>>>> the wrong problem.  If you have a dependency on an external library,
>>>> thats ok, and accessing it via dlopen makes it possible to build the
>>>> library without having that library present, but it not really in
>>>> keeping with the spirit of what I meant.  This driver is still
>>>> effectively dependent on a binary blob that we have no visibility
>>>> into.  The better solution is releasing the source for the ntnic and
>>>> ntos libraries.  The license file in the referenced git tree
>>>> indicates its BSD licensed, so I don't think there should be a problem in
>> doing that.
>>>>
>>>> Neil
>>>>
>>> No, unfortunately the ntapi is not BSD licensed, only the header files
>>> that you can freely download are.
>>> We are building this NT NIC by using parts or our technology from our
>>> capture adapters and that is using closed source software.
>>>
>>> We are new to opensource and we want to go that way, but we haven't
>>> yet a complete stand-alone driver ready that we can put into the DPDK
>>> PMD to have a complete self contained and open sourced DPDK PMD, that
>>> only needs the actual HW NIC plugged in to run.
>>> Therefore this version is implemented as a virtual device, exactly
>>> like the PCAP PMD driver is, and it runs on top of a driver that follows the
>> NIC itself.
>>>
>>> In regards to the DPDK functionality we do not see that anything is missing.
>>> I cannot either see where we should add source code, because it is not
>>> part of the DPDK package and it should not be either.
>>>
>>> One of the things I really liked about the DPDK open source project is
>>> that it uses BSD licensing not GPL. Therefore, I must admit, we
>>> completely failed to see that the "spirit" of the DPDK community is
>>> not really BSD. Our view of this community was that the main driving
>>> force of it was to be able to make DPDK run on everything anywhere
>>> effectively, in a global contributing community, without  any legally
>> constrains prohibiting us to do so.
>>
>> It is difficult to define what is the spirit of a community, especially only after
>> few mail exchanges.
>> I agree that running on everything anywhere is a nice goal.
>> Here Neil, as a RedHat developer, is probably concerned about enabling your
>> driver in a distribution. It seems your model is not compatible with the
>> "anywhere goal" and will be disabled in that case, until it is fully open.
> 
> The ntnic PMD is not enabled by default and I think it should not be either. To
> enable it in a distribution for general purposes seems wrong. In that respect
> we see no difference between the PCAP PMD and this ntnic PMD.
> 
>>> However, this is our standing, and I don't know what else to do.
>>> Please advise or NAK this PMD.
>>
>> I do not remember having already seen such model in DPDK.
>> So we need to think about the implications a bit more.
>> (Comments/discussions are welcome)
>> Thanks for your patience.
> 
> Thanks. I will be happy to discuss this further, so that we can get to a conclusion.
> If the outcome is that the majority of the community does not like the idea that
> upstream supported PMDs has external linking dependencies to closed source
> libraries, then it is ok with us(a pity though). But then it might be a good idea to
> make that decision clear to everybody else by putting in a clause into the
> contribution section of the DPDK guide, or somewhere else in the guide.
> 
> In our opinion, the inclusion of the ntnic PMD into upstream DPDK, does not
> seem to be any different than that of the PCAP PMD, since that is also
> dependent on external header files and externally built libraries.
> Of course we see the difference in open source vs close source library. But we
> cannot see that is has any influence in the usage or functionality of the DPDK.
> 
> Thanks for this discussion!
> 

The patch is still waiting in the patchwork.

This requires a high level discussion. Any suggestion on how to proceed?

^ permalink raw reply

* [PATCH] examples/ip_pipeline: fix load balancing function in pass-through pipeline
From: Jasvinder Singh @ 2016-11-21 13:37 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This patch fixes the configuration file parsing error when load balancing
function is enabled in pass-through pipeline.

error log:
pipeline> [APP] Initializing PIPELINE1 ...
[PIPELINE1] Pass-through
Parse error in section "PIPELINE1": entry "lb" has invalid value ("hash")

Fixes: cbe82f6cfb0a ("examples/ip_pipeline: add swap action in pass-through")

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/pipeline/pipeline_passthrough_be.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
index 8b71a7d..7ab0afe 100644
--- a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
@@ -589,7 +589,7 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
 				params->name, arg_name);
 			dma_hash_lb_present = 1;
 
-			if (strcmp(arg_value, "hash") ||
+			if (strcmp(arg_value, "hash") &&
 				strcmp(arg_value, "HASH"))
 
 				PIPELINE_PARSE_ERR_INV_VAL(0,
-- 
2.5.5

^ permalink raw reply related

* Re: [dpdk-stable] [PATCH] Revert "bonding: use existing enslaved device queues"
From: Ilya Maximets @ 2016-11-21 13:11 UTC (permalink / raw)
  To: Jan Blunck, Ferruh Yigit
  Cc: Bruce Richardson, Declan Doherty, Eric Kinzie, dev, Heetae Ahn,
	Yuanhan Liu, Bernard Iremonger, stable, Thomas Monjalon
In-Reply-To: <e298faba-701c-54bf-5913-3dea032b1966@samsung.com>

To be clear, I still insist on applying this path as is.

Best regards, Ilya Maximets.

On 21.11.2016 15:49, Ilya Maximets wrote:
> On 21.11.2016 14:39, Jan Blunck wrote:
>> Ferruh,
>>
>> I've been working on a patch but was distracted by other stuff and
>> therefore haven't tested it yet.
> 
> Jan, on what patch are you working? I don't understand.
> 
>>
>> Stay tuned,
>> Jan
>>
>> On Mon, Nov 21, 2016 at 12:30 PM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>>
>>> Is there an update for this patch? Is a consensus reached?
> 
> Ferruh, I didn't receive any response on my e-mails. I've pinged this thread
> few times, but didn't receive any feedback and I have no idea what patch Jan
> talking about.
> 
> Best regards, Ilya Maximets.
> 

^ permalink raw reply

* 16.07.2 stable patches review and test
From: Yuanhan Liu @ 2016-11-21 13:05 UTC (permalink / raw)
  To: dpdk stable; +Cc: dev

Hi all,

Here is a list of patches targeted for 16.07.2 release. Please help
reviewing and testing. The planned date for the final release is 30th,
Nov. Before that, please shout if anyone has objections with these
patches being applied, or if I missed some important fixes.

These patches are located at branch 16.07 of dpdk-stable repo:
    http://dpdk.org/browse/dpdk-stable/

Please also be noted that this would be the last stable release for 16.07.

Thanks.

	--yliu

---
Adrien Mazarguil (1):
      net/mlx5: fix Rx VLAN offload capability report

Ajit Khaparde (1):
      net/bnxt: fix crash when closing

Beilei Xing (1):
      net/i40e: fix floating VEB

Bernard Iremonger (1):
      app/testpmd: fix DCB configuration

David Marchand (1):
      ethdev: fix vendor id in debug message

E. Scott Daniels (1):
      ethdev: prevent duplicate event callback

Eric Kinzie (1):
      net/bonding: validate speed after link up

Ferruh Yigit (4):
      net/ring: fix ring device creation via devargs
      net/bnx2x: fix build with icc
      kni: fix build with kernel 4.8
      kni: fix build with kernel 4.9

Gowrishankar Muthukrishnan (1):
      examples/ip_pipeline: fix plugin loading

Igor Ryzhov (1):
      pci: fix probing error if no driver found

Jasvinder Singh (1):
      examples/qos_sched: fix dequeue from ring

Jeff Guo (1):
      net/i40e: fix hash filter on X722

Jianbo Liu (2):
      eal/arm: fix file descriptor leak when getting CPU features
      eal/ppc: fix file descriptor leak when getting CPU features

Jingjing Wu (2):
      net/i40e: fix DCB configuration
      doc: add limitations for i40e PMD

John Daley (5):
      net/enic: fix flow director
      net/enic: fix crash with removed flow director filters
      net/enic: fix multi-queue Rx performance
      net/enic: fix crash on MTU update or Rx queue reconfigure
      net/enic: fix max packet length check

John W. Linville (4):
      net/ena: improve safety of string handling
      net/bnxt: ensure entry length is unsigned
      net/i40e: do not use VSI before NULL check
      net/bnxt: fix bit shift size

Kamil Rytarowski (1):
      net/thunderx: fix Tx checksum handling

Michael Qiu (2):
      examples/tep_term: fix L4 length
      examples/tep_term: fix packet length with multi-segments

Mohammad Abdul Awal (1):
      app/testpmd: fix RSS hash key size

Nelio Laranjeiro (1):
      net/mlx5: fix Rx checksum macros

Nelson Escobar (3):
      net/enic: revert truncated packets counter fix
      net/enic: document how to configure vNIC parameters
      net/enic: fix Rx queue index when not using Rx scatter

Nipun Gupta (1):
      mempool: fix leak if populate fails

Nélio Laranjeiro (7):
      net/mlx5: fix Rx function selection
      net/mlx5: fix hash key size retrieval
      net/mlx5: support Mellanox OFED 3.4
      net/mlx5: re-factorize functions
      net/mlx5: fix inline logic
      net/mlx5: fix link speed capability information
      net/mlx5: fix support for newer link speeds

Olga Shern (1):
      net/mlx5: fix link status report

Olivier Gournet (1):
      net/mlx5: fix initialization in secondary process

Pablo de Lara (3):
      app/test: fix hash multiwriter sequence
      hash: fix unlimited cuckoo path
      hash: fix bucket size usage

Piotr Azarewicz (1):
      examples/l2fwd-crypto: fix verify with decrypt in chain

Qi Zhang (4):
      net/ixgbe: fix out of order Rx read
      net/fm10k: fix out of order Rx read
      net/i40e: fix Rx hang when disable LLDP
      net/i40e: fix out of order Rx read

Qiming Yang (2):
      net/i40e: fix link status change interrupt
      net/i40e: fix VF bonded device link down

Rasesh Mody (3):
      net/bnx2x: fix maximum PF queues
      net/bnx2x: fix socket id for slowpath memory
      net/qede/base: fix 32-bit build

Raslan Darawsheh (2):
      net/mlx5: fix removing VLAN filter
      net/mlx5: fix handling of small mbuf sizes

Reshma Pattan (2):
      pdump: fix created directory permissions
      app/procinfo: free xstats memory upon failure

Sagi Grimberg (1):
      net/mlx5: fix possible NULL dereference in Rx path

Sergio Gonzalez Monroy (1):
      examples/ipsec-secgw: check SP only when setup

Wei Dai (3):
      lpm: fix freeing unused sub-table on rule delete
      mempool: fix search of maximum contiguous pages
      lpm: fix freeing memory

Wenzhuo Lu (6):
      app/testpmd: fix DCB configuration
      app/testpmd: fix PF/VF check of flow director
      net/ixgbe: fix flow director mask
      app/testpmd: fix flow director mask
      app/testpmd: fix flow director endianness
      net/ixgbe: fix VF registers

Xiao Wang (2):
      net/fm10k: fix Rx checksum flags
      net/fm10k: fix VF Tx queue initialization

Yaacov Hazan (3):
      net/mlx5: fix inconsistent return value in flow director
      net/mlx5: refactor allocation of flow director queues
      net/mlx5: fix flow director drop mode

Yong Wang (1):
      net/vmxnet3: fix mbuf release on reset/stop

Yuanhan Liu (1):
      net/virtio: revert fix restart

Zhihong Wang (1):
      vhost: fix Windows VM hang

^ permalink raw reply

* Re: [PATCH v2] nfp: report link speed using hardware info
From: Thomas Monjalon @ 2016-11-21  9:22 UTC (permalink / raw)
  To: Alejandro Lucero; +Cc: dev
In-Reply-To: <CAD+H990O-ZwxOtQ1DORTH7yanv-DY8wbzUUnv1AWoTiU+7YiEw@mail.gmail.com>

2016-11-18 16:50, Alejandro Lucero:
> On Fri, Nov 18, 2016 at 4:29 PM, Thomas Monjalon <thomas.monjalon@6wind.com>
> wrote:
> > You should update the doc in the same patch:
> >         doc/guides/nics/features/nfp.ini
> > It will be the first feature as the file appears to be empty.
> > So you will need another patch to fill other existing features.
> >
> 
> Yes. I'm just working on updating that file properly.
> May I delay this doc change for including it with that other one?
> It will be a bit weird to just have one feature there.

It will provide you a good motivation to fix the doc :)
Up to you

^ permalink raw reply

* Re: [PATCH v9] drivers/net:new PMD using tun/tap host interface
From: Ferruh Yigit @ 2016-11-21 12:56 UTC (permalink / raw)
  To: Keith Wiles, dev; +Cc: pmatilai, yuanhan.liu
In-Reply-To: <1476396234-44694-1-git-send-email-keith.wiles@intel.com>

On 10/13/2016 11:03 PM, Keith Wiles wrote:
> The rte_eth_tap.c PMD creates a device using TUN/TAP interfaces
> on the local host. The PMD allows for DPDK and the host to
> communicate using a raw device interface on the host and in
> the DPDK application. The device created is a Tap device with
> a L2 packet header.
> 
> v9 - Fix up the docs to use correct syntax
> v8 - Fix issue with tap_tx_queue_setup() not return zero on success.
> v7 - Reword the comment in common_base and fix the data->name issue
> v6 - fixed the checkpatch issues
> v5 - merge in changes from list review see related emails
>      fixed many minor edits
> v4 - merge with latest driver changes
> v3 - fix includes by removing ifdef for other type besides Linux
>      Fix the copyright notice in the Makefile
> v2 - merge all of the patches into one patch
>      Fix a typo on naming the tap device
>      Update the maintainers list
> 
> Signed-off-by: Keith Wiles <keith.wiles@intel.com>
> ---

Just a reminder, this is a new PMD and waiting for community review.

^ permalink raw reply

* Re: [dpdk-stable] [PATCH] Revert "bonding: use existing enslaved device queues"
From: Ilya Maximets @ 2016-11-21 12:49 UTC (permalink / raw)
  To: Jan Blunck, Ferruh Yigit
  Cc: Bruce Richardson, Declan Doherty, Eric Kinzie, dev, Heetae Ahn,
	Yuanhan Liu, Bernard Iremonger, stable, Thomas Monjalon
In-Reply-To: <CALe+Z02_342X4H9aFsvpaOJVw9Yb8F_qjmRH8XKUseP=QfjdWw@mail.gmail.com>

On 21.11.2016 14:39, Jan Blunck wrote:
> Ferruh,
> 
> I've been working on a patch but was distracted by other stuff and
> therefore haven't tested it yet.

Jan, on what patch are you working? I don't understand.

> 
> Stay tuned,
> Jan
> 
> On Mon, Nov 21, 2016 at 12:30 PM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>
>> Is there an update for this patch? Is a consensus reached?

Ferruh, I didn't receive any response on my e-mails. I've pinged this thread
few times, but didn't receive any feedback and I have no idea what patch Jan
talking about.

Best regards, Ilya Maximets.

^ permalink raw reply

* Re: [dpdk-stable] [PATCH] Revert "bonding: use existing enslaved device queues"
From: Jan Blunck @ 2016-11-21 11:39 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: Bruce Richardson, Declan Doherty, Eric Kinzie, Ilya Maximets, dev,
	Heetae Ahn, Yuanhan Liu, Bernard Iremonger, stable,
	Thomas Monjalon
In-Reply-To: <7c4bc057-93ee-42e1-b7ce-c87460aeee2a@intel.com>

Ferruh,

I've been working on a patch but was distracted by other stuff and
therefore haven't tested it yet.

Stay tuned,
Jan

On Mon, Nov 21, 2016 at 12:30 PM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> On 10/25/2016 3:00 PM, Bruce Richardson wrote:
>> On Tue, Oct 25, 2016 at 02:48:04PM +0100, Declan Doherty wrote:
>>> On 25/10/16 13:57, Bruce Richardson wrote:
>>>> On Mon, Oct 24, 2016 at 04:07:17PM +0100, Declan Doherty wrote:
>>>>> On 24/10/16 15:51, Jan Blunck wrote:
>>>>>> On Mon, Oct 24, 2016 at 7:02 AM, Declan Doherty
>>>>>> <declan.doherty@intel.com> wrote:
>>>>>>> On 14/10/16 00:37, Eric Kinzie wrote:
>>>>>>>>
>>>>>>>> On Wed Oct 12 16:24:21 +0100 2016, Bruce Richardson wrote:
>>>>>>>>>
>>>>>>>>> On Wed, Oct 12, 2016 at 04:24:54PM +0300, Ilya Maximets wrote:
>>>>>>>>>>
>>>>>>>>>> On 07.10.2016 05:02, Eric Kinzie wrote:
>>>>>>>>>>>
>>>>>>>>>>> On Wed Sep 07 15:28:10 +0300 2016, Ilya Maximets wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> This reverts commit 5b7bb2bda5519b7800f814df64d4e015282140e5.
>>>>>>>>>>>>
>>>>>>>>>>>> It is necessary to reconfigure all queues every time because
>>>>>>>>>>>> configuration
>>>>>>>>>>>> can be changed.
>>>>>>>>>>>>
>>>>>>>>>>>> For example, if we're reconfiguring bonding device with new memory
>>>>>>>>>>>> pool,
>>>>>>>>>>>> already configured queues will still use the old one. And if the old
>>>>>>>>>>>> mempool be freed, application likely will panic in attempt to use
>>>>>>>>>>>> freed mempool.
>>>>>>>>>>>>
>>>>>>>>>>>> This happens when we use the bonding device with OVS 2.6 while MTU
>>>>>>>>>>>> reconfiguration:
>>>>>>>>>>>>
>>>>>>>>>>>> PANIC in rte_mempool_get_ops():
>>>>>>>>>>>> assert "(ops_index >= 0) && (ops_index < RTE_MEMPOOL_MAX_OPS_IDX)"
>>>>>>>>>>>> failed
>>>>>>>>>>>>
>>>>>>>>>>>> Cc: <stable@dpdk.org>
>>>>>>>>>>>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>>>>>>>>>>>> ---
>>>>>>>>>>>>  drivers/net/bonding/rte_eth_bond_pmd.c | 10 ++--------
>>>>>>>>>>>>  1 file changed, 2 insertions(+), 8 deletions(-)
>>>>>>>>>>>>
>>>>>>>>>>>> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c
>>>>>>>>>>>> b/drivers/net/bonding/rte_eth_bond_pmd.c
>>>>>>>>>>>> index b20a272..eb5b6d1 100644
>>>>>>>>>>>> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
>>>>>>>>>>>> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
>>>>>>>>>>>> @@ -1305,8 +1305,6 @@ slave_configure(struct rte_eth_dev
>>>>>>>>>>>> *bonded_eth_dev,
>>>>>>>>>>>>         struct bond_rx_queue *bd_rx_q;
>>>>>>>>>>>>         struct bond_tx_queue *bd_tx_q;
>>>>>>>>>>>>
>>>>>>>>>>>> -       uint16_t old_nb_tx_queues = slave_eth_dev->data->nb_tx_queues;
>>>>>>>>>>>> -       uint16_t old_nb_rx_queues = slave_eth_dev->data->nb_rx_queues;
>>>>>>>>>>>>         int errval;
>>>>>>>>>>>>         uint16_t q_id;
>>>>>>>>>>>>
>>>>>>>>>>>> @@ -1347,9 +1345,7 @@ slave_configure(struct rte_eth_dev
>>>>>>>>>>>> *bonded_eth_dev,
>>>>>>>>>>>>         }
>>>>>>>>>>>>
>>>>>>>>>>>>         /* Setup Rx Queues */
>>>>>>>>>>>> -       /* Use existing queues, if any */
>>>>>>>>>>>> -       for (q_id = old_nb_rx_queues;
>>>>>>>>>>>> -            q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
>>>>>>>>>>>> +       for (q_id = 0; q_id < bonded_eth_dev->data->nb_rx_queues;
>>>>>>>>>>>> q_id++) {
>>>>>>>>>>>>                 bd_rx_q = (struct bond_rx_queue
>>>>>>>>>>>> *)bonded_eth_dev->data->rx_queues[q_id];
>>>>>>>>>>>>
>>>>>>>>>>>>                 errval =
>>>>>>>>>>>> rte_eth_rx_queue_setup(slave_eth_dev->data->port_id, q_id,
>>>>>>>>>>>> @@ -1365,9 +1361,7 @@ slave_configure(struct rte_eth_dev
>>>>>>>>>>>> *bonded_eth_dev,
>>>>>>>>>>>>         }
>>>>>>>>>>>>
>>>>>>>>>>>>         /* Setup Tx Queues */
>>>>>>>>>>>> -       /* Use existing queues, if any */
>>>>>>>>>>>> -       for (q_id = old_nb_tx_queues;
>>>>>>>>>>>> -            q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) {
>>>>>>>>>>>> +       for (q_id = 0; q_id < bonded_eth_dev->data->nb_tx_queues;
>>>>>>>>>>>> q_id++) {
>>>>>>>>>>>>                 bd_tx_q = (struct bond_tx_queue
>>>>>>>>>>>> *)bonded_eth_dev->data->tx_queues[q_id];
>>>>>>>>>>>>
>>>>>>>>>>>>                 errval =
>>>>>>>>>>>> rte_eth_tx_queue_setup(slave_eth_dev->data->port_id, q_id,
>>>>>>>>>>>> --
>>>>>>>>>>>> 2.7.4
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> NAK
>>>>>>>>>>>
>>>>>>>>>>> There are still some users of this code.  Let's give them a chance to
>>>>>>>>>>> comment before removing it.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Hi Eric,
>>>>>>>>>>
>>>>>>>>>> Are these users in CC-list? If not, could you, please, add them?
>>>>>>>>>> This patch awaits in mail-list already more than a month. I think, it's
>>>>>>>>>> enough
>>>>>>>>>> time period for all who wants to say something. Patch fixes a real bug
>>>>>>>>>> that
>>>>>>>>>> prevent using of DPDK bonding in all applications that reconfigures
>>>>>>>>>> devices
>>>>>>>>>> in runtime including OVS.
>>>>>>>>>>
>>>>>>>>> Agreed.
>>>>>>>>>
>>>>>>>>> Eric, does reverting this patch cause you problems directly, or is your
>>>>>>>>> concern
>>>>>>>>> just with regards to potential impact to others?
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> /Bruce
>>>>>>>>
>>>>>>>>
>>>>>>>> This won't impact me directly.  The users are CCed (different thread)
>>>>>>>> and I haven't seen any comment, so I no longer have any objection to
>>>>>>>> reverting this change.
>>>>>>>>
>>>>>>>> Eric
>>>>>>>>
>>>>>>>
>>>>>>> As there has been no further objections and this reinstates the original
>>>>>>> expected behavior of the bonding driver. I'm re-ack'ing for inclusion in
>>>>>>> release.
>>>>>>>
>>>>>>> Acked-by: Declan Doherty <declan.doherty@intel.com>
>>>>>>
>>>>>> Ok, I can revert the revert for us.
>>>>>>
>>>>>> Do I read this correctly that you are not interested in fixing this properly?!
>>>>>>
>>>>>> Thanks,
>>>>>> Jan
>>>>>>
>>>>>
>>>>> Jan, sorry I missed the replies from last week due to the way my mail client
>>>>> was filtering the conversation. Let me have another look at this and I'll
>>>>> come back to the list.
>>>>>
>>>>> Thanks
>>>>> Declan
>>>>
>>>> While this patch has already been applied to dpdk-next-net tree, it
>>>> appears that there is still some ongoing discussion about it. I'm
>>>> therefore planning to pull it back out of the tree for rc2. If a
>>>> subsequent consensus is reached we can see about including it in rc3.
>>>>
>>>> Declan, as maintainer, does this seem reasonable to you.
>>>>
>>>> Regards,
>>>> /Bruce
>>>>
>>>
>>>
>>> Hey Bruce, that seems reasonable, I would like to discuss this further with
>>> Jan and Ilya.
>>>
>>
>> Done. Hopefully consensus on a correct solution for this driver can be
>> reached soon.
>>
>
> Is there an update for this patch? Is a consensus reached?
>
> Thanks,
> ferruh
>

^ permalink raw reply

* Re: [dpdk-stable] [PATCH] Revert "bonding: use existing enslaved device queues"
From: Ferruh Yigit @ 2016-11-21 11:30 UTC (permalink / raw)
  To: Bruce Richardson, Declan Doherty
  Cc: Jan Blunck, Eric Kinzie, Ilya Maximets, dev, Heetae Ahn,
	Yuanhan Liu, Bernard Iremonger, stable, Thomas Monjalon
In-Reply-To: <20161025140048.GB10444@bricha3-MOBL3.ger.corp.intel.com>

On 10/25/2016 3:00 PM, Bruce Richardson wrote:
> On Tue, Oct 25, 2016 at 02:48:04PM +0100, Declan Doherty wrote:
>> On 25/10/16 13:57, Bruce Richardson wrote:
>>> On Mon, Oct 24, 2016 at 04:07:17PM +0100, Declan Doherty wrote:
>>>> On 24/10/16 15:51, Jan Blunck wrote:
>>>>> On Mon, Oct 24, 2016 at 7:02 AM, Declan Doherty
>>>>> <declan.doherty@intel.com> wrote:
>>>>>> On 14/10/16 00:37, Eric Kinzie wrote:
>>>>>>>
>>>>>>> On Wed Oct 12 16:24:21 +0100 2016, Bruce Richardson wrote:
>>>>>>>>
>>>>>>>> On Wed, Oct 12, 2016 at 04:24:54PM +0300, Ilya Maximets wrote:
>>>>>>>>>
>>>>>>>>> On 07.10.2016 05:02, Eric Kinzie wrote:
>>>>>>>>>>
>>>>>>>>>> On Wed Sep 07 15:28:10 +0300 2016, Ilya Maximets wrote:
>>>>>>>>>>>
>>>>>>>>>>> This reverts commit 5b7bb2bda5519b7800f814df64d4e015282140e5.
>>>>>>>>>>>
>>>>>>>>>>> It is necessary to reconfigure all queues every time because
>>>>>>>>>>> configuration
>>>>>>>>>>> can be changed.
>>>>>>>>>>>
>>>>>>>>>>> For example, if we're reconfiguring bonding device with new memory
>>>>>>>>>>> pool,
>>>>>>>>>>> already configured queues will still use the old one. And if the old
>>>>>>>>>>> mempool be freed, application likely will panic in attempt to use
>>>>>>>>>>> freed mempool.
>>>>>>>>>>>
>>>>>>>>>>> This happens when we use the bonding device with OVS 2.6 while MTU
>>>>>>>>>>> reconfiguration:
>>>>>>>>>>>
>>>>>>>>>>> PANIC in rte_mempool_get_ops():
>>>>>>>>>>> assert "(ops_index >= 0) && (ops_index < RTE_MEMPOOL_MAX_OPS_IDX)"
>>>>>>>>>>> failed
>>>>>>>>>>>
>>>>>>>>>>> Cc: <stable@dpdk.org>
>>>>>>>>>>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>>>>>>>>>>> ---
>>>>>>>>>>>  drivers/net/bonding/rte_eth_bond_pmd.c | 10 ++--------
>>>>>>>>>>>  1 file changed, 2 insertions(+), 8 deletions(-)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c
>>>>>>>>>>> b/drivers/net/bonding/rte_eth_bond_pmd.c
>>>>>>>>>>> index b20a272..eb5b6d1 100644
>>>>>>>>>>> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
>>>>>>>>>>> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
>>>>>>>>>>> @@ -1305,8 +1305,6 @@ slave_configure(struct rte_eth_dev
>>>>>>>>>>> *bonded_eth_dev,
>>>>>>>>>>>         struct bond_rx_queue *bd_rx_q;
>>>>>>>>>>>         struct bond_tx_queue *bd_tx_q;
>>>>>>>>>>>
>>>>>>>>>>> -       uint16_t old_nb_tx_queues = slave_eth_dev->data->nb_tx_queues;
>>>>>>>>>>> -       uint16_t old_nb_rx_queues = slave_eth_dev->data->nb_rx_queues;
>>>>>>>>>>>         int errval;
>>>>>>>>>>>         uint16_t q_id;
>>>>>>>>>>>
>>>>>>>>>>> @@ -1347,9 +1345,7 @@ slave_configure(struct rte_eth_dev
>>>>>>>>>>> *bonded_eth_dev,
>>>>>>>>>>>         }
>>>>>>>>>>>
>>>>>>>>>>>         /* Setup Rx Queues */
>>>>>>>>>>> -       /* Use existing queues, if any */
>>>>>>>>>>> -       for (q_id = old_nb_rx_queues;
>>>>>>>>>>> -            q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
>>>>>>>>>>> +       for (q_id = 0; q_id < bonded_eth_dev->data->nb_rx_queues;
>>>>>>>>>>> q_id++) {
>>>>>>>>>>>                 bd_rx_q = (struct bond_rx_queue
>>>>>>>>>>> *)bonded_eth_dev->data->rx_queues[q_id];
>>>>>>>>>>>
>>>>>>>>>>>                 errval =
>>>>>>>>>>> rte_eth_rx_queue_setup(slave_eth_dev->data->port_id, q_id,
>>>>>>>>>>> @@ -1365,9 +1361,7 @@ slave_configure(struct rte_eth_dev
>>>>>>>>>>> *bonded_eth_dev,
>>>>>>>>>>>         }
>>>>>>>>>>>
>>>>>>>>>>>         /* Setup Tx Queues */
>>>>>>>>>>> -       /* Use existing queues, if any */
>>>>>>>>>>> -       for (q_id = old_nb_tx_queues;
>>>>>>>>>>> -            q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) {
>>>>>>>>>>> +       for (q_id = 0; q_id < bonded_eth_dev->data->nb_tx_queues;
>>>>>>>>>>> q_id++) {
>>>>>>>>>>>                 bd_tx_q = (struct bond_tx_queue
>>>>>>>>>>> *)bonded_eth_dev->data->tx_queues[q_id];
>>>>>>>>>>>
>>>>>>>>>>>                 errval =
>>>>>>>>>>> rte_eth_tx_queue_setup(slave_eth_dev->data->port_id, q_id,
>>>>>>>>>>> --
>>>>>>>>>>> 2.7.4
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> NAK
>>>>>>>>>>
>>>>>>>>>> There are still some users of this code.  Let's give them a chance to
>>>>>>>>>> comment before removing it.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Hi Eric,
>>>>>>>>>
>>>>>>>>> Are these users in CC-list? If not, could you, please, add them?
>>>>>>>>> This patch awaits in mail-list already more than a month. I think, it's
>>>>>>>>> enough
>>>>>>>>> time period for all who wants to say something. Patch fixes a real bug
>>>>>>>>> that
>>>>>>>>> prevent using of DPDK bonding in all applications that reconfigures
>>>>>>>>> devices
>>>>>>>>> in runtime including OVS.
>>>>>>>>>
>>>>>>>> Agreed.
>>>>>>>>
>>>>>>>> Eric, does reverting this patch cause you problems directly, or is your
>>>>>>>> concern
>>>>>>>> just with regards to potential impact to others?
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> /Bruce
>>>>>>>
>>>>>>>
>>>>>>> This won't impact me directly.  The users are CCed (different thread)
>>>>>>> and I haven't seen any comment, so I no longer have any objection to
>>>>>>> reverting this change.
>>>>>>>
>>>>>>> Eric
>>>>>>>
>>>>>>
>>>>>> As there has been no further objections and this reinstates the original
>>>>>> expected behavior of the bonding driver. I'm re-ack'ing for inclusion in
>>>>>> release.
>>>>>>
>>>>>> Acked-by: Declan Doherty <declan.doherty@intel.com>
>>>>>
>>>>> Ok, I can revert the revert for us.
>>>>>
>>>>> Do I read this correctly that you are not interested in fixing this properly?!
>>>>>
>>>>> Thanks,
>>>>> Jan
>>>>>
>>>>
>>>> Jan, sorry I missed the replies from last week due to the way my mail client
>>>> was filtering the conversation. Let me have another look at this and I'll
>>>> come back to the list.
>>>>
>>>> Thanks
>>>> Declan
>>>
>>> While this patch has already been applied to dpdk-next-net tree, it
>>> appears that there is still some ongoing discussion about it. I'm
>>> therefore planning to pull it back out of the tree for rc2. If a
>>> subsequent consensus is reached we can see about including it in rc3.
>>>
>>> Declan, as maintainer, does this seem reasonable to you.
>>>
>>> Regards,
>>> /Bruce
>>>
>>
>>
>> Hey Bruce, that seems reasonable, I would like to discuss this further with
>> Jan and Ilya.
>>
> 
> Done. Hopefully consensus on a correct solution for this driver can be
> reached soon.
> 

Is there an update for this patch? Is a consensus reached?

Thanks,
ferruh

^ permalink raw reply

* Re: [PATCH v2] nfp: report link speed using hardware info
From: Ferruh Yigit @ 2016-11-21 11:18 UTC (permalink / raw)
  To: Alejandro Lucero, dev
In-Reply-To: <1479485218-11931-1-git-send-email-alejandro.lucero@netronome.com>

On 11/18/2016 4:06 PM, Alejandro Lucero wrote:
> Previous reported speed was hardcoded.
> 
> Signed-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>
> ---
>  drivers/net/nfp/nfp_net.c      | 28 ++++++++++++++++++++++++++--
>  drivers/net/nfp/nfp_net_ctrl.h | 13 +++++++++++++
>  2 files changed, 39 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
> index c6b1587..24f3164 100644
> --- a/drivers/net/nfp/nfp_net.c
> +++ b/drivers/net/nfp/nfp_net.c
> @@ -816,6 +816,17 @@ static void nfp_net_read_mac(struct nfp_net_hw *hw)
>  	struct rte_eth_link link, old;
>  	uint32_t nn_link_status;
>  
> +	static const uint32_t ls_to_ethtool[] = {
> +		[NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = ETH_SPEED_NUM_NONE,
> +		[NFP_NET_CFG_STS_LINK_RATE_UNKNOWN]     = ETH_SPEED_NUM_NONE,
> +		[NFP_NET_CFG_STS_LINK_RATE_1G]          = ETH_SPEED_NUM_1G,
> +		[NFP_NET_CFG_STS_LINK_RATE_10G]         = ETH_SPEED_NUM_10G,
> +		[NFP_NET_CFG_STS_LINK_RATE_25G]         = ETH_SPEED_NUM_25G,
> +		[NFP_NET_CFG_STS_LINK_RATE_40G]         = ETH_SPEED_NUM_40G,
> +		[NFP_NET_CFG_STS_LINK_RATE_50G]         = ETH_SPEED_NUM_50G,
> +		[NFP_NET_CFG_STS_LINK_RATE_100G]        = ETH_SPEED_NUM_100G,
> +	};
> +
>  	PMD_DRV_LOG(DEBUG, "Link update\n");
>  
>  	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> @@ -831,8 +842,21 @@ static void nfp_net_read_mac(struct nfp_net_hw *hw)
>  		link.link_status = ETH_LINK_UP;
>  
>  	link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -	/* Other cards can limit the tx and rx rate per VF */
> -	link.link_speed = ETH_SPEED_NUM_40G;
> +
> +	nn_link_status = (nn_link_status >> NFP_NET_CFG_STS_LINK_RATE_SHIFT) &
> +			 NFP_NET_CFG_STS_LINK_RATE_MASK;
> +
> +	if ((NFD_CFG_MAJOR_VERSION_of(hw->ver) < 4) ||
> +	    ((NFD_CFG_MINOR_VERSION_of(hw->ver) == 4) &&
> +	    (NFD_CFG_MINOR_VERSION_of(hw->ver) == 0)))
> +		link.link_speed = ETH_SPEED_NUM_40G;

For specific firmware version, speed is still hardcoded to 40G, can you
please mention from this and if possible its reason in commit log?

> +	else {
> +		if (nn_link_status == NFP_NET_CFG_STS_LINK_RATE_UNKNOWN ||

This check can be redundant, since
ls_to_ethtool[NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] => ETH_SPEED_NUM_NONE

> +		    nn_link_status >= RTE_DIM(ls_to_ethtool))
> +			link.link_speed = ETH_SPEED_NUM_NONE;
> +		else
> +			link.link_speed = ls_to_ethtool[nn_link_status];
> +	}
>  
>  	if (old.link_status != link.link_status) {
>  		nfp_net_dev_atomic_write_link_status(dev, &link);
> diff --git a/drivers/net/nfp/nfp_net_ctrl.h b/drivers/net/nfp/nfp_net_ctrl.h
> index fce8251..f9aaba3 100644
> --- a/drivers/net/nfp/nfp_net_ctrl.h
> +++ b/drivers/net/nfp/nfp_net_ctrl.h
> @@ -157,6 +157,19 @@
>  #define   NFP_NET_CFG_VERSION_MINOR(x)    (((x) & 0xff) <<  0)
>  #define NFP_NET_CFG_STS                 0x0034
>  #define   NFP_NET_CFG_STS_LINK            (0x1 << 0) /* Link up or down */
> +/* Link rate */
> +#define   NFP_NET_CFG_STS_LINK_RATE_SHIFT 1
> +#define   NFP_NET_CFG_STS_LINK_RATE_MASK  0xF
> +#define   NFP_NET_CFG_STS_LINK_RATE       \
> +	  (NFP_NET_CFG_STS_LINK_RATE_MASK << NFP_NET_CFG_STS_LINK_RATE_SHIFT)

This macro is not used at all, just fyi.

> +#define   NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED   0
> +#define   NFP_NET_CFG_STS_LINK_RATE_UNKNOWN       1
> +#define   NFP_NET_CFG_STS_LINK_RATE_1G            2
> +#define   NFP_NET_CFG_STS_LINK_RATE_10G           3
> +#define   NFP_NET_CFG_STS_LINK_RATE_25G           4
> +#define   NFP_NET_CFG_STS_LINK_RATE_40G           5
> +#define   NFP_NET_CFG_STS_LINK_RATE_50G           6
> +#define   NFP_NET_CFG_STS_LINK_RATE_100G          7
>  #define NFP_NET_CFG_CAP                 0x0038
>  #define NFP_NET_CFG_MAX_TXRINGS         0x003c
>  #define NFP_NET_CFG_MAX_RXRINGS         0x0040
> 

^ permalink raw reply

* Re: [PATCH v2] nfp: report link speed using hardware info
From: Ferruh Yigit @ 2016-11-21 10:57 UTC (permalink / raw)
  To: Alejandro Lucero, Thomas Monjalon; +Cc: dev
In-Reply-To: <CAD+H990O-ZwxOtQ1DORTH7yanv-DY8wbzUUnv1AWoTiU+7YiEw@mail.gmail.com>

On 11/18/2016 4:50 PM, Alejandro Lucero wrote:
> On Fri, Nov 18, 2016 at 4:29 PM, Thomas Monjalon <thomas.monjalon@6wind.com>
> wrote:
> 
>> 2016-11-18 16:06, Alejandro Lucero:
>>> Previous reported speed was hardcoded.
>>>
>>> Signed-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>
>>> ---
>>>  drivers/net/nfp/nfp_net.c      | 28 ++++++++++++++++++++++++++--
>>>  drivers/net/nfp/nfp_net_ctrl.h | 13 +++++++++++++
>>>  2 files changed, 39 insertions(+), 2 deletions(-)
>>
>> You should update the doc in the same patch:
>>         doc/guides/nics/features/nfp.ini
>> It will be the first feature as the file appears to be empty.
>> So you will need another patch to fill other existing features.
>>
> 
> Yes. I'm just working on updating that file properly.
> May I delay this doc change for including it with that other one?
> It will be a bit weird to just have one feature there.

I think yes, but can you please send the documentation patch before
integration deadline of this release?

> 
> 
>>
>> I have an unrelated question: why nfp is disabled in the default build?
>>
>>
> Because NFP PMD can just work if Netronome BSP is installed in the system.

Is this BSP open source and freely available? If so, can you update the
document with details (how/where to get it) please?

> We do not support PF with the PMD, so it requires a Linux PF driver which
> comes with the BSP.
> 
> The compilation has no dependencies, but we had our own UIO driver before
> (now using igb_uio). So basically, we wanted the people aware of this
> dependency and to specifically configure this option.
> 
> I know what you are surely going to ask about DPDK in Linux distributions,
> and that this being a bad idea. The fact is, we have people using NFP PMD
> as part of a product, so installing that product implies to (automatically)
> install the BSP and a specific DPDK version with the NFP PMD enabled. But
> yes, maybe we should modify this and to add some sort of BSP check inside
> the PMD.

Is there a DPDK version <-> BSP version dependency?

> 
> So, thanks for the heads up. I will think about this.
> 

^ permalink raw reply

* Adding API to force freeing consumed buffers in TX ring
From: Damjan Marion (damarion) @ 2016-11-21 10:48 UTC (permalink / raw)
  To: dev@dpdk.org


Hi,

Currently in VPP we do memcpy of whole packet when we need to do 
replication as we cannot know if specific buffer is transmitted
from tx ring before we update it again (i.e. l2 header rewrite).

Unless there is already a way to address this issue in DPDK which I’m not aware
of my proposal is that we provide mechanism for polling TX ring 
for consumed buffers. This can be either completely new API or 
extension of rte_etx_tx_burst (i.e. special case when nb_pkts=0).

This will allows us to start polling tx ring when we expect some 
mbuf back, instead of waiting for next tx burst (which we don’t know
when it will happen) and hoping that we will reach free_threshold soon.

Any thoughts?

Thanks,

Damjan




^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox