vf通过msi向pf发送中断

vf通过msi向pf发送中断_第1张图片

在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

vf通过msi向pf发送中断_第2张图片

最终调用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;
}




你可能感兴趣的:(Linux,源码分析)