+static int
+eth_igbvf_interrupt_get_status(struct rte_eth_dev *dev)
+{
+ uint32_t eicr;
+ struct e1000_hw *hw =
+ E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct e1000_interrupt *intr =
+ E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+
+ igbvf_intr_disable(hw);
+
+ /* read-on-clear nic registers here */
+ eicr = E1000_READ_REG(hw, E1000_EICR);
+ intr->flags = 0;
+
+ if (eicr == E1000_VTIVAR_MISC_MAILBOX)
+ intr->flags |= E1000_FLAG_MAILBOX;
+
+ return 0;
+}
+
+void igbvf_mbx_process(struct rte_eth_dev *dev)
+{
+ struct e1000_hw *hw =
+ E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ u32 in_msg = 0;
+
+ if (mbx->ops.read(hw, &in_msg, 1, 0))
+ return;
+
+ /* PF reset VF event */
+ if (in_msg == E1000_PF_CONTROL_MSG)
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+}
+
+static int
+eth_igbvf_interrupt_action(struct rte_eth_dev *dev)
+{
+ struct e1000_interrupt *intr =
+ E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+
+ if (intr->flags & E1000_FLAG_MAILBOX) {
+ igbvf_mbx_process(dev);
+ intr->flags &= ~E1000_FLAG_MAILBOX;
+ }
+
+ igbvf_intr_enable(dev);
+ rte_intr_enable(&dev->pci_dev->intr_handle);
+
+ return 0;
+}
+
+static void
+eth_igbvf_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
+ void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+
+ eth_igbvf_interrupt_get_status(dev);
+ eth_igbvf_interrupt_action(dev);
+}
+