+void
+hns3vf_update_push_lsc_cap(struct hns3_hw *hw, bool supported)
+{
+ uint16_t val = supported ? HNS3_PF_PUSH_LSC_CAP_SUPPORTED :
+ HNS3_PF_PUSH_LSC_CAP_NOT_SUPPORTED;
+ uint16_t exp = HNS3_PF_PUSH_LSC_CAP_UNKNOWN;
+ struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw);
+
+ if (vf->pf_push_lsc_cap == HNS3_PF_PUSH_LSC_CAP_UNKNOWN)
+ __atomic_compare_exchange(&vf->pf_push_lsc_cap, &exp, &val, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+static void
+hns3vf_get_push_lsc_cap(struct hns3_hw *hw)
+{
+#define HNS3_CHECK_PUSH_LSC_CAP_TIMEOUT_MS 500
+
+ struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
+ int32_t remain_ms = HNS3_CHECK_PUSH_LSC_CAP_TIMEOUT_MS;
+ uint16_t val = HNS3_PF_PUSH_LSC_CAP_NOT_SUPPORTED;
+ uint16_t exp = HNS3_PF_PUSH_LSC_CAP_UNKNOWN;
+ struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw);
+
+ __atomic_store_n(&vf->pf_push_lsc_cap, HNS3_PF_PUSH_LSC_CAP_UNKNOWN,
+ __ATOMIC_RELEASE);
+
+ (void)hns3_send_mbx_msg(hw, HNS3_MBX_GET_LINK_STATUS, 0, NULL, 0, false,
+ NULL, 0);
+
+ while (remain_ms > 0) {
+ rte_delay_ms(HNS3_POLL_RESPONE_MS);
+ if (__atomic_load_n(&vf->pf_push_lsc_cap, __ATOMIC_ACQUIRE) !=
+ HNS3_PF_PUSH_LSC_CAP_UNKNOWN)
+ break;
+ remain_ms--;
+ }
+
+ /*
+ * When exit above loop, the pf_push_lsc_cap could be one of the three
+ * state: unknown (means pf not ack), not_supported, supported.
+ * Here config it as 'not_supported' when it's 'unknown' state.
+ */
+ __atomic_compare_exchange(&vf->pf_push_lsc_cap, &exp, &val, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+
+ if (__atomic_load_n(&vf->pf_push_lsc_cap, __ATOMIC_ACQUIRE) ==
+ HNS3_PF_PUSH_LSC_CAP_SUPPORTED) {
+ hns3_info(hw, "detect PF support push link status change!");
+ } else {
+ /*
+ * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver
+ * declared RTE_PCI_DRV_INTR_LSC in drv_flags. So here cleared
+ * the RTE_ETH_DEV_INTR_LSC capability.
+ */
+ dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
+ }
+}
+