+void
+i40e_notify_vf_link_status(struct rte_eth_dev *dev, struct i40e_pf_vf *vf)
+{
+ struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+ struct virtchnl_pf_event event;
+ uint16_t vf_id = vf->vf_idx;
+ uint32_t tval, rval;
+
+ event.event = VIRTCHNL_EVENT_LINK_CHANGE;
+ event.event_data.link_event.link_status =
+ dev->data->dev_link.link_status;
+
+ /* need to convert the ETH_SPEED_xxx into VIRTCHNL_LINK_SPEED_xxx */
+ switch (dev->data->dev_link.link_speed) {
+ case ETH_SPEED_NUM_100M:
+ event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_100MB;
+ break;
+ case ETH_SPEED_NUM_1G:
+ event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_1GB;
+ break;
+ case ETH_SPEED_NUM_10G:
+ event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_10GB;
+ break;
+ case ETH_SPEED_NUM_20G:
+ event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_20GB;
+ break;
+ case ETH_SPEED_NUM_25G:
+ event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_25GB;
+ break;
+ case ETH_SPEED_NUM_40G:
+ event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_40GB;
+ break;
+ default:
+ event.event_data.link_event.link_speed =
+ VIRTCHNL_LINK_SPEED_UNKNOWN;
+ break;
+ }
+
+ tval = I40E_READ_REG(hw, I40E_VF_ATQLEN(vf_id));
+ rval = I40E_READ_REG(hw, I40E_VF_ARQLEN(vf_id));
+
+ if (tval & I40E_VF_ATQLEN_ATQLEN_MASK ||
+ tval & I40E_VF_ATQLEN_ATQENABLE_MASK ||
+ rval & I40E_VF_ARQLEN_ARQLEN_MASK ||
+ rval & I40E_VF_ARQLEN_ARQENABLE_MASK)
+ i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_EVENT,
+ I40E_SUCCESS, (uint8_t *)&event, sizeof(event));
+}
+