[intelxl] Handle admin events via a callback

The physical and virtual function drivers each care about precisely
one admin queue event type.  Simplify event handling by using a
per-driver callback instead of the existing weak function symbol.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/697/head^2
Michael Brown 2022-08-08 14:34:47 +01:00
parent 9e46ffa924
commit 67f8878e10
3 changed files with 43 additions and 30 deletions

View File

@ -743,18 +743,26 @@ static int intelxl_admin_link ( struct net_device *netdev ) {
} }
/** /**
* Handle virtual function event (when VF driver is not present) * Handle admin event
* *
* @v netdev Network device * @v netdev Network device
* @v evt Admin queue event descriptor * @v evt Event descriptor
* @v buf Admin queue event data buffer * @v buf Data buffer
*/ */
__weak void static void intelxl_admin_event ( struct net_device *netdev,
intelxlvf_admin_event ( struct net_device *netdev __unused, struct intelxl_admin_descriptor *evt,
struct intelxl_admin_descriptor *evt __unused,
union intelxl_admin_buffer *buf __unused ) { union intelxl_admin_buffer *buf __unused ) {
struct intelxl_nic *intelxl = netdev->priv;
/* Nothing to do */ /* Ignore unrecognised events */
if ( evt->opcode != cpu_to_le16 ( INTELXL_ADMIN_LINK ) ) {
DBGC ( intelxl, "INTELXL %p unrecognised event opcode "
"%#04x\n", intelxl, le16_to_cpu ( evt->opcode ) );
return;
}
/* Update link status */
intelxl_admin_link ( netdev );
} }
/** /**
@ -806,19 +814,7 @@ void intelxl_poll_admin ( struct net_device *netdev ) {
} }
/* Handle event */ /* Handle event */
switch ( evt->opcode ) { intelxl->handle ( netdev, evt, buf );
case cpu_to_le16 ( INTELXL_ADMIN_LINK ):
intelxl_admin_link ( netdev );
break;
case cpu_to_le16 ( INTELXL_ADMIN_SEND_TO_VF ):
intelxlvf_admin_event ( netdev, evt, buf );
break;
default:
DBGC ( intelxl, "INTELXL %p admin event %#x "
"unrecognised opcode %#04x\n", intelxl,
admin->index, le16_to_cpu ( evt->opcode ) );
break;
}
/* Reset descriptor and refill queue */ /* Reset descriptor and refill queue */
intelxl_admin_event_init ( intelxl, admin->index ); intelxl_admin_event_init ( intelxl, admin->index );
@ -1645,6 +1641,7 @@ static int intelxl_probe ( struct pci_device *pci ) {
netdev->dev = &pci->dev; netdev->dev = &pci->dev;
memset ( intelxl, 0, sizeof ( *intelxl ) ); memset ( intelxl, 0, sizeof ( *intelxl ) );
intelxl->intr = INTELXL_PFINT_DYN_CTL0; intelxl->intr = INTELXL_PFINT_DYN_CTL0;
intelxl->handle = intelxl_admin_event;
intelxl_init_admin ( &intelxl->command, INTELXL_ADMIN_CMD, intelxl_init_admin ( &intelxl->command, INTELXL_ADMIN_CMD,
&intelxl_admin_offsets ); &intelxl_admin_offsets );
intelxl_init_admin ( &intelxl->event, INTELXL_ADMIN_EVT, intelxl_init_admin ( &intelxl->event, INTELXL_ADMIN_EVT,

View File

@ -1103,6 +1103,17 @@ struct intelxl_nic {
struct intelxl_ring rx; struct intelxl_ring rx;
/** Receive I/O buffers */ /** Receive I/O buffers */
struct io_buffer *rx_iobuf[INTELXL_RX_NUM_DESC]; struct io_buffer *rx_iobuf[INTELXL_RX_NUM_DESC];
/**
* Handle admin event
*
* @v netdev Network device
* @v evt Event descriptor
* @v buf Data buffer
*/
void ( * handle ) ( struct net_device *netdev,
struct intelxl_admin_descriptor *evt,
union intelxl_admin_buffer *buf );
}; };
extern int intelxl_msix_enable ( struct intelxl_nic *intelxl, extern int intelxl_msix_enable ( struct intelxl_nic *intelxl,
@ -1129,8 +1140,4 @@ extern int intelxl_transmit ( struct net_device *netdev,
struct io_buffer *iobuf ); struct io_buffer *iobuf );
extern void intelxl_poll ( struct net_device *netdev ); extern void intelxl_poll ( struct net_device *netdev );
extern void intelxlvf_admin_event ( struct net_device *netdev,
struct intelxl_admin_descriptor *evt,
union intelxl_admin_buffer *buf );
#endif /* _INTELXL_H */ #endif /* _INTELXL_H */

View File

@ -261,19 +261,27 @@ intelxlvf_admin_status ( struct net_device *netdev,
} }
/** /**
* Handle virtual function event * Handle admin event
* *
* @v netdev Network device * @v netdev Network device
* @v evt Admin queue event descriptor * @v evt Admin queue event descriptor
* @v buf Admin queue event data buffer * @v buf Admin queue event data buffer
*/ */
void intelxlvf_admin_event ( struct net_device *netdev, static void intelxlvf_admin_event ( struct net_device *netdev,
struct intelxl_admin_descriptor *evt, struct intelxl_admin_descriptor *evt,
union intelxl_admin_buffer *buf ) { union intelxl_admin_buffer *buf ) {
struct intelxl_nic *intelxl = netdev->priv; struct intelxl_nic *intelxl = netdev->priv;
unsigned int vopcode = le32_to_cpu ( evt->vopcode ); unsigned int vopcode;
/* Ignore unrecognised events */
if ( evt->opcode != cpu_to_le16 ( INTELXL_ADMIN_SEND_TO_VF ) ) {
DBGC ( intelxl, "INTELXL %p unrecognised event opcode "
"%#04x\n", intelxl, le16_to_cpu ( evt->opcode ) );
return;
}
/* Record command response if applicable */ /* Record command response if applicable */
vopcode = le32_to_cpu ( evt->vopcode );
if ( vopcode == intelxl->vopcode ) { if ( vopcode == intelxl->vopcode ) {
memcpy ( &intelxl->vbuf, buf, sizeof ( intelxl->vbuf ) ); memcpy ( &intelxl->vbuf, buf, sizeof ( intelxl->vbuf ) );
intelxl->vopcode = 0; intelxl->vopcode = 0;
@ -626,6 +634,7 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
netdev->dev = &pci->dev; netdev->dev = &pci->dev;
memset ( intelxl, 0, sizeof ( *intelxl ) ); memset ( intelxl, 0, sizeof ( *intelxl ) );
intelxl->intr = INTELXLVF_VFINT_DYN_CTLN ( INTELXLVF_MSIX_VECTOR ); intelxl->intr = INTELXLVF_VFINT_DYN_CTLN ( INTELXLVF_MSIX_VECTOR );
intelxl->handle = intelxlvf_admin_event;
intelxl_init_admin ( &intelxl->command, INTELXLVF_ADMIN, intelxl_init_admin ( &intelxl->command, INTELXLVF_ADMIN,
&intelxlvf_admin_command_offsets ); &intelxlvf_admin_command_offsets );
intelxl_init_admin ( &intelxl->event, INTELXLVF_ADMIN, intelxl_init_admin ( &intelxl->event, INTELXLVF_ADMIN,