[dpdk-dev] [PATCH 24/29] net/sfc/base: support proxy auth operations for SR-IOV

Andrew Rybchenko arybchenko at solarflare.com
Mon Jun 10 09:38:39 CEST 2019


From: Gautam Dawar <gdawar at solarflare.com>

VMware expects that certain kind of configurations made on the VFs are
authorized by the ESXi before these are applied e.g. assigning a MAC
address to the VF, setting MTU etc. Firmware supports a feature called
MCDI proxy which will be used to implement this authorization check.
The proxy auth module is governed by EFSYS_OPT_MCDI_PROXY_AUTH switch.
This patch adds the framework for proxy auth module along with the APIs
required for SR-IOV initialization.

Signed-off-by: Gautam Dawar <gdawar at solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
---
 drivers/net/sfc/Makefile          |   2 +
 drivers/net/sfc/base/ef10_impl.h  |  34 +++++
 drivers/net/sfc/base/ef10_proxy.c | 255 ++++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/base/efx.h        |  32 +++++
 drivers/net/sfc/base/efx_impl.h   |  22 ++++
 drivers/net/sfc/base/efx_proxy.c  | 200 ++++++++++++++++++++++++++++++
 drivers/net/sfc/base/meson.build  |   2 +
 drivers/net/sfc/efsys.h           |   2 +
 8 files changed, 549 insertions(+)
 create mode 100644 drivers/net/sfc/base/ef10_proxy.c
 create mode 100644 drivers/net/sfc/base/efx_proxy.c

diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index 7149afd..7dd660d 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -101,6 +101,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_nic.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_nvram.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_phy.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_port.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_proxy.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_rx.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_sram.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_tunnel.c
@@ -124,6 +125,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_mcdi.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_nic.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_nvram.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_phy.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_proxy.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_rx.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_tx.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_vpd.c
diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index e261487..4b719c9 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -1344,6 +1344,40 @@ extern	__checkReturn	__success(return != B_FALSE)	boolean_t
 
 #endif  /* EFSYS_OPT_EVB */
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+extern	__checkReturn	efx_rc_t
+ef10_proxy_auth_init(
+	__in		efx_nic_t *enp);
+
+extern			void
+ef10_proxy_auth_fini(
+	__in		efx_nic_t *enp);
+
+extern	__checkReturn		efx_rc_t
+ef10_proxy_auth_mc_config(
+	__in			efx_nic_t *enp,
+	__in			efsys_mem_t *request_bufferp,
+	__in			efsys_mem_t *response_bufferp,
+	__in			efsys_mem_t *status_bufferp,
+	__in			uint32_t block_cnt,
+	__in_ecount(op_count)	uint32_t *op_listp,
+	__in			size_t op_count);
+
+extern	__checkReturn	efx_rc_t
+ef10_proxy_auth_disable(
+	__in		efx_nic_t *enp);
+
+extern	__checkReturn	efx_rc_t
+ef10_proxy_auth_privilege_modify(
+	__in		efx_nic_t *enp,
+	__in		uint32_t fn_group,
+	__in		uint32_t pf_index,
+	__in		uint32_t vf_index,
+	__in		uint32_t add_privileges_mask,
+	__in		uint32_t remove_privileges_mask);
+
+#endif  /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
+
 #if EFSYS_OPT_RX_PACKED_STREAM
 
 /* Data space per credit in packed stream mode */
diff --git a/drivers/net/sfc/base/ef10_proxy.c b/drivers/net/sfc/base/ef10_proxy.c
new file mode 100644
index 0000000..6b1afcc
--- /dev/null
+++ b/drivers/net/sfc/base/ef10_proxy.c
@@ -0,0 +1,255 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2018-2019 Solarflare Communications Inc.
+ * All rights reserved.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+
+	__checkReturn	efx_rc_t
+ef10_proxy_auth_init(
+	__in		efx_nic_t *enp)
+{
+	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+		enp->en_family == EFX_FAMILY_MEDFORD ||
+		enp->en_family == EFX_FAMILY_MEDFORD2);
+
+	return (0);
+}
+
+			void
+ef10_proxy_auth_fini(
+	__in		efx_nic_t *enp)
+{
+	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+		enp->en_family == EFX_FAMILY_MEDFORD ||
+		enp->en_family == EFX_FAMILY_MEDFORD2);
+}
+
+static	__checkReturn	efx_rc_t
+efx_mcdi_proxy_configure(
+	__in		efx_nic_t *enp,
+	__in		boolean_t disable_proxy,
+	__in		uint64_t req_buffer_addr,
+	__in		uint64_t resp_buffer_addr,
+	__in		uint64_t stat_buffer_addr,
+	__in		size_t req_size,
+	__in		size_t resp_size,
+	__in		uint32_t block_cnt,
+	__in		uint8_t *op_maskp,
+	__in		size_t op_mask_size)
+{
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PROXY_CONFIGURE_EXT_IN_LEN,
+		MC_CMD_PROXY_CONFIGURE_OUT_LEN);
+	efx_mcdi_req_t req;
+	efx_rc_t rc;
+
+	req.emr_cmd = MC_CMD_PROXY_CONFIGURE;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_PROXY_CONFIGURE_EXT_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_PROXY_CONFIGURE_OUT_LEN;
+
+	if (!disable_proxy) {
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_FLAGS, 1);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_LO,
+			req_buffer_addr & 0xffffffff);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_HI,
+			req_buffer_addr >> 32);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_LO,
+			resp_buffer_addr & 0xffffffff);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_HI,
+			resp_buffer_addr >> 32);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_LO,
+			stat_buffer_addr & 0xffffffff);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_HI,
+			stat_buffer_addr >> 32);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REQUEST_BLOCK_SIZE,
+			req_size);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REPLY_BLOCK_SIZE,
+			resp_size);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_STATUS_BLOCK_SIZE,
+			MC_PROXY_STATUS_BUFFER_LEN);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_NUM_BLOCKS,
+			block_cnt);
+		memcpy(MCDI_IN2(req, efx_byte_t,
+				PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK),
+			op_maskp, op_mask_size);
+		MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_EXT_IN_RESERVED,
+			EFX_PROXY_CONFIGURE_MAGIC);
+	}
+
+	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);
+}
+
+static	__checkReturn	efx_rc_t
+efx_mcdi_privilege_modify(
+	__in		efx_nic_t *enp,
+	__in		uint32_t fn_group,
+	__in		uint32_t pf_index,
+	__in		uint32_t vf_index,
+	__in		uint32_t add_privileges_mask,
+	__in		uint32_t remove_privileges_mask)
+{
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PRIVILEGE_MODIFY_IN_LEN,
+		MC_CMD_PRIVILEGE_MODIFY_OUT_LEN);
+	efx_mcdi_req_t req;
+	efx_rc_t rc;
+
+	req.emr_cmd = MC_CMD_PRIVILEGE_MODIFY;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_PRIVILEGE_MODIFY_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_PRIVILEGE_MODIFY_OUT_LEN;
+
+	EFSYS_ASSERT(fn_group <= MC_CMD_PRIVILEGE_MODIFY_IN_ONE);
+
+	MCDI_IN_SET_DWORD(req, PRIVILEGE_MODIFY_IN_FN_GROUP, fn_group);
+
+	if ((fn_group == MC_CMD_PRIVILEGE_MODIFY_IN_ONE) ||
+	    (fn_group == MC_CMD_PRIVILEGE_MODIFY_IN_VFS_OF_PF)) {
+		MCDI_IN_POPULATE_DWORD_2(req,
+		    PRIVILEGE_MODIFY_IN_FUNCTION,
+		    PRIVILEGE_MODIFY_IN_FUNCTION_PF, pf_index,
+		    PRIVILEGE_MODIFY_IN_FUNCTION_VF, vf_index);
+	}
+
+	MCDI_IN_SET_DWORD(req, PRIVILEGE_MODIFY_IN_ADD_MASK,
+		add_privileges_mask);
+	MCDI_IN_SET_DWORD(req, PRIVILEGE_MODIFY_IN_REMOVE_MASK,
+		remove_privileges_mask);
+
+	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);
+}
+
+static	__checkReturn			efx_rc_t
+efx_proxy_auth_fill_op_mask(
+	__in_ecount(op_count)		uint32_t *op_listp,
+	__in				size_t op_count,
+	__out_ecount(op_mask_size)	uint32_t *op_maskp,
+	__in				size_t op_mask_size)
+{
+	efx_rc_t rc;
+	uint32_t op;
+
+	if ((op_listp == NULL) || (op_maskp == NULL)) {
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	while (op_count--) {
+		op = *op_listp++;
+		if (op > op_mask_size * 32) {
+			rc = EINVAL;
+			goto fail2;
+		}
+		op_maskp[op / 32] |= 1u << (op & 31);
+	}
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn		efx_rc_t
+ef10_proxy_auth_mc_config(
+	__in			efx_nic_t *enp,
+	__in_ecount(block_cnt)	efsys_mem_t *request_bufferp,
+	__in_ecount(block_cnt)	efsys_mem_t *response_bufferp,
+	__in_ecount(block_cnt)	efsys_mem_t *status_bufferp,
+	__in			uint32_t block_cnt,
+	__in_ecount(op_count)	uint32_t *op_listp,
+	__in			size_t op_count)
+{
+#define	PROXY_OPS_MASK_SIZE						\
+	(EFX_DIV_ROUND_UP(						\
+	    MC_CMD_PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK_LEN,		\
+	    sizeof (uint32_t)))
+
+	efx_rc_t rc;
+	uint32_t op_mask[PROXY_OPS_MASK_SIZE] = {0};
+
+	/* Prepare the operation mask from operation list array */
+	if ((rc = efx_proxy_auth_fill_op_mask(op_listp, op_count,
+			op_mask, PROXY_OPS_MASK_SIZE) != 0))
+		goto fail1;
+
+	if ((rc = efx_mcdi_proxy_configure(enp, B_FALSE,
+			EFSYS_MEM_ADDR(request_bufferp),
+			EFSYS_MEM_ADDR(response_bufferp),
+			EFSYS_MEM_ADDR(status_bufferp),
+			EFSYS_MEM_SIZE(request_bufferp) / block_cnt,
+			EFSYS_MEM_SIZE(response_bufferp) / block_cnt,
+			block_cnt, (uint8_t *)&op_mask,
+			sizeof (op_mask))) != 0)
+		goto fail2;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+ef10_proxy_auth_disable(
+	__in		efx_nic_t *enp)
+{
+	efx_rc_t rc;
+
+	if ((rc = efx_mcdi_proxy_configure(enp, B_TRUE,
+			0, 0, 0, 0, 0, 0, NULL, 0) != 0))
+		goto fail1;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+ef10_proxy_auth_privilege_modify(
+	__in		efx_nic_t *enp,
+	__in		uint32_t fn_group,
+	__in		uint32_t pf_index,
+	__in		uint32_t vf_index,
+	__in		uint32_t add_privileges_mask,
+	__in		uint32_t remove_privileges_mask)
+{
+	return (efx_mcdi_privilege_modify(enp, fn_group, pf_index, vf_index,
+			add_privileges_mask, remove_privileges_mask));
+}
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 492c8c6..8a3eb17 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -3419,6 +3419,38 @@ extern	__checkReturn	__success(return != B_FALSE)	boolean_t
 
 #endif /* EFSYS_OPT_EVB */
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+
+typedef struct efx_proxy_auth_config_s {
+	efsys_mem_t	*request_bufferp;
+	efsys_mem_t	*response_bufferp;
+	efsys_mem_t	*status_bufferp;
+	uint32_t	block_cnt;
+	uint32_t	*op_listp;
+	size_t		op_count;
+	uint32_t	handled_privileges;
+} efx_proxy_auth_config_t;
+
+extern	__checkReturn	efx_rc_t
+efx_proxy_auth_init(
+	__in		efx_nic_t *enp);
+
+extern			void
+efx_proxy_auth_fini(
+	__in		efx_nic_t *enp);
+
+extern	__checkReturn	efx_rc_t
+efx_proxy_auth_configure(
+	__in		efx_nic_t *enp,
+	__in		efx_proxy_auth_config_t *configp);
+
+	__checkReturn	efx_rc_t
+efx_proxy_auth_destroy(
+	__in		efx_nic_t *enp,
+	__in		uint32_t handled_privileges);
+
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
+
 #ifdef	__cplusplus
 }
 #endif
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 46d5389..6a8fee8 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -59,6 +59,7 @@
 #define	EFX_MOD_LIC		0x00002000
 #define	EFX_MOD_TUNNEL		0x00004000
 #define	EFX_MOD_EVB		0x00008000
+#define	EFX_MOD_PROXY		0x00010000
 
 #define	EFX_RESET_PHY		0x00000001
 #define	EFX_RESET_RXQ_ERR	0x00000002
@@ -691,6 +692,24 @@ struct efx_vswitch_s {
 
 #endif /* EFSYS_OPT_EVB */
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+
+#define	EFX_PROXY_CONFIGURE_MAGIC	0xAB2015EF
+
+
+typedef struct efx_proxy_ops_s {
+	efx_rc_t	(*epo_init)(efx_nic_t *);
+	void		(*epo_fini)(efx_nic_t *);
+	efx_rc_t	(*epo_mc_config)(efx_nic_t *, efsys_mem_t *,
+					efsys_mem_t *, efsys_mem_t *,
+					uint32_t, uint32_t *, size_t);
+	efx_rc_t	(*epo_disable)(efx_nic_t *);
+	efx_rc_t	(*epo_privilege_modify)(efx_nic_t *, uint32_t, uint32_t,
+					uint32_t, uint32_t, uint32_t);
+} efx_proxy_ops_t;
+
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
+
 #define	EFX_DRV_VER_MAX		20
 
 typedef struct efx_drv_cfg_s {
@@ -793,6 +812,9 @@ struct efx_nic_s {
 	const efx_evb_ops_t	*en_eeop;
 	struct efx_vswitch_s    *en_vswitchp;
 #endif	/* EFSYS_OPT_EVB */
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+	const efx_proxy_ops_t	*en_epop;
+#endif	/* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
 };
 
 #define	EFX_FAMILY_IS_EF10(_enp) \
diff --git a/drivers/net/sfc/base/efx_proxy.c b/drivers/net/sfc/base/efx_proxy.c
new file mode 100644
index 0000000..6aadf07
--- /dev/null
+++ b/drivers/net/sfc/base/efx_proxy.c
@@ -0,0 +1,200 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2018-2019 Solarflare Communications Inc.
+ * All rights reserved.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+
+#if EFSYS_OPT_SIENA
+static const efx_proxy_ops_t	__efx_proxy_dummy_ops = {
+	NULL,			/* epo_init */
+	NULL,			/* epo_fini */
+	NULL,			/* epo_mc_config */
+	NULL,			/* epo_disable */
+	NULL,			/* epo_privilege_modify */
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
+static const efx_proxy_ops_t			__efx_proxy_ef10_ops = {
+	ef10_proxy_auth_init,			/* epo_init */
+	ef10_proxy_auth_fini,			/* epo_fini */
+	ef10_proxy_auth_mc_config,		/* epo_mc_config */
+	ef10_proxy_auth_disable,		/* epo_disable */
+	ef10_proxy_auth_privilege_modify,	/* epo_privilege_modify */
+};
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
+
+	__checkReturn	efx_rc_t
+efx_proxy_auth_init(
+	__in		efx_nic_t *enp)
+{
+	const efx_proxy_ops_t *epop;
+	efx_rc_t rc;
+
+	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_PROXY));
+
+	switch (enp->en_family) {
+#if EFSYS_OPT_SIENA
+	case EFX_FAMILY_SIENA:
+		epop = &__efx_proxy_dummy_ops;
+		break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+	case EFX_FAMILY_HUNTINGTON:
+		epop = &__efx_proxy_ef10_ops;
+		break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		epop = &__efx_proxy_ef10_ops;
+		break;
+#endif /* EFSYS_OPT_MEDFORD */
+
+#if EFSYS_OPT_MEDFORD2
+	case EFX_FAMILY_MEDFORD2:
+		epop = &__efx_proxy_ef10_ops;
+		break;
+#endif /* EFSYS_OPT_MEDFORD2 */
+
+	default:
+		EFSYS_ASSERT(0);
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if (epop->epo_init == NULL) {
+		rc = ENOTSUP;
+		goto fail2;
+	}
+
+	if ((rc = epop->epo_init(enp)) != 0)
+		goto fail3;
+
+	enp->en_epop = epop;
+	enp->en_mod_flags |= EFX_MOD_PROXY;
+	return (0);
+
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+			void
+efx_proxy_auth_fini(
+	__in		efx_nic_t *enp)
+{
+	const efx_proxy_ops_t *epop = enp->en_epop;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
+	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
+
+	if ((epop != NULL) && (epop->epo_fini != NULL))
+		epop->epo_fini(enp);
+
+	enp->en_epop = NULL;
+	enp->en_mod_flags &= ~EFX_MOD_PROXY;
+}
+
+	__checkReturn	efx_rc_t
+efx_proxy_auth_configure(
+	__in		efx_nic_t *enp,
+	__in		efx_proxy_auth_config_t *configp)
+{
+	const efx_proxy_ops_t *epop = enp->en_epop;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
+
+	if ((configp == NULL) ||
+	    (configp->request_bufferp == NULL) ||
+	    (configp->response_bufferp == NULL) ||
+	    (configp->status_bufferp == NULL) ||
+	    (configp->op_listp == NULL) ||
+	    (configp->block_cnt == 0)) {
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	if ((epop->epo_mc_config == NULL) ||
+	    (epop->epo_privilege_modify == NULL)) {
+		rc = ENOTSUP;
+		goto fail2;
+	}
+
+	rc = epop->epo_mc_config(enp, configp->request_bufferp,
+			configp->response_bufferp, configp->status_bufferp,
+			configp->block_cnt, configp->op_listp,
+			configp->op_count);
+	if (rc != 0)
+		goto fail3;
+
+	rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ALL,
+			0, 0, 0, configp->handled_privileges);
+	if (rc != 0)
+		goto fail4;
+
+	return (0);
+
+fail4:
+	EFSYS_PROBE(fail4);
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+efx_proxy_auth_destroy(
+	__in		efx_nic_t *enp,
+	__in		uint32_t handled_privileges)
+{
+	const efx_proxy_ops_t *epop = enp->en_epop;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
+
+	if ((epop->epo_disable == NULL) ||
+	    (epop->epo_privilege_modify == NULL)) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ALL,
+		0, 0, handled_privileges, 0);
+	if (rc != 0)
+		goto fail2;
+
+	rc = epop->epo_disable(enp);
+	if (rc != 0)
+		goto fail3;
+
+	return (0);
+
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
diff --git a/drivers/net/sfc/base/meson.build b/drivers/net/sfc/base/meson.build
index 6fa7948..6c80305 100644
--- a/drivers/net/sfc/base/meson.build
+++ b/drivers/net/sfc/base/meson.build
@@ -20,6 +20,7 @@ sources = [
 	'efx_nvram.c',
 	'efx_phy.c',
 	'efx_port.c',
+	'efx_proxy.c',
 	'efx_rx.c',
 	'efx_sram.c',
 	'efx_tunnel.c',
@@ -43,6 +44,7 @@ sources = [
 	'ef10_nic.c',
 	'ef10_nvram.c',
 	'ef10_phy.c',
+	'ef10_proxy.c',
 	'ef10_rx.c',
 	'ef10_tx.c',
 	'ef10_vpd.c',
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index 24f3769..762c6ee 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -168,6 +168,8 @@
 
 #define EFSYS_OPT_EVB 0
 
+#define EFSYS_OPT_MCDI_PROXY_AUTH_SERVER 0
+
 /* ID */
 
 typedef struct __efsys_identifier_s efsys_identifier_t;
-- 
1.8.3.1



More information about the dev mailing list