aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/net/intelxlvf.c45
-rw-r--r--src/drivers/net/intelxlvf.h14
2 files changed, 58 insertions, 1 deletions
diff --git a/src/drivers/net/intelxlvf.c b/src/drivers/net/intelxlvf.c
index e30d8c6..0831955 100644
--- a/src/drivers/net/intelxlvf.c
+++ b/src/drivers/net/intelxlvf.c
@@ -395,7 +395,8 @@ static int intelxlvf_admin_get_resources ( struct net_device *netdev ) {
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 );
+ buf->caps.caps = cpu_to_le32 ( INTELXLVF_ADMIN_CAP_L2 |
+ INTELXLVF_ADMIN_CAP_RQPS );
/* Issue command */
if ( ( rc = intelxlvf_admin_command ( netdev ) ) != 0 )
@@ -462,6 +463,42 @@ static int intelxlvf_admin_stats ( struct net_device *netdev ) {
return 0;
}
+/**
+ * Configure number of queue pairs
+ *
+ * @v netdev Network device
+ * @ret rc Return status code
+ */
+static int intelxlvf_admin_request_qps ( struct net_device *netdev ) {
+ struct intelxl_nic *intelxl = netdev->priv;
+ struct intelxlvf_admin_descriptor *cmd;
+ union intelxlvf_admin_buffer *buf;
+ int rc;
+
+ /* Populate descriptor */
+ cmd = intelxlvf_admin_command_descriptor ( intelxl );
+ cmd->opcode = cpu_to_le16 ( INTELXLVF_ADMIN_SEND_TO_PF );
+ cmd->vopcode = cpu_to_le32 ( INTELXLVF_ADMIN_REQUEST_QPS );
+ cmd->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_RD | INTELXL_ADMIN_FL_BUF );
+ cmd->len = cpu_to_le16 ( sizeof ( buf->rqps ) );
+ buf = intelxlvf_admin_command_buffer ( intelxl );
+ buf->rqps.count = cpu_to_le16 ( 1 );
+
+ /* Issue command (which will trigger a reset) */
+ if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
+ return rc;
+
+ /* Wait for reset to complete */
+ if ( ( rc = intelxlvf_reset_wait ( intelxl ) ) != 0 )
+ return rc;
+
+ /* Reestablish capabilities to reactivate VF after reset */
+ if ( ( rc = intelxlvf_admin_get_resources ( netdev ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
/******************************************************************************
*
* Network device interface
@@ -781,6 +818,11 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
if ( ( rc = intelxlvf_admin_get_resources ( netdev ) ) != 0 )
goto err_get_resources;
+ /* Configure number of queue pairs, if applicable */
+ if ( ( intelxl->caps & INTELXLVF_ADMIN_CAP_RQPS ) &&
+ ( ( rc = intelxlvf_admin_request_qps ( netdev ) ) != 0 ) )
+ goto err_rqps;
+
/* Register network device */
if ( ( rc = register_netdev ( netdev ) ) != 0 )
goto err_register_netdev;
@@ -789,6 +831,7 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
unregister_netdev ( netdev );
err_register_netdev:
+ err_rqps:
err_get_resources:
err_version:
err_reset_admin:
diff --git a/src/drivers/net/intelxlvf.h b/src/drivers/net/intelxlvf.h
index 783c856..95ddf94 100644
--- a/src/drivers/net/intelxlvf.h
+++ b/src/drivers/net/intelxlvf.h
@@ -130,6 +130,9 @@ struct intelxlvf_admin_get_resources_buffer {
/** Layer 2 capabilities (add/remove MAC, configure promiscuous mode) */
#define INTELXLVF_ADMIN_CAP_L2 0x00000001
+/** Request Queues capabilities */
+#define INTELXLVF_ADMIN_CAP_RQPS 0x00000040
+
/** Admin Queue VF Status Change Event opcode */
#define INTELXLVF_ADMIN_STATUS 0x00000011
@@ -299,6 +302,15 @@ struct intelxlvf_admin_stats_buffer {
struct intelxlvf_admin_stats tx;
} __attribute__ (( packed ));
+/** Admin Queue VF Request Queues opcode */
+#define INTELXLVF_ADMIN_REQUEST_QPS 0x0000001d
+
+/** Admin Queue VF Request Queues data buffer */
+struct intelxlvf_admin_request_qps_buffer {
+ /** Number of queue pairs */
+ uint16_t count;
+} __attribute__ (( packed ));
+
/** Admin queue data buffer */
union intelxlvf_admin_buffer {
/** Original 40 Gigabit Ethernet data buffer */
@@ -321,6 +333,8 @@ union intelxlvf_admin_buffer {
struct intelxlvf_admin_irq_map_buffer irq;
/** VF Get Statistics data buffer */
struct intelxlvf_admin_stats_buffer stats;
+ /** VF Request Queues data buffer */
+ struct intelxlvf_admin_request_qps_buffer rqps;
} __attribute__ (( packed ));
/** Admin queue descriptor */