mirror of https://github.com/ipxe/ipxe.git
[intelxl] Use non-zero MSI-X vector for virtual function interrupts
The 100 Gigabit physical function driver requires a virtual function driver to request that transmit and receive queues are mapped to MSI-X vector 1 or higher. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/697/head^2
parent
1b61c2118c
commit
b4216fa506
|
@ -104,10 +104,11 @@ static int intelxl_fetch_mac ( struct intelxl_nic *intelxl,
|
|||
*
|
||||
* @v intelxl Intel device
|
||||
* @v pci PCI device
|
||||
* @v vector MSI-X vector
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int intelxl_msix_enable ( struct intelxl_nic *intelxl,
|
||||
struct pci_device *pci ) {
|
||||
struct pci_device *pci, unsigned int vector ) {
|
||||
int rc;
|
||||
|
||||
/* Map dummy target location */
|
||||
|
@ -126,12 +127,12 @@ int intelxl_msix_enable ( struct intelxl_nic *intelxl,
|
|||
goto err_enable;
|
||||
}
|
||||
|
||||
/* Configure interrupt zero to write to dummy location */
|
||||
pci_msix_map ( &intelxl->msix.cap, 0,
|
||||
/* Configure interrupt to write to dummy location */
|
||||
pci_msix_map ( &intelxl->msix.cap, vector,
|
||||
dma ( &intelxl->msix.map, &intelxl->msix.msg ), 0 );
|
||||
|
||||
/* Enable dummy interrupt zero */
|
||||
pci_msix_unmask ( &intelxl->msix.cap, 0 );
|
||||
/* Enable dummy interrupt */
|
||||
pci_msix_unmask ( &intelxl->msix.cap, vector );
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -147,12 +148,13 @@ int intelxl_msix_enable ( struct intelxl_nic *intelxl,
|
|||
*
|
||||
* @v intelxl Intel device
|
||||
* @v pci PCI device
|
||||
* @v vector MSI-X vector
|
||||
*/
|
||||
void intelxl_msix_disable ( struct intelxl_nic *intelxl,
|
||||
struct pci_device *pci ) {
|
||||
struct pci_device *pci, unsigned int vector ) {
|
||||
|
||||
/* Disable dummy interrupt zero */
|
||||
pci_msix_mask ( &intelxl->msix.cap, 0 );
|
||||
/* Disable dummy interrupts */
|
||||
pci_msix_mask ( &intelxl->msix.cap, vector );
|
||||
|
||||
/* Disable MSI-X capability */
|
||||
pci_msix_disable ( pci, &intelxl->msix.cap );
|
||||
|
@ -1707,7 +1709,8 @@ static int intelxl_probe ( struct pci_device *pci ) {
|
|||
goto err_fetch_mac;
|
||||
|
||||
/* Enable MSI-X dummy interrupt */
|
||||
if ( ( rc = intelxl_msix_enable ( intelxl, pci ) ) != 0 )
|
||||
if ( ( rc = intelxl_msix_enable ( intelxl, pci,
|
||||
INTELXL_MSIX_VECTOR ) ) != 0 )
|
||||
goto err_msix;
|
||||
|
||||
/* Open admin queues */
|
||||
|
@ -1767,7 +1770,7 @@ static int intelxl_probe ( struct pci_device *pci ) {
|
|||
err_admin_clear_pxe:
|
||||
intelxl_close_admin ( intelxl );
|
||||
err_open_admin:
|
||||
intelxl_msix_disable ( intelxl, pci );
|
||||
intelxl_msix_disable ( intelxl, pci, INTELXL_MSIX_VECTOR );
|
||||
err_msix:
|
||||
err_fetch_mac:
|
||||
pci_reset ( pci, intelxl->exp );
|
||||
|
@ -1796,7 +1799,7 @@ static void intelxl_remove ( struct pci_device *pci ) {
|
|||
intelxl_close_admin ( intelxl );
|
||||
|
||||
/* Disable MSI-X dummy interrupt */
|
||||
intelxl_msix_disable ( intelxl, pci );
|
||||
intelxl_msix_disable ( intelxl, pci, INTELXL_MSIX_VECTOR );
|
||||
|
||||
/* Reset the NIC */
|
||||
pci_reset ( pci, intelxl->exp );
|
||||
|
|
|
@ -1035,6 +1035,9 @@ struct intelxl_msix {
|
|||
struct dma_mapping map;
|
||||
};
|
||||
|
||||
/** MSI-X interrupt vector */
|
||||
#define INTELXL_MSIX_VECTOR 0
|
||||
|
||||
/** An Intel 40 Gigabit network card */
|
||||
struct intelxl_nic {
|
||||
/** Registers */
|
||||
|
@ -1084,9 +1087,11 @@ struct intelxl_nic {
|
|||
};
|
||||
|
||||
extern int intelxl_msix_enable ( struct intelxl_nic *intelxl,
|
||||
struct pci_device *pci );
|
||||
struct pci_device *pci,
|
||||
unsigned int vector );
|
||||
extern void intelxl_msix_disable ( struct intelxl_nic *intelxl,
|
||||
struct pci_device *pci );
|
||||
struct pci_device *pci,
|
||||
unsigned int vector );
|
||||
extern struct intelxl_admin_descriptor *
|
||||
intelxl_admin_command_descriptor ( struct intelxl_nic *intelxl );
|
||||
extern union intelxl_admin_buffer *
|
||||
|
|
|
@ -399,6 +399,7 @@ static int intelxlvf_admin_irq_map ( struct net_device *netdev ) {
|
|||
buf = intelxl_admin_command_buffer ( intelxl );
|
||||
buf->irq.count = cpu_to_le16 ( 1 );
|
||||
buf->irq.vsi = cpu_to_le16 ( intelxl->vsi );
|
||||
buf->irq.vec = cpu_to_le16 ( INTELXLVF_MSIX_VECTOR );
|
||||
buf->irq.rxmap = cpu_to_le16 ( 0x0001 );
|
||||
buf->irq.txmap = cpu_to_le16 ( 0x0001 );
|
||||
|
||||
|
@ -583,7 +584,7 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
|
|||
pci_set_drvdata ( pci, netdev );
|
||||
netdev->dev = &pci->dev;
|
||||
memset ( intelxl, 0, sizeof ( *intelxl ) );
|
||||
intelxl->intr = INTELXLVF_VFINT_DYN_CTL0;
|
||||
intelxl->intr = INTELXLVF_VFINT_DYN_CTLN ( INTELXLVF_MSIX_VECTOR );
|
||||
intelxl_init_admin ( &intelxl->command, INTELXLVF_ADMIN,
|
||||
&intelxlvf_admin_command_offsets );
|
||||
intelxl_init_admin ( &intelxl->event, INTELXLVF_ADMIN,
|
||||
|
@ -623,7 +624,8 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
|
|||
pci_reset ( pci, intelxl->exp );
|
||||
|
||||
/* Enable MSI-X dummy interrupt */
|
||||
if ( ( rc = intelxl_msix_enable ( intelxl, pci ) ) != 0 )
|
||||
if ( ( rc = intelxl_msix_enable ( intelxl, pci,
|
||||
INTELXLVF_MSIX_VECTOR ) ) != 0 )
|
||||
goto err_msix;
|
||||
|
||||
/* Open admin queues */
|
||||
|
@ -650,7 +652,7 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
|
|||
err_reset_admin:
|
||||
intelxl_close_admin ( intelxl );
|
||||
err_open_admin:
|
||||
intelxl_msix_disable ( intelxl, pci );
|
||||
intelxl_msix_disable ( intelxl, pci, INTELXLVF_MSIX_VECTOR );
|
||||
err_msix:
|
||||
pci_reset ( pci, intelxl->exp );
|
||||
err_exp:
|
||||
|
@ -681,7 +683,7 @@ static void intelxlvf_remove ( struct pci_device *pci ) {
|
|||
intelxl_close_admin ( intelxl );
|
||||
|
||||
/* Disable MSI-X dummy interrupt */
|
||||
intelxl_msix_disable ( intelxl, pci );
|
||||
intelxl_msix_disable ( intelxl, pci, INTELXLVF_MSIX_VECTOR );
|
||||
|
||||
/* Reset the function via PCIe FLR */
|
||||
pci_reset ( pci, intelxl->exp );
|
||||
|
|
|
@ -14,12 +14,23 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
/** BAR size */
|
||||
#define INTELXLVF_BAR_SIZE 0x10000
|
||||
|
||||
/** MSI-X vector
|
||||
*
|
||||
* The 100 Gigabit physical function driver requires a virtual
|
||||
* function driver to request that transmit and receive queues are
|
||||
* mapped to MSI-X vector 1 or higher.
|
||||
*/
|
||||
#define INTELXLVF_MSIX_VECTOR 1
|
||||
|
||||
/** Transmit Queue Tail Register */
|
||||
#define INTELXLVF_QTX_TAIL 0x00000
|
||||
|
||||
/** Receive Queue Tail Register */
|
||||
#define INTELXLVF_QRX_TAIL 0x02000
|
||||
|
||||
/** VF Interrupt N Dynamic Control Register */
|
||||
#define INTELXLVF_VFINT_DYN_CTLN( x ) ( 0x3800 + ( 0x4 * ( (x) - 1 ) ) )
|
||||
|
||||
/** VF Interrupt Zero Dynamic Control Register */
|
||||
#define INTELXLVF_VFINT_DYN_CTL0 0x5c00
|
||||
|
||||
|
|
Loading…
Reference in New Issue