From 491c075f7f3ce3e7d58e969d8fcd0af1e102e515 Mon Sep 17 00:00:00 2001
From: Michael Brown <mcb30@ipxe.org>
Date: Tue, 16 Aug 2022 15:48:24 +0100
Subject: [intelxl] Negotiate virtual function API version 1.1

Negotiate API version 1.1 in order to allow access to virtual function
opcodes that are disallowed by default on the E810.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
---
 src/drivers/net/intelxl.h   |  2 ++
 src/drivers/net/intelxlvf.c |  7 ++++++-
 src/drivers/net/intelxlvf.h | 25 +++++++++++++++++++++++--
 3 files changed, 31 insertions(+), 3 deletions(-)

(limited to 'src')

diff --git a/src/drivers/net/intelxl.h b/src/drivers/net/intelxl.h
index 0db16b5..6c7865a 100644
--- a/src/drivers/net/intelxl.h
+++ b/src/drivers/net/intelxl.h
@@ -927,6 +927,8 @@ struct intelxl_nic {
 	unsigned int qset;
 	/** Transmit element ID */
 	uint32_t teid;
+	/** Device capabilities */
+	uint32_t caps;
 	/** Interrupt control register */
 	unsigned int intr;
 	/** PCI Express capability offset */
diff --git a/src/drivers/net/intelxlvf.c b/src/drivers/net/intelxlvf.c
index c58520a..79245b4 100644
--- a/src/drivers/net/intelxlvf.c
+++ b/src/drivers/net/intelxlvf.c
@@ -377,16 +377,21 @@ static int intelxlvf_admin_get_resources ( struct net_device *netdev ) {
 	/* Populate descriptor */
 	cmd = intelxlvf_admin_command_descriptor ( intelxl );
 	cmd->vopcode = cpu_to_le32 ( INTELXLVF_ADMIN_GET_RESOURCES );
+	cmd->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_RD | INTELXL_ADMIN_FL_BUF );
+	cmd->len = cpu_to_le16 ( sizeof ( buf->caps ) );
 	buf = intelxlvf_admin_command_buffer ( intelxl );
+	buf->caps.caps = cpu_to_le32 ( INTELXLVF_ADMIN_CAP_L2 );
 
 	/* Issue command */
 	if ( ( rc = intelxlvf_admin_command ( netdev ) ) != 0 )
 		return rc;
 
 	/* Parse response */
+	intelxl->caps = le32_to_cpu ( buf->res.caps );
 	intelxl->vsi = le16_to_cpu ( buf->res.vsi );
 	memcpy ( netdev->hw_addr, buf->res.mac, ETH_ALEN );
-	DBGC ( intelxl, "INTELXL %p VSI %#04x\n", intelxl, intelxl->vsi );
+	DBGC ( intelxl, "INTELXL %p capabilities %#08x VSI %#04x\n",
+	       intelxl, intelxl->caps, intelxl->vsi );
 
 	return 0;
 }
diff --git a/src/drivers/net/intelxlvf.h b/src/drivers/net/intelxlvf.h
index c537f6a..783c856 100644
--- a/src/drivers/net/intelxlvf.h
+++ b/src/drivers/net/intelxlvf.h
@@ -91,7 +91,7 @@ struct intelxlvf_admin_version_buffer {
 #define INTELXLVF_ADMIN_API_MAJOR 1
 
 /** Admin queue VF API minor version */
-#define INTELXLVF_ADMIN_API_MINOR 0
+#define INTELXLVF_ADMIN_API_MINOR 1
 
 /** Admin Queue VF Reset opcode */
 #define INTELXLVF_ADMIN_RESET 0x00000002
@@ -99,10 +99,26 @@ struct intelxlvf_admin_version_buffer {
 /** Admin Queue VF Get Resources opcode */
 #define INTELXLVF_ADMIN_GET_RESOURCES 0x00000003
 
+/** Admin Queue VF Capabilities data buffer */
+struct intelxlvf_admin_capabilities_buffer {
+	/** Capabilities */
+	uint32_t caps;
+} __attribute__ (( packed ));
+
 /** Admin Queue VF Get Resources data buffer */
 struct intelxlvf_admin_get_resources_buffer {
+	/** Number of VSIs */
+	uint16_t vsis;
+	/** Number of queue pairs */
+	uint16_t qps;
+	/** Number of MSI-X vectors */
+	uint16_t vectors;
+	/** Maximum MTU */
+	uint16_t mtu;
+	/** Capabilities */
+	uint32_t caps;
 	/** Reserved */
-	uint8_t reserved_a[20];
+	uint8_t reserved_a[8];
 	/** VSI switching element ID */
 	uint16_t vsi;
 	/** Reserved */
@@ -111,6 +127,9 @@ struct intelxlvf_admin_get_resources_buffer {
 	uint8_t mac[ETH_ALEN];
 } __attribute__ (( packed ));
 
+/** Layer 2 capabilities (add/remove MAC, configure promiscuous mode) */
+#define INTELXLVF_ADMIN_CAP_L2 0x00000001
+
 /** Admin Queue VF Status Change Event opcode */
 #define INTELXLVF_ADMIN_STATUS 0x00000011
 
@@ -286,6 +305,8 @@ union intelxlvf_admin_buffer {
 	union intelxl_admin_buffer xl;
 	/** VF Version data buffer */
 	struct intelxlvf_admin_version_buffer ver;
+	/** VF Capabilities data buffer */
+	struct intelxlvf_admin_capabilities_buffer caps;
 	/** VF Get Resources data buffer */
 	struct intelxlvf_admin_get_resources_buffer res;
 	/** VF Status Change Event data buffer */
-- 
cgit v1.1