diff options
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/net/intelxlvf.c | 45 | ||||
-rw-r--r-- | src/drivers/net/intelxlvf.h | 14 |
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 */ |