net/txgbe: support TM shaper profile add and delete
authorJiawen Wu <jiawenwu@trustnetic.com>
Fri, 18 Dec 2020 09:36:54 +0000 (17:36 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 13 Jan 2021 17:51:58 +0000 (18:51 +0100)
Support traffic manager profile add and delete operations.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
drivers/net/txgbe/txgbe_tm.c

index 545590b..8adb038 100644 (file)
@@ -9,6 +9,13 @@
 static int txgbe_tm_capabilities_get(struct rte_eth_dev *dev,
                                     struct rte_tm_capabilities *cap,
                                     struct rte_tm_error *error);
+static int txgbe_shaper_profile_add(struct rte_eth_dev *dev,
+                                   uint32_t shaper_profile_id,
+                                   struct rte_tm_shaper_params *profile,
+                                   struct rte_tm_error *error);
+static int txgbe_shaper_profile_del(struct rte_eth_dev *dev,
+                                   uint32_t shaper_profile_id,
+                                   struct rte_tm_error *error);
 static int txgbe_level_capabilities_get(struct rte_eth_dev *dev,
                                        uint32_t level_id,
                                        struct rte_tm_level_capabilities *cap,
@@ -20,6 +27,8 @@ static int txgbe_node_capabilities_get(struct rte_eth_dev *dev,
 
 const struct rte_tm_ops txgbe_tm_ops = {
        .capabilities_get = txgbe_tm_capabilities_get,
+       .shaper_profile_add = txgbe_shaper_profile_add,
+       .shaper_profile_delete = txgbe_shaper_profile_del,
        .level_capabilities_get = txgbe_level_capabilities_get,
        .node_capabilities_get = txgbe_node_capabilities_get,
 };
@@ -174,6 +183,126 @@ txgbe_tm_capabilities_get(struct rte_eth_dev *dev,
        return 0;
 }
 
+static inline struct txgbe_tm_shaper_profile *
+txgbe_shaper_profile_search(struct rte_eth_dev *dev,
+                           uint32_t shaper_profile_id)
+{
+       struct txgbe_tm_conf *tm_conf = TXGBE_DEV_TM_CONF(dev);
+       struct txgbe_shaper_profile_list *shaper_profile_list =
+               &tm_conf->shaper_profile_list;
+       struct txgbe_tm_shaper_profile *shaper_profile;
+
+       TAILQ_FOREACH(shaper_profile, shaper_profile_list, node) {
+               if (shaper_profile_id == shaper_profile->shaper_profile_id)
+                       return shaper_profile;
+       }
+
+       return NULL;
+}
+
+static int
+txgbe_shaper_profile_param_check(struct rte_tm_shaper_params *profile,
+                                struct rte_tm_error *error)
+{
+       /* min rate not supported */
+       if (profile->committed.rate) {
+               error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_RATE;
+               error->message = "committed rate not supported";
+               return -EINVAL;
+       }
+       /* min bucket size not supported */
+       if (profile->committed.size) {
+               error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_SIZE;
+               error->message = "committed bucket size not supported";
+               return -EINVAL;
+       }
+       /* max bucket size not supported */
+       if (profile->peak.size) {
+               error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE;
+               error->message = "peak bucket size not supported";
+               return -EINVAL;
+       }
+       /* length adjustment not supported */
+       if (profile->pkt_length_adjust) {
+               error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PKT_ADJUST_LEN;
+               error->message = "packet length adjustment not supported";
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int
+txgbe_shaper_profile_add(struct rte_eth_dev *dev,
+                        uint32_t shaper_profile_id,
+                        struct rte_tm_shaper_params *profile,
+                        struct rte_tm_error *error)
+{
+       struct txgbe_tm_conf *tm_conf = TXGBE_DEV_TM_CONF(dev);
+       struct txgbe_tm_shaper_profile *shaper_profile;
+       int ret;
+
+       if (!profile || !error)
+               return -EINVAL;
+
+       ret = txgbe_shaper_profile_param_check(profile, error);
+       if (ret)
+               return ret;
+
+       shaper_profile = txgbe_shaper_profile_search(dev, shaper_profile_id);
+
+       if (shaper_profile) {
+               error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID;
+               error->message = "profile ID exist";
+               return -EINVAL;
+       }
+
+       shaper_profile = rte_zmalloc("txgbe_tm_shaper_profile",
+                                    sizeof(struct txgbe_tm_shaper_profile),
+                                    0);
+       if (!shaper_profile)
+               return -ENOMEM;
+       shaper_profile->shaper_profile_id = shaper_profile_id;
+       rte_memcpy(&shaper_profile->profile, profile,
+                        sizeof(struct rte_tm_shaper_params));
+       TAILQ_INSERT_TAIL(&tm_conf->shaper_profile_list,
+                         shaper_profile, node);
+
+       return 0;
+}
+
+static int
+txgbe_shaper_profile_del(struct rte_eth_dev *dev,
+                        uint32_t shaper_profile_id,
+                        struct rte_tm_error *error)
+{
+       struct txgbe_tm_conf *tm_conf = TXGBE_DEV_TM_CONF(dev);
+       struct txgbe_tm_shaper_profile *shaper_profile;
+
+       if (!error)
+               return -EINVAL;
+
+       shaper_profile = txgbe_shaper_profile_search(dev, shaper_profile_id);
+
+       if (!shaper_profile) {
+               error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID;
+               error->message = "profile ID not exist";
+               return -EINVAL;
+       }
+
+       /* don't delete a profile if it's used by one or several nodes */
+       if (shaper_profile->reference_count) {
+               error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE;
+               error->message = "profile in use";
+               return -EINVAL;
+       }
+
+       TAILQ_REMOVE(&tm_conf->shaper_profile_list, shaper_profile, node);
+       rte_free(shaper_profile);
+
+       return 0;
+}
+
 static inline struct txgbe_tm_node *
 txgbe_tm_node_search(struct rte_eth_dev *dev, uint32_t node_id,
                     enum txgbe_tm_node_type *node_type)