aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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: