src/dpdk/drivers/net/e1000/igb_ethdev.c
static void
eth_igb_configure_msix_intr(struct rte_eth_dev *dev)
{
	int queue_id;
	uint32_t tmpval, regval, intr_mask;
	struct e1000_hw *hw =
		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
	uint32_t vec = E1000_MISC_VEC_ID;
	uint32_t base = E1000_MISC_VEC_ID;
	uint32_t misc_shift = 0;
	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;

	/* won't configure msix register if no mapping is done
	 * between intr vector and event fd
	 */
	if (!rte_intr_dp_is_en(intr_handle))
		return;

	if (rte_intr_allow_others(intr_handle)) {
		vec = base = E1000_RX_VEC_START;
		misc_shift = 1;
	}

	/* set interrupt vector for other causes */
	if (hw->mac.type == e1000_82575) {
		tmpval = E1000_READ_REG(hw, E1000_CTRL_EXT);
		/* enable MSI-X PBA support */
		tmpval |= E1000_CTRL_EXT_PBA_CLR;

		/* Auto-Mask interrupts upon ICR read */
		tmpval |= E1000_CTRL_EXT_EIAME;
		tmpval |= E1000_CTRL_EXT_IRCA;

		E1000_WRITE_REG(hw, E1000_CTRL_EXT, tmpval);

		/* enable msix_other interrupt */
		E1000_WRITE_REG_ARRAY(hw, E1000_MSIXBM(0), 0, E1000_EIMS_OTHER);
		regval = E1000_READ_REG(hw, E1000_EIAC);
		E1000_WRITE_REG(hw, E1000_EIAC, regval | E1000_EIMS_OTHER);
		regval = E1000_READ_REG(hw, E1000_EIAM);
		E1000_WRITE_REG(hw, E1000_EIMS, regval | E1000_EIMS_OTHER);
	} else if ((hw->mac.type == e1000_82576) ||
			(hw->mac.type == e1000_82580) ||
			(hw->mac.type == e1000_i350) ||
			(hw->mac.type == e1000_i354) ||
			(hw->mac.type == e1000_i210) ||
			(hw->mac.type == e1000_i211)) {
		/* turn on MSI-X capability first */
		E1000_WRITE_REG(hw, E1000_GPIE, E1000_GPIE_MSIX_MODE |
					E1000_GPIE_PBA | E1000_GPIE_EIAME |
					E1000_GPIE_NSICR);
		intr_mask = RTE_LEN2MASK(intr_handle->nb_efd, uint32_t) <<
			misc_shift;

		if (dev->data->dev_conf.intr_conf.lsc != 0)
			intr_mask |= (1 << IGB_MSIX_OTHER_INTR_VEC);

		regval = E1000_READ_REG(hw, E1000_EIAC);
		E1000_WRITE_REG(hw, E1000_EIAC, regval | intr_mask);

		/* enable msix_other interrupt */
		regval = E1000_READ_REG(hw, E1000_EIMS);
		E1000_WRITE_REG(hw, E1000_EIMS, regval | intr_mask);
		tmpval = (IGB_MSIX_OTHER_INTR_VEC | E1000_IVAR_VALID) << 8;
		E1000_WRITE_REG(hw, E1000_IVAR_MISC, tmpval);
	}

	/* use EIAM to auto-mask when MSI-X interrupt
	 * is asserted, this saves a register write for every interrupt
	 */
	intr_mask = RTE_LEN2MASK(intr_handle->nb_efd, uint32_t) <<
		misc_shift;

	if (dev->data->dev_conf.intr_conf.lsc != 0)
		intr_mask |= (1 << IGB_MSIX_OTHER_INTR_VEC);

	regval = E1000_READ_REG(hw, E1000_EIAM);
	E1000_WRITE_REG(hw, E1000_EIAM, regval | intr_mask);

	for (queue_id = 0; queue_id < dev->data->nb_rx_queues; queue_id++) {
		eth_igb_assign_msix_vector(hw, 0, queue_id, vec);
		intr_handle->intr_vec[queue_id] = vec;
		if (vec < base + intr_handle->nb_efd - 1)
			vec++;
	}

	E1000_WRITE_FLUSH(hw);
}
/* Sets up the hardware to generate MSI-X interrupts properly
 * @hw
 *  board private structure
 */
Sets up the hardware to generate MSI-X interrupts properly
@hw
board private structure
Sets up the hardware to generate MSI - X interrupts properly @hw board private structure
static void
eth_igb_configure_msix_intr(struct rte_eth_dev *dev)
{
	int queue_id;
	uint32_t tmpval, regval, intr_mask;
	struct e1000_hw *hw =
		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
	uint32_t vec = E1000_MISC_VEC_ID;
	uint32_t base = E1000_MISC_VEC_ID;
	uint32_t misc_shift = 0;
	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
	if (!rte_intr_dp_is_en(intr_handle))
		return;
	if (rte_intr_allow_others(intr_handle)) {
		vec = base = E1000_RX_VEC_START;
		misc_shift = 1;
	}
	if (hw->mac.type == e1000_82575) {
		tmpval = E1000_READ_REG(hw, E1000_CTRL_EXT);
		tmpval |= E1000_CTRL_EXT_PBA_CLR;
		tmpval |= E1000_CTRL_EXT_EIAME;
		tmpval |= E1000_CTRL_EXT_IRCA;
		E1000_WRITE_REG(hw, E1000_CTRL_EXT, tmpval);
		E1000_WRITE_REG_ARRAY(hw, E1000_MSIXBM(0), 0, E1000_EIMS_OTHER);
		regval = E1000_READ_REG(hw, E1000_EIAC);
		E1000_WRITE_REG(hw, E1000_EIAC, regval | E1000_EIMS_OTHER);
		regval = E1000_READ_REG(hw, E1000_EIAM);
		E1000_WRITE_REG(hw, E1000_EIMS, regval | E1000_EIMS_OTHER);
	} else if ((hw->mac.type == e1000_82576) ||
			(hw->mac.type == e1000_82580) ||
			(hw->mac.type == e1000_i350) ||
			(hw->mac.type == e1000_i354) ||
			(hw->mac.type == e1000_i210) ||
			(hw->mac.type == e1000_i211)) {
		E1000_WRITE_REG(hw, E1000_GPIE, E1000_GPIE_MSIX_MODE |
					E1000_GPIE_PBA | E1000_GPIE_EIAME |
					E1000_GPIE_NSICR);
		intr_mask = RTE_LEN2MASK(intr_handle->nb_efd, uint32_t) <<
			misc_shift;
		if (dev->data->dev_conf.intr_conf.lsc != 0)
			intr_mask |= (1 << IGB_MSIX_OTHER_INTR_VEC);
		regval = E1000_READ_REG(hw, E1000_EIAC);
		E1000_WRITE_REG(hw, E1000_EIAC, regval | intr_mask);
		regval = E1000_READ_REG(hw, E1000_EIMS);
		E1000_WRITE_REG(hw, E1000_EIMS, regval | intr_mask);
		tmpval = (IGB_MSIX_OTHER_INTR_VEC | E1000_IVAR_VALID) << 8;
		E1000_WRITE_REG(hw, E1000_IVAR_MISC, tmpval);
	}
	intr_mask = RTE_LEN2MASK(intr_handle->nb_efd, uint32_t) <<
		misc_shift;
	if (dev->data->dev_conf.intr_conf.lsc != 0)
		intr_mask |= (1 << IGB_MSIX_OTHER_INTR_VEC);
	regval = E1000_READ_REG(hw, E1000_EIAM);
	E1000_WRITE_REG(hw, E1000_EIAM, regval | intr_mask);
	for (queue_id = 0; queue_id < dev->data->nb_rx_queues; queue_id++) {
		eth_igb_assign_msix_vector(hw, 0, queue_id, vec);
		intr_handle->intr_vec[queue_id] = vec;
		if (vec < base + intr_handle->nb_efd - 1)
			vec++;
	}
	E1000_WRITE_FLUSH(hw);
}
static void eth_igb_configure_msix_intr ( struct rte_eth_dev * dev ) { int queue_id ; uint32_t tmpval , regval , intr_mask ; struct e1000_hw * hw = E1000_DEV_PRIVATE_TO_HW ( dev -> data -> dev_private ) ; uint32_t vec = E1000_MISC_VEC_ID ; uint32_t base = E1000_MISC_VEC_ID ; uint32_t misc_shift = 0 ; struct rte_pci_device * pci_dev = RTE_ETH_DEV_TO_PCI ( dev ) ; struct rte_intr_handle * intr_handle = & pci_dev -> intr_handle ; if ( ! rte_intr_dp_is_en ( intr_handle ) ) return ; if ( rte_intr_allow_others ( intr_handle ) ) { vec = base = E1000_RX_VEC_START ; misc_shift = 1 ; } if ( hw -> mac . type == e1000_82575 ) { tmpval = E1000_READ_REG ( hw , E1000_CTRL_EXT ) ; tmpval |= E1000_CTRL_EXT_PBA_CLR ; tmpval |= E1000_CTRL_EXT_EIAME ; tmpval |= E1000_CTRL_EXT_IRCA ; E1000_WRITE_REG ( hw , E1000_CTRL_EXT , tmpval ) ; E1000_WRITE_REG_ARRAY ( hw , E1000_MSIXBM ( 0 ) , 0 , E1000_EIMS_OTHER ) ; regval = E1000_READ_REG ( hw , E1000_EIAC ) ; E1000_WRITE_REG ( hw , E1000_EIAC , regval | E1000_EIMS_OTHER ) ; regval = E1000_READ_REG ( hw , E1000_EIAM ) ; E1000_WRITE_REG ( hw , E1000_EIMS , regval | E1000_EIMS_OTHER ) ; } else if ( ( hw -> mac . type == e1000_82576 ) || ( hw -> mac . type == e1000_82580 ) || ( hw -> mac . type == e1000_i350 ) || ( hw -> mac . type == e1000_i354 ) || ( hw -> mac . type == e1000_i210 ) || ( hw -> mac . type == e1000_i211 ) ) { E1000_WRITE_REG ( hw , E1000_GPIE , E1000_GPIE_MSIX_MODE | E1000_GPIE_PBA | E1000_GPIE_EIAME | E1000_GPIE_NSICR ) ; intr_mask = RTE_LEN2MASK ( intr_handle -> nb_efd , uint32_t ) << misc_shift ; if ( dev -> data -> dev_conf . intr_conf . lsc != 0 ) intr_mask |= ( 1 << IGB_MSIX_OTHER_INTR_VEC ) ; regval = E1000_READ_REG ( hw , E1000_EIAC ) ; E1000_WRITE_REG ( hw , E1000_EIAC , regval | intr_mask ) ; regval = E1000_READ_REG ( hw , E1000_EIMS ) ; E1000_WRITE_REG ( hw , E1000_EIMS , regval | intr_mask ) ; tmpval = ( IGB_MSIX_OTHER_INTR_VEC | E1000_IVAR_VALID ) << 8 ; E1000_WRITE_REG ( hw , E1000_IVAR_MISC , tmpval ) ; } intr_mask = RTE_LEN2MASK ( intr_handle -> nb_efd , uint32_t ) << misc_shift ; if ( dev -> data -> dev_conf . intr_conf . lsc != 0 ) intr_mask |= ( 1 << IGB_MSIX_OTHER_INTR_VEC ) ; regval = E1000_READ_REG ( hw , E1000_EIAM ) ; E1000_WRITE_REG ( hw , E1000_EIAM , regval | intr_mask ) ; for ( queue_id = 0 ; queue_id < dev -> data -> nb_rx_queues ; queue_id ++ ) { eth_igb_assign_msix_vector ( hw , 0 , queue_id , vec ) ; intr_handle -> intr_vec [ queue_id ] = vec ; if ( vec < base + intr_handle -> nb_efd - 1 ) vec ++ ; } E1000_WRITE_FLUSH ( hw ) ; }
Sets up the hardware to generate MSI-X interrupts properly
 @hw
  board private structure
Sets up the hardware to generate MSI - X interrupts properly @hw board private structure
/* won't configure msix register if no mapping is done
	 * between intr vector and event fd
	 */ /* set interrupt vector for other causes */ /* enable MSI-X PBA support */ /* Auto-Mask interrupts upon ICR read */ /* enable msix_other interrupt */ /* turn on MSI-X capability first */ /* enable msix_other interrupt */ /* use EIAM to auto-mask when MSI-X interrupt
	 * is asserted, this saves a register write for every interrupt
	 */