When link status changes, DCF will receive virtchnl PF event message.
Add support to handle this event, change link status and update link
info.
Signed-off-by: Ting Xu <ting.xu@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
uint16_t nb_msix;
uint16_t rxq_map[16];
struct virtchnl_eth_stats eth_stats_offset;
+
+ /* Link status */
+ bool link_up;
+ uint32_t link_speed;
};
int ice_dcf_execute_virtchnl_cmd(struct ice_dcf_hw *hw,
int ice_dcf_query_stats(struct ice_dcf_hw *hw,
struct virtchnl_eth_stats *pstats);
int ice_dcf_add_del_all_mac_addr(struct ice_dcf_hw *hw, bool add);
+int ice_dcf_link_update(struct rte_eth_dev *dev,
+ __rte_unused int wait_to_complete);
#endif /* _ICE_DCF_H_ */
return 0;
}
-static int
-ice_dcf_link_update(__rte_unused struct rte_eth_dev *dev,
+int
+ice_dcf_link_update(struct rte_eth_dev *dev,
__rte_unused int wait_to_complete)
{
- return 0;
+ struct ice_dcf_adapter *ad = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &ad->real_hw;
+ struct rte_eth_link new_link;
+
+ memset(&new_link, 0, sizeof(new_link));
+
+ /* Only read status info stored in VF, and the info is updated
+ * when receive LINK_CHANGE event from PF by virtchnl.
+ */
+ switch (hw->link_speed) {
+ case 10:
+ new_link.link_speed = ETH_SPEED_NUM_10M;
+ break;
+ case 100:
+ new_link.link_speed = ETH_SPEED_NUM_100M;
+ break;
+ case 1000:
+ new_link.link_speed = ETH_SPEED_NUM_1G;
+ break;
+ case 10000:
+ new_link.link_speed = ETH_SPEED_NUM_10G;
+ break;
+ case 20000:
+ new_link.link_speed = ETH_SPEED_NUM_20G;
+ break;
+ case 25000:
+ new_link.link_speed = ETH_SPEED_NUM_25G;
+ break;
+ case 40000:
+ new_link.link_speed = ETH_SPEED_NUM_40G;
+ break;
+ case 50000:
+ new_link.link_speed = ETH_SPEED_NUM_50G;
+ break;
+ case 100000:
+ new_link.link_speed = ETH_SPEED_NUM_100G;
+ break;
+ default:
+ new_link.link_speed = ETH_SPEED_NUM_NONE;
+ break;
+ }
+
+ new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+ new_link.link_status = hw->link_up ? ETH_LINK_UP :
+ ETH_LINK_DOWN;
+ new_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
+
+ return rte_eth_linkstatus_set(dev, &new_link);
}
/* Add UDP tunneling port */
}
}
+static uint32_t
+ice_dcf_convert_link_speed(enum virtchnl_link_speed virt_link_speed)
+{
+ uint32_t speed;
+
+ switch (virt_link_speed) {
+ case VIRTCHNL_LINK_SPEED_100MB:
+ speed = 100;
+ break;
+ case VIRTCHNL_LINK_SPEED_1GB:
+ speed = 1000;
+ break;
+ case VIRTCHNL_LINK_SPEED_10GB:
+ speed = 10000;
+ break;
+ case VIRTCHNL_LINK_SPEED_40GB:
+ speed = 40000;
+ break;
+ case VIRTCHNL_LINK_SPEED_20GB:
+ speed = 20000;
+ break;
+ case VIRTCHNL_LINK_SPEED_25GB:
+ speed = 25000;
+ break;
+ case VIRTCHNL_LINK_SPEED_2_5GB:
+ speed = 2500;
+ break;
+ case VIRTCHNL_LINK_SPEED_5GB:
+ speed = 5000;
+ break;
+ default:
+ speed = 0;
+ break;
+ }
+
+ return speed;
+}
+
void
ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
uint8_t *msg, uint16_t msglen)
break;
case VIRTCHNL_EVENT_LINK_CHANGE:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
+ dcf_hw->link_up = pf_msg->event_data.link_event.link_status;
+ if (dcf_hw->vf_res->vf_cap_flags &
+ VIRTCHNL_VF_CAP_ADV_LINK_SPEED) {
+ dcf_hw->link_speed =
+ pf_msg->event_data.link_event_adv.link_speed;
+ } else {
+ enum virtchnl_link_speed speed;
+ speed = pf_msg->event_data.link_event.link_speed;
+ dcf_hw->link_speed = ice_dcf_convert_link_speed(speed);
+ }
+ ice_dcf_link_update(dcf_hw->eth_dev, 0);
+ rte_eth_dev_callback_process(dcf_hw->eth_dev,
+ RTE_ETH_EVENT_INTR_LSC, NULL);
break;
case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event");