在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);
}
而这里的write_posted的赋值是在Mbx.c (drivers\net\ethernet\intel\ixgbevf)
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, };
所以这里直接看write_posted
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; }
这里又调用mbx->ops->write,其同样是在ixgbevf_mbx_ops 中定义的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; }