在ixgbe_request_msix_irqs 中最后通过
err = request_irq(adapter->msix_entries[vector].vector,
ixgbe_msix_other, 0, netdev->name, adapter);
来注册一个中断。
当vf向pf通信的时候会调用ixgbevf_set_uc_addr_vf
最终调用ixgbevf_write_msg_read_ack
static inline s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg,
u32 *retmsg, u16 size)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
s32 retval = mbx->ops.write_posted(hw, msg, size);
if (retval)
return retval;
return mbx->ops.read_posted(hw, retmsg, size);
}
const struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
.init_params = ixgbevf_init_mbx_params_vf,
.read = ixgbevf_read_mbx_vf,
.write = ixgbevf_write_mbx_vf,
.read_posted = ixgbevf_read_posted_mbx,
.write_posted = ixgbevf_write_posted_mbx,
.check_for_msg = ixgbevf_check_for_msg_vf,
.check_for_ack = ixgbevf_check_for_ack_vf,
.check_for_rst = ixgbevf_check_for_rst_vf,
};
static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
s32 ret_val = IXGBE_ERR_MBX;
/* exit if either we can't write or there isn't a defined timeout */
if (!mbx->ops.write || !mbx->timeout)
goto out;
/* send msg */
ret_val = mbx->ops.write(hw, msg, size);
/* if msg sent wait until we receive an ack */
if (!ret_val)
ret_val = ixgbevf_poll_for_ack(hw);
out:
return ret_val;
}
static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
{
s32 ret_val;
u16 i;
/* lock the mailbox to prevent PF/VF race condition */
ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
if (ret_val)
goto out_no_write;
/* flush msg and acks as we are overwriting the message buffer */
ixgbevf_check_for_msg_vf(hw);
ixgbevf_check_for_ack_vf(hw);
/* copy the caller specified message to the mailbox memory buffer */
for (i = 0; i < size; i++)
IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
/* update stats */
hw->mbx.stats.msgs_tx++;
//最终通过写寄存器出发中断,这就是vf通过msi向pf发送中断的过程
/* Drop VFU and interrupt the PF to tell it a message has been sent */
IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
out_no_write:
return ret_val;
}