net/ice: support QoS config VF bandwidth in DCF
[dpdk.git] / drivers / net / ice / ice_dcf_parent.c
index c8e4332..c59cd0b 100644 (file)
@@ -121,6 +121,8 @@ ice_dcf_vsi_update_service_handler(void *param)
        struct ice_dcf_hw *hw = reset_param->dcf_hw;
        struct ice_dcf_adapter *adapter;
 
+       pthread_detach(pthread_self());
+
        rte_delay_us(ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL);
 
        rte_spinlock_lock(&vsi_update_lock);
@@ -176,6 +178,44 @@ start_vsi_reset_thread(struct ice_dcf_hw *dcf_hw, bool vfr, uint16_t vf_id)
        }
 }
 
+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)
@@ -194,6 +234,19 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
                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");
@@ -211,6 +264,29 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
        }
 }
 
+static int
+ice_dcf_query_port_ets(struct ice_hw *parent_hw, struct ice_dcf_hw *real_hw)
+{
+       int ret;
+
+       real_hw->ets_config = (struct ice_aqc_port_ets_elem *)
+                       ice_malloc(real_hw, sizeof(*real_hw->ets_config));
+       if (!real_hw->ets_config)
+               return ICE_ERR_NO_MEMORY;
+
+       ret = ice_aq_query_port_ets(parent_hw->port_info,
+                       real_hw->ets_config, sizeof(*real_hw->ets_config),
+                       NULL);
+       if (ret) {
+               PMD_DRV_LOG(ERR, "DCF Query Port ETS failed");
+               rte_free(real_hw->ets_config);
+               real_hw->ets_config = NULL;
+               return ret;
+       }
+
+       return ICE_SUCCESS;
+}
+
 static int
 ice_dcf_init_parent_hw(struct ice_hw *hw)
 {
@@ -406,7 +482,6 @@ ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev)
        const struct rte_ether_addr *mac;
        int err;
 
-       parent_adapter->eth_dev = eth_dev;
        parent_adapter->pf.adapter = parent_adapter;
        parent_adapter->pf.dev_data = eth_dev->data;
        /* create a dummy main_vsi */
@@ -434,6 +509,15 @@ ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev)
                return err;
        }
 
+       if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS) {
+               err = ice_dcf_query_port_ets(parent_hw, hw);
+               if (err) {
+                       PMD_INIT_LOG(ERR, "failed to query port ets with error %d",
+                                    err);
+                       goto uninit_hw;
+               }
+       }
+
        err = ice_dcf_load_pkg(parent_hw);
        if (err) {
                PMD_INIT_LOG(ERR, "failed to load package with error %d",