aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-03-09 00:30:14 +0000
committerMichael Brown <mcb30@ipxe.org>2022-08-10 12:29:47 +0100
commit9f5b9e3abbeade8730811f22e385f120d36ab827 (patch)
treedd412990cf6eefafeca22664bc06c1e14b887453
parentb4216fa5063e464a16361bba247d49e8620a2cf2 (diff)
downloadipxe-9f5b9e3abbeade8730811f22e385f120d36ab827.zip
ipxe-9f5b9e3abbeade8730811f22e385f120d36ab827.tar.gz
ipxe-9f5b9e3abbeade8730811f22e385f120d36ab827.tar.bz2
[intelxl] Negotiate API version for virtual function via admin queue
Do not attempt to use the admin commands to get the firmware version and report the driver version for the virtual function driver, since these will be rejected by the E810 firmware as invalid commands when issued by a virtual function. Instead, use the mailbox interface to negotiate the API version with the physical function driver. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/drivers/net/intelxl.c20
-rw-r--r--src/drivers/net/intelxl.h19
-rw-r--r--src/drivers/net/intelxlvf.c46
3 files changed, 75 insertions, 10 deletions
diff --git a/src/drivers/net/intelxl.c b/src/drivers/net/intelxl.c
index a7fbd60..be4e911 100644
--- a/src/drivers/net/intelxl.c
+++ b/src/drivers/net/intelxl.c
@@ -847,18 +847,8 @@ int intelxl_open_admin ( struct intelxl_nic *intelxl ) {
/* (Re)open admin queues */
intelxl_reopen_admin ( intelxl );
- /* Get firmware version */
- if ( ( rc = intelxl_admin_version ( intelxl ) ) != 0 )
- goto err_version;
-
- /* Report driver version */
- if ( ( rc = intelxl_admin_driver ( intelxl ) ) != 0 )
- goto err_driver;
-
return 0;
- err_driver:
- err_version:
intelxl_disable_admin ( intelxl, &intelxl->command );
intelxl_disable_admin ( intelxl, &intelxl->event );
intelxl_free_admin ( intelxl, &intelxl->command );
@@ -1717,6 +1707,14 @@ static int intelxl_probe ( struct pci_device *pci ) {
if ( ( rc = intelxl_open_admin ( intelxl ) ) != 0 )
goto err_open_admin;
+ /* Get firmware version */
+ if ( ( rc = intelxl_admin_version ( intelxl ) ) != 0 )
+ goto err_admin_version;
+
+ /* Report driver version */
+ if ( ( rc = intelxl_admin_driver ( intelxl ) ) != 0 )
+ goto err_admin_driver;
+
/* Clear PXE mode */
if ( ( rc = intelxl_admin_clear_pxe ( intelxl ) ) != 0 )
goto err_admin_clear_pxe;
@@ -1768,6 +1766,8 @@ static int intelxl_probe ( struct pci_device *pci ) {
err_admin_vsi:
err_admin_switch:
err_admin_clear_pxe:
+ err_admin_driver:
+ err_admin_version:
intelxl_close_admin ( intelxl );
err_open_admin:
intelxl_msix_disable ( intelxl, pci, INTELXL_MSIX_VECTOR );
diff --git a/src/drivers/net/intelxl.h b/src/drivers/net/intelxl.h
index 92d7f88..2c7eb4a 100644
--- a/src/drivers/net/intelxl.h
+++ b/src/drivers/net/intelxl.h
@@ -311,6 +311,17 @@ struct intelxl_admin_link_params {
/** Admin queue Send Message to VF command */
#define INTELXL_ADMIN_SEND_TO_VF 0x0802
+/** Admin Queue VF Version opcode */
+#define INTELXL_ADMIN_VF_VERSION 0x00000001
+
+/** Admin Queue VF Version data buffer */
+struct intelxl_admin_vf_version_buffer {
+ /** Major version */
+ uint32_t major;
+ /** Minor version */
+ uint32_t minor;
+} __attribute__ (( packed ));
+
/** Admin Queue VF Reset opcode */
#define INTELXL_ADMIN_VF_RESET 0x00000002
@@ -503,6 +514,8 @@ union intelxl_admin_buffer {
struct intelxl_admin_switch_buffer sw;
/** Get VSI Parameters data buffer */
struct intelxl_admin_vsi_buffer vsi;
+ /** VF Version data buffer */
+ struct intelxl_admin_vf_version_buffer ver;
/** VF Get Resources data buffer */
struct intelxl_admin_vf_get_resources_buffer res;
/** VF Status Change Event data buffer */
@@ -598,6 +611,12 @@ intelxl_init_admin ( struct intelxl_admin *admin, unsigned int base,
/** Admin queue API major version */
#define INTELXL_ADMIN_API_MAJOR 1
+/** Admin queue VF API major version */
+#define INTELXL_ADMIN_VF_API_MAJOR 1
+
+/** Admin queue VF API minor version */
+#define INTELXL_ADMIN_VF_API_MINOR 0
+
/******************************************************************************
*
* Transmit and receive queue context
diff --git a/src/drivers/net/intelxlvf.c b/src/drivers/net/intelxlvf.c
index 7dedf0f..8febbb2 100644
--- a/src/drivers/net/intelxlvf.c
+++ b/src/drivers/net/intelxlvf.c
@@ -306,6 +306,47 @@ void intelxlvf_admin_event ( struct net_device *netdev,
}
/**
+ * Negotiate API version
+ *
+ * @v netdev Network device
+ * @ret rc Return status code
+ */
+static int intelxlvf_admin_version ( struct net_device *netdev ) {
+ struct intelxl_nic *intelxl = netdev->priv;
+ struct intelxl_admin_descriptor *cmd;
+ struct intelxl_admin_vf_version_buffer *ver;
+ union intelxl_admin_buffer *buf;
+ unsigned int api;
+ int rc;
+
+ /* Populate descriptor */
+ cmd = intelxl_admin_command_descriptor ( intelxl );
+ cmd->vopcode = cpu_to_le32 ( INTELXL_ADMIN_VF_VERSION );
+ cmd->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_RD | INTELXL_ADMIN_FL_BUF );
+ cmd->len = cpu_to_le16 ( sizeof ( buf->ver ) );
+ buf = intelxl_admin_command_buffer ( intelxl );
+ buf->ver.major = cpu_to_le32 ( INTELXL_ADMIN_VF_API_MAJOR );
+ buf->ver.minor = cpu_to_le32 ( INTELXL_ADMIN_VF_API_MINOR );
+
+ /* Issue command */
+ if ( ( rc = intelxlvf_admin_command ( netdev ) ) != 0 )
+ return rc;
+ ver = &intelxl->vbuf.ver;
+ api = le32_to_cpu ( ver->major );
+ DBGC ( intelxl, "INTELXL %p API v%d.%d\n",
+ intelxl, api, le32_to_cpu ( ver->minor ) );
+
+ /* Check for API compatibility */
+ if ( api > INTELXL_ADMIN_VF_API_MAJOR ) {
+ DBGC ( intelxl, "INTELXL %p unsupported API v%d\n",
+ intelxl, api );
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
+/**
* Get resources
*
* @v netdev Network device
@@ -636,6 +677,10 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
if ( ( rc = intelxlvf_reset_admin ( intelxl ) ) != 0 )
goto err_reset_admin;
+ /* Negotiate API version */
+ if ( ( rc = intelxlvf_admin_version ( netdev ) ) != 0 )
+ goto err_version;
+
/* Get MAC address */
if ( ( rc = intelxlvf_admin_get_resources ( netdev ) ) != 0 )
goto err_get_resources;
@@ -649,6 +694,7 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
unregister_netdev ( netdev );
err_register_netdev:
err_get_resources:
+ err_version:
err_reset_admin:
intelxl_close_admin ( intelxl );
err_open_admin: