FreeBSD/sys/dev/ixgbe/if_ixv.c
/*********************************************************************
 *
 *  Setup MSIX Interrupt resources and handlers 
 *
 **********************************************************************/
Setup MSIX Interrupt resources and handlers
Setup MSIX Interrupt resources and handlers
static int
ixv_allocate_msix(struct adapter *adapter)
{
	device_t	dev = adapter->dev;
	struct 		ix_queue *que = adapter->queues;
	struct		tx_ring *txr = adapter->tx_rings;
	int 		error, rid, vector = 0;
	for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
		rid = vector + 1;
		que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
		    RF_SHAREABLE | RF_ACTIVE);
		if (que->res == NULL) {
			device_printf(dev,"Unable to allocate"
		    	    " bus resource: que interrupt [%d]\n", vector);
			return (ENXIO);
		}
		error = bus_setup_intr(dev, que->res,
		    INTR_TYPE_NET | INTR_MPSAFE, NULL,
		    ixv_msix_que, que, &que->tag);
		if (error) {
			que->res = NULL;
			device_printf(dev, "Failed to register QUE handler");
			return (error);
		}
#if __FreeBSD_version >= 800504
		bus_describe_intr(dev, que->res, que->tag, "que %d", i);
#endif
		que->msix = vector;
        	adapter->active_queues |= (u64)(1 << que->msix);
		if (adapter->num_queues > 1)
			bus_bind_intr(dev, que->res, i);
		TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr);
		TASK_INIT(&que->que_task, 0, ixv_handle_que, que);
		que->tq = taskqueue_create_fast("ixv_que", M_NOWAIT,
		    taskqueue_thread_enqueue, &que->tq);
		taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que",
		    device_get_nameunit(adapter->dev));
	}
	rid = vector + 1;
	adapter->res = bus_alloc_resource_any(dev,
    	    SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
	if (!adapter->res) {
		device_printf(dev,"Unable to allocate"
    	    " bus resource: MBX interrupt [%d]\n", rid);
		return (ENXIO);
	}
	error = bus_setup_intr(dev, adapter->res,
	    INTR_TYPE_NET | INTR_MPSAFE, NULL,
	    ixv_msix_mbx, adapter, &adapter->tag);
	if (error) {
		adapter->res = NULL;
		device_printf(dev, "Failed to register LINK handler");
		return (error);
	}
#if __FreeBSD_version >= 800504
	bus_describe_intr(dev, adapter->res, adapter->tag, "mbx");
#endif
	adapter->vector = vector;
	TASK_INIT(&adapter->link_task, 0, ixv_handle_mbx, adapter);
	adapter->tq = taskqueue_create_fast("ixv_mbx", M_NOWAIT,
	    taskqueue_thread_enqueue, &adapter->tq);
	taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s mbxq",
	    device_get_nameunit(adapter->dev));
	if (adapter->hw.mac.type == ixgbe_mac_82599_vf) {
		int msix_ctrl;
		pci_find_cap(dev, PCIY_MSIX, &rid);
		rid += PCIR_MSIX_CTRL;
		msix_ctrl = pci_read_config(dev, rid, 2);
		msix_ctrl |= PCIM_MSIXCTRL_MSIX_ENABLE;
		pci_write_config(dev, rid, msix_ctrl, 2);
	}
	return (0);
}
static int ixv_allocate_msix ( struct adapter * adapter ) { device_t dev = adapter -> dev ; struct ix_queue * que = adapter -> queues ; struct tx_ring * txr = adapter -> tx_rings ; int error , rid , vector = 0 ; for ( int i = 0 ; i < adapter -> num_queues ; i ++ , vector ++ , que ++ , txr ++ ) { rid = vector + 1 ; que -> res = bus_alloc_resource_any ( dev , SYS_RES_IRQ , & rid , RF_SHAREABLE | RF_ACTIVE ) ; if ( que -> res == NULL ) { device_printf ( dev , " " " \n " , vector ) ; return ( ENXIO ) ; } error = bus_setup_intr ( dev , que -> res , INTR_TYPE_NET | INTR_MPSAFE , NULL , ixv_msix_que , que , & que -> tag ) ; if ( error ) { que -> res = NULL ; device_printf ( dev , " " ) ; return ( error ) ; } #if __FreeBSD_version >= 800504 bus_describe_intr ( dev , que -> res , que -> tag , " " , i ) ; #endif que -> msix = vector ; adapter -> active_queues |= ( u64 ) ( 1 << que -> msix ) ; if ( adapter -> num_queues > 1 ) bus_bind_intr ( dev , que -> res , i ) ; TASK_INIT ( & txr -> txq_task , 0 , ixgbe_deferred_mq_start , txr ) ; TASK_INIT ( & que -> que_task , 0 , ixv_handle_que , que ) ; que -> tq = taskqueue_create_fast ( " " , M_NOWAIT , taskqueue_thread_enqueue , & que -> tq ) ; taskqueue_start_threads ( & que -> tq , 1 , PI_NET , " " , device_get_nameunit ( adapter -> dev ) ) ; } rid = vector + 1 ; adapter -> res = bus_alloc_resource_any ( dev , SYS_RES_IRQ , & rid , RF_SHAREABLE | RF_ACTIVE ) ; if ( ! adapter -> res ) { device_printf ( dev , " " " \n " , rid ) ; return ( ENXIO ) ; } error = bus_setup_intr ( dev , adapter -> res , INTR_TYPE_NET | INTR_MPSAFE , NULL , ixv_msix_mbx , adapter , & adapter -> tag ) ; if ( error ) { adapter -> res = NULL ; device_printf ( dev , " " ) ; return ( error ) ; } #if __FreeBSD_version >= 800504 bus_describe_intr ( dev , adapter -> res , adapter -> tag , " " ) ; #endif adapter -> vector = vector ; TASK_INIT ( & adapter -> link_task , 0 , ixv_handle_mbx , adapter ) ; adapter -> tq = taskqueue_create_fast ( " " , M_NOWAIT , taskqueue_thread_enqueue , & adapter -> tq ) ; taskqueue_start_threads ( & adapter -> tq , 1 , PI_NET , " " , device_get_nameunit ( adapter -> dev ) ) ; if ( adapter -> hw . mac . type == ixgbe_mac_82599_vf ) { int msix_ctrl ; pci_find_cap ( dev , PCIY_MSIX , & rid ) ; rid += PCIR_MSIX_CTRL ; msix_ctrl = pci_read_config ( dev , rid , 2 ) ; msix_ctrl |= PCIM_MSIXCTRL_MSIX_ENABLE ; pci_write_config ( dev , rid , msix_ctrl , 2 ) ; } return ( 0 ) ; }
Setup MSIX Interrupt resources and handlers
Setup MSIX Interrupt resources and handlers
/* Set the handler function */ /*
		** Bind the msix vector, and thus the
		** ring to the corresponding cpu.
		*/ /* and Mailbox */ /* Set the mbx handler function */ /* Tasklets for Mailbox */ /*
	** Due to a broken design QEMU will fail to properly
	** enable the guest for MSIX unless the vectors in
	** the table are all set up, so we must rewrite the
	** ENABLE in the MSIX control register again at this
	** point to cause it to successfully initialize us.
	*/