From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from dpdk.org (dpdk.org [92.243.14.124])
	by dpdk.space (Postfix) with ESMTP id A4875A0495
	for <public@inbox.dpdk.org>; Mon, 10 Jun 2019 09:42:08 +0200 (CEST)
Received: from [92.243.14.124] (localhost [127.0.0.1])
	by dpdk.org (Postfix) with ESMTP id 5DF041BF39;
	Mon, 10 Jun 2019 09:39:38 +0200 (CEST)
Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com
 [67.231.154.164]) by dpdk.org (Postfix) with ESMTP id 8D3D41BE9C
 for <dev@dpdk.org>; Mon, 10 Jun 2019 09:38:59 +0200 (CEST)
X-Virus-Scanned: Proofpoint Essentials engine
Received: from webmail.solarflare.com (webmail.solarflare.com [12.187.104.26])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits))
 (No client certificate requested)
 by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id 857BD140058
 for <dev@dpdk.org>; Mon, 10 Jun 2019 07:38:58 +0000 (UTC)
Received: from ocex03.SolarFlarecom.com (10.20.40.36) by
 ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id
 15.0.1395.4; Mon, 10 Jun 2019 00:38:51 -0700
Received: from opal.uk.solarflarecom.com (10.17.10.1) by
 ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id
 15.0.1395.4 via Frontend Transport; Mon, 10 Jun 2019 00:38:51 -0700
Received: from ukv-loginhost.uk.solarflarecom.com
 (ukv-loginhost.uk.solarflarecom.com [10.17.10.39])
 by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id x5A7coBL008866;
 Mon, 10 Jun 2019 08:38:50 +0100
Received: from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1])
 by ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id 4C1541616E0;
 Mon, 10 Jun 2019 08:38:50 +0100 (BST)
From: Andrew Rybchenko <arybchenko@solarflare.com>
To: <dev@dpdk.org>
CC: Gautam Dawar <gdawar@solarflare.com>
Date: Mon, 10 Jun 2019 08:38:41 +0100
Message-ID: <1560152324-20538-27-git-send-email-arybchenko@solarflare.com>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1560152324-20538-1-git-send-email-arybchenko@solarflare.com>
References: <1560152324-20538-1-git-send-email-arybchenko@solarflare.com>
MIME-Version: 1.0
Content-Type: text/plain
X-TM-AS-Product-Ver: SMEX-12.5.0.1300-8.5.1010-24664.003
X-TM-AS-Result: No-7.366700-4.000000-10
X-TMASE-MatchedRID: qYdBQr1QwYAIHyE1IfGi6Ydlc1JaOB1TXs5nqGvDCfNjLp8Cm8vwF6pD
 J3T7GsWZ+xHfx8k2JFSlskwMhnibrwihmwiXCMoGPwKTD1v8YV5MkOX0Uoduuey9vsxhLmzevQS
 /jzORDUHWOjFTe37S5GmK1BXz5NhErRll5FNO+m1H+PTjR9EWkp4oEP/S42Q2jEoCiXjMvE0S99
 dUV0LYkvnCSbx7AyEmKQZUP+tGhCh78ZKYQ4N2csnUT+eskUQPVCGp3g4/hjvxVrC9HCwRJzK2i
 eu8M5yxZ3LwX2AqIR0XDKoC5H4ejY1pcgBT/7Ns4jRkIImnX0Mr9gVlOIN/6tNXOy0pXgUhltea
 i6D7W37NcUlS6Hr2U4msf/IiAf1B3bq08eBVhehhXXywTJLpfNyyh6r/9tsYSrBbamk8Kaoh6QO
 HM6EIp/muR0hyvRqJoFW8SPM0GkIfE8yM4pjsDwtuKBGekqUpI/NGWt0UYPDYHjDOorHJjI6hWi
 QKexgHlKVxZ6ITjJjYA+vquSfYTNfOOh2Ygt5I
X-TM-AS-User-Approved-Sender: No
X-TM-AS-User-Blocked-Sender: No
X-TMASE-Result: 10--7.366700-4.000000
X-TMASE-Version: SMEX-12.5.0.1300-8.5.1010-24664.003
X-MDID: 1560152339-C3XZLslxrY_l
Subject: [dpdk-dev] [PATCH 26/29] net/sfc/base: provide proxy APIs to client
	drivers
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>

From: Gautam Dawar <gdawar@solarflare.com>

Implement the APIs for PROXY_CMD, PROXY_COMPLETE and PRIVILEGE_MASK
messages to allow client drivers authorize VF operations like set MAC,
set MTU etc. with firmware.

Signed-off-by: Gautam Dawar <gdawar@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_impl.h  |  19 ++++
 drivers/net/sfc/base/ef10_proxy.c | 208 ++++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/base/efx.h        |  29 ++++++
 drivers/net/sfc/base/efx_impl.h   |   5 +
 drivers/net/sfc/base/efx_mcdi.c   |  34 ++++++-
 drivers/net/sfc/base/efx_mcdi.h   |   2 +-
 drivers/net/sfc/base/efx_proxy.c  | 100 ++++++++++++++++++
 7 files changed, 394 insertions(+), 3 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index 4b719c9..e9ce31a 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -1376,6 +1376,25 @@ extern	__checkReturn	__success(return != B_FALSE)	boolean_t
 	__in		uint32_t add_privileges_mask,
 	__in		uint32_t remove_privileges_mask);
 
+	__checkReturn	efx_rc_t
+ef10_proxy_auth_set_privilege_mask(
+	__in		efx_nic_t *enp,
+	__in		uint32_t vf_index,
+	__in		uint32_t mask,
+	__in		uint32_t value);
+
+	__checkReturn	efx_rc_t
+ef10_proxy_auth_complete_request(
+	__in		efx_nic_t *enp,
+	__in		uint32_t fn_index,
+	__in		uint32_t proxy_result,
+	__in		uint32_t handle);
+
+	__checkReturn	efx_rc_t
+ef10_proxy_auth_exec_cmd(
+	__in		efx_nic_t *enp,
+	__inout		efx_proxy_cmd_params_t *paramsp);
+
 #endif  /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
 
 #if EFSYS_OPT_RX_PACKED_STREAM
diff --git a/drivers/net/sfc/base/ef10_proxy.c b/drivers/net/sfc/base/ef10_proxy.c
index 6b1afcc..a3b73f4 100644
--- a/drivers/net/sfc/base/ef10_proxy.c
+++ b/drivers/net/sfc/base/ef10_proxy.c
@@ -252,4 +252,212 @@
 	return (efx_mcdi_privilege_modify(enp, fn_group, pf_index, vf_index,
 			add_privileges_mask, remove_privileges_mask));
 }
+
+static	__checkReturn	efx_rc_t
+efx_mcdi_privilege_mask_set(
+	__in		efx_nic_t *enp,
+	__in		uint32_t vf_index,
+	__in		uint32_t mask,
+	__in		uint32_t value)
+{
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PRIVILEGE_MASK_IN_LEN,
+		MC_CMD_PRIVILEGE_MASK_OUT_LEN);
+	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+	efx_mcdi_req_t req;
+	efx_rc_t rc;
+	uint32_t old_mask = 0;
+	uint32_t new_mask = 0;
+
+	EFSYS_ASSERT((value & ~mask) == 0);
+
+	req.emr_cmd = MC_CMD_PRIVILEGE_MASK;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_PRIVILEGE_MASK_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_PRIVILEGE_MASK_OUT_LEN;
+
+	/* Get privilege mask */
+	MCDI_IN_POPULATE_DWORD_2(req, PRIVILEGE_MASK_IN_FUNCTION,
+		PRIVILEGE_MASK_IN_FUNCTION_PF, encp->enc_pf,
+		PRIVILEGE_MASK_IN_FUNCTION_VF, vf_index);
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail1;
+	}
+
+	if (req.emr_out_length_used != MC_CMD_PRIVILEGE_MASK_OUT_LEN) {
+		rc = EMSGSIZE;
+		goto fail2;
+	}
+
+	old_mask = *MCDI_OUT2(req, uint32_t, PRIVILEGE_MASK_OUT_OLD_MASK);
+	new_mask = old_mask & ~mask;
+	new_mask |= (value & mask);
+
+	if (new_mask == old_mask)
+		return (0);
+
+	new_mask |= MC_CMD_PRIVILEGE_MASK_IN_DO_CHANGE;
+	memset(payload, 0, sizeof (payload));
+
+	req.emr_cmd = MC_CMD_PRIVILEGE_MASK;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_PRIVILEGE_MASK_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_PRIVILEGE_MASK_OUT_LEN;
+
+	/* Set privilege mask */
+	MCDI_IN_SET_DWORD(req, PRIVILEGE_MASK_IN_NEW_MASK, new_mask);
+
+	efx_mcdi_execute(enp, &req);
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail3;
+	}
+
+	if (req.emr_out_length_used != MC_CMD_PRIVILEGE_MASK_OUT_LEN) {
+		rc = EMSGSIZE;
+		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
+ef10_proxy_auth_set_privilege_mask(
+	__in		efx_nic_t *enp,
+	__in		uint32_t vf_index,
+	__in		uint32_t mask,
+	__in		uint32_t value)
+{
+	return (efx_mcdi_privilege_mask_set(enp, vf_index,
+			mask, value));
+}
+
+static	__checkReturn	efx_rc_t
+efx_mcdi_proxy_complete(
+	__in		efx_nic_t *enp,
+	__in		uint32_t fn_index,
+	__in		uint32_t proxy_result,
+	__in		uint32_t handle)
+{
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PROXY_COMPLETE_IN_LEN,
+		MC_CMD_PROXY_COMPLETE_OUT_LEN);
+	efx_mcdi_req_t req;
+	efx_rc_t rc;
+
+	req.emr_cmd = MC_CMD_PROXY_COMPLETE;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_PROXY_COMPLETE_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_PROXY_COMPLETE_OUT_LEN;
+
+	MCDI_IN_SET_DWORD(req, PROXY_COMPLETE_IN_BLOCK_INDEX, fn_index);
+	MCDI_IN_SET_DWORD(req, PROXY_COMPLETE_IN_STATUS, proxy_result);
+	MCDI_IN_SET_DWORD(req, PROXY_COMPLETE_IN_HANDLE, handle);
+
+	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);
+}
+
+	__checkReturn	efx_rc_t
+ef10_proxy_auth_complete_request(
+	__in		efx_nic_t *enp,
+	__in		uint32_t fn_index,
+	__in		uint32_t proxy_result,
+	__in		uint32_t handle)
+{
+	return (efx_mcdi_proxy_complete(enp, fn_index,
+			proxy_result, handle));
+}
+
+static	__checkReturn			efx_rc_t
+efx_mcdi_proxy_cmd(
+	__in				efx_nic_t *enp,
+	__in				uint32_t pf_index,
+	__in				uint32_t vf_index,
+	__in_bcount(request_size)	uint8_t *request_bufferp,
+	__in				size_t request_size,
+	__out_bcount(response_size)	uint8_t *response_bufferp,
+	__in				size_t response_size,
+	__out_opt			size_t *response_size_actualp)
+{
+	efx_dword_t *inbufp;
+	efx_mcdi_req_t req;
+	efx_rc_t rc;
+
+	if (request_size % sizeof (*inbufp) != 0) {
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	EFSYS_KMEM_ALLOC(enp, (MC_CMD_PROXY_CMD_IN_LEN + request_size), inbufp);
+
+	req.emr_cmd = MC_CMD_PROXY_CMD;
+	req.emr_in_buf = (uint8_t *) inbufp;
+	req.emr_in_length = MC_CMD_PROXY_CMD_IN_LEN + request_size;
+	req.emr_out_buf = response_bufferp;
+	req.emr_out_length = response_size;
+
+	MCDI_IN_POPULATE_DWORD_2(req, PROXY_CMD_IN_TARGET,
+		 PROXY_CMD_IN_TARGET_PF, pf_index,
+		 PROXY_CMD_IN_TARGET_VF, vf_index);
+
+	/* Proxied command should be located just after PROXY_CMD */
+	memcpy(&inbufp[MC_CMD_PROXY_CMD_IN_LEN / sizeof (*inbufp)],
+		request_bufferp, request_size);
+
+	efx_mcdi_execute(enp, &req);
+
+	EFSYS_KMEM_FREE(enp, (MC_CMD_PROXY_CMD_IN_LEN + request_size), inbufp);
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail2;
+	}
+
+	if (response_size_actualp != NULL)
+		*response_size_actualp = req.emr_out_length_used;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+ef10_proxy_auth_exec_cmd(
+	__in		efx_nic_t *enp,
+	__inout		efx_proxy_cmd_params_t *paramsp)
+{
+	return (efx_mcdi_proxy_cmd(enp, paramsp->pf_index, paramsp->vf_index,
+			paramsp->request_bufferp, paramsp->request_size,
+			paramsp->response_bufferp, paramsp->response_size,
+			paramsp->response_size_actualp));
+}
 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 97c4e62..e43302a 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -3434,6 +3434,16 @@ extern	__checkReturn	__success(return != B_FALSE)	boolean_t
 	uint32_t	handled_privileges;
 } efx_proxy_auth_config_t;
 
+typedef struct efx_proxy_cmd_params_s {
+	uint32_t	pf_index;
+	uint32_t	vf_index;
+	uint8_t		*request_bufferp;
+	size_t		request_size;
+	uint8_t		*response_bufferp;
+	size_t		response_size;
+	size_t		*response_size_actualp;
+} efx_proxy_cmd_params_t;
+
 extern	__checkReturn	efx_rc_t
 efx_proxy_auth_init(
 	__in		efx_nic_t *enp);
@@ -3452,6 +3462,25 @@ extern	__checkReturn	__success(return != B_FALSE)	boolean_t
 	__in		efx_nic_t *enp,
 	__in		uint32_t handled_privileges);
 
+	__checkReturn	efx_rc_t
+efx_proxy_auth_complete_request(
+	__in		efx_nic_t *enp,
+	__in		uint32_t fn_index,
+	__in		uint32_t proxy_result,
+	__in		uint32_t handle);
+
+	__checkReturn	efx_rc_t
+efx_proxy_auth_exec_cmd(
+	__in		efx_nic_t *enp,
+	__inout		efx_proxy_cmd_params_t *paramsp);
+
+	__checkReturn	efx_rc_t
+efx_proxy_auth_set_privilege_mask(
+	__in		efx_nic_t *enp,
+	__in		uint32_t vf_index,
+	__in		uint32_t mask,
+	__in		uint32_t value);
+
 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
 
 #ifdef	__cplusplus
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 6a8fee8..6c72166 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -706,6 +706,11 @@ struct efx_vswitch_s {
 	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_rc_t	(*epo_set_privilege_mask)(efx_nic_t *, uint32_t,
+					uint32_t, uint32_t);
+	efx_rc_t	(*epo_complete_request)(efx_nic_t *, uint32_t,
+					uint32_t, uint32_t);
+	efx_rc_t	(*epo_exec_cmd)(efx_nic_t *, efx_proxy_cmd_params_t *);
 } efx_proxy_ops_t;
 
 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
diff --git a/drivers/net/sfc/base/efx_mcdi.c b/drivers/net/sfc/base/efx_mcdi.c
index 325c2e4..e840401 100644
--- a/drivers/net/sfc/base/efx_mcdi.c
+++ b/drivers/net/sfc/base/efx_mcdi.c
@@ -360,7 +360,11 @@
 		rc = EIO;
 		goto fail1;
 	}
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+	if (((cmd != emrp->emr_cmd) && (emrp->emr_cmd != MC_CMD_PROXY_CMD)) ||
+#else
 	if ((cmd != emrp->emr_cmd) ||
+#endif
 	    (seq != ((emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ)))) {
 		/* Response is for a different request */
 		rc = EIO;
@@ -442,6 +446,11 @@
 	efx_dword_t hdr[2];
 	unsigned int hdr_len;
 	size_t bytes;
+	unsigned int resp_off;
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+	unsigned int resp_cmd;
+	boolean_t proxied_cmd_resp = B_FALSE;
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
 
 	if (emrp->emr_out_buf == NULL)
 		return;
@@ -456,14 +465,35 @@
 		 */
 		efx_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1]));
 		hdr_len += sizeof (hdr[1]);
+		resp_off = hdr_len;
 
 		emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr[1],
-					    MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+						MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+		/*
+		 * A proxy MCDI command is executed by PF on behalf of
+		 * one of its VFs. The command to be proxied follows
+		 * immediately afterward in the host buffer.
+		 * PROXY_CMD inner call complete response should be copied to
+		 * output buffer so that it can be returned to the requesting
+		 * function in MC_CMD_PROXY_COMPLETE payload.
+		 */
+		resp_cmd =
+			EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
+		proxied_cmd_resp = ((emrp->emr_cmd == MC_CMD_PROXY_CMD) &&
+					(resp_cmd != MC_CMD_PROXY_CMD));
+		if (proxied_cmd_resp) {
+			resp_off = 0;
+			emrp->emr_out_length_used += hdr_len;
+		}
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
+	} else {
+		resp_off = hdr_len;
 	}
 
 	/* Copy payload out into caller supplied buffer */
 	bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length);
-	efx_mcdi_read_response(enp, emrp->emr_out_buf, hdr_len, bytes);
+	efx_mcdi_read_response(enp, emrp->emr_out_buf, resp_off, bytes);
 
 #if EFSYS_OPT_MCDI_LOGGING
 	if (emtp->emt_logger != NULL) {
diff --git a/drivers/net/sfc/base/efx_mcdi.h b/drivers/net/sfc/base/efx_mcdi.h
index 56c0ab1..74cde50 100644
--- a/drivers/net/sfc/base/efx_mcdi.h
+++ b/drivers/net/sfc/base/efx_mcdi.h
@@ -31,7 +31,7 @@ struct efx_mcdi_req_s {
 	unsigned int	emr_cmd;
 	uint8_t		*emr_in_buf;
 	size_t		emr_in_length;
-	/* Outputs: retcode, buffer, length, and length used */
+	/* Outputs: retcode, buffer, length and length used */
 	efx_rc_t	emr_rc;
 	uint8_t		*emr_out_buf;
 	size_t		emr_out_length;
diff --git a/drivers/net/sfc/base/efx_proxy.c b/drivers/net/sfc/base/efx_proxy.c
index 6aadf07..b04e7dd 100644
--- a/drivers/net/sfc/base/efx_proxy.c
+++ b/drivers/net/sfc/base/efx_proxy.c
@@ -16,6 +16,9 @@
 	NULL,			/* epo_mc_config */
 	NULL,			/* epo_disable */
 	NULL,			/* epo_privilege_modify */
+	NULL,			/* epo_set_privilege_mask */
+	NULL,			/* epo_complete_request */
+	NULL,			/* epo_exec_cmd */
 };
 #endif /* EFSYS_OPT_SIENA */
 
@@ -26,6 +29,9 @@
 	ef10_proxy_auth_mc_config,		/* epo_mc_config */
 	ef10_proxy_auth_disable,		/* epo_disable */
 	ef10_proxy_auth_privilege_modify,	/* epo_privilege_modify */
+	ef10_proxy_auth_set_privilege_mask,	/* epo_set_privilege_mask */
+	ef10_proxy_auth_complete_request,	/* epo_complete_request */
+	ef10_proxy_auth_exec_cmd,		/* epo_exec_cmd */
 };
 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
 
@@ -197,4 +203,98 @@
 	return (rc);
 }
 
+	__checkReturn	efx_rc_t
+efx_proxy_auth_complete_request(
+	__in		efx_nic_t *enp,
+	__in		uint32_t fn_index,
+	__in		uint32_t proxy_result,
+	__in		uint32_t handle)
+{
+	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_complete_request == NULL) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	rc = epop->epo_complete_request(enp, fn_index, proxy_result, handle);
+	if (rc != 0)
+		goto fail2;
+
+	return (0);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+efx_proxy_auth_exec_cmd(
+	__in		efx_nic_t *enp,
+	__inout		efx_proxy_cmd_params_t *paramsp)
+{
+	const efx_proxy_ops_t *epop = enp->en_epop;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
+
+	if (paramsp == NULL) {
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	if (epop->epo_exec_cmd == NULL) {
+		rc = ENOTSUP;
+		goto fail2;
+	}
+
+	rc = epop->epo_exec_cmd(enp, paramsp);
+	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);
+}
+
+	__checkReturn	efx_rc_t
+efx_proxy_auth_set_privilege_mask(
+	__in		efx_nic_t *enp,
+	__in		uint32_t vf_index,
+	__in		uint32_t mask,
+	__in		uint32_t value)
+{
+	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_set_privilege_mask == NULL) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	rc = epop->epo_set_privilege_mask(enp, vf_index, mask, value);
+	if (rc != 0)
+		goto fail2;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+
 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
-- 
1.8.3.1