net/i40e: support adding TM shaper profile
authorWenzhuo Lu <wenzhuo.lu@intel.com>
Thu, 29 Jun 2017 04:23:40 +0000 (12:23 +0800)
committerCristian Dumitrescu <cristian.dumitrescu@intel.com>
Tue, 11 Jul 2017 17:57:28 +0000 (19:57 +0200)
Add the support of the Traffic Management API,
rte_tm_shaper_profile_add.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
drivers/net/i40e/i40e_ethdev.c
drivers/net/i40e/i40e_ethdev.h
drivers/net/i40e/i40e_tm.c

index b50ab6a..b423f5d 100644 (file)
@@ -1296,6 +1296,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
        /* initialize mirror rule list */
        TAILQ_INIT(&pf->mirror_list);
 
+       /* initialize Traffic Manager configuration */
+       i40e_tm_conf_init(dev);
+
        ret = i40e_init_ethtype_filter_list(dev);
        if (ret < 0)
                goto err_init_ethtype_filter_list;
@@ -1458,6 +1461,9 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
                rte_free(p_flow);
        }
 
+       /* Remove all Traffic Manager configuration */
+       i40e_tm_conf_uninit(dev);
+
        return 0;
 }
 
index 2e900ff..af035cb 100644 (file)
@@ -652,6 +652,21 @@ struct rte_flow {
 
 TAILQ_HEAD(i40e_flow_list, rte_flow);
 
+/* Struct to store Traffic Manager shaper profile. */
+struct i40e_tm_shaper_profile {
+       TAILQ_ENTRY(i40e_tm_shaper_profile) node;
+       uint32_t shaper_profile_id;
+       uint32_t reference_count;
+       struct rte_tm_shaper_params profile;
+};
+
+TAILQ_HEAD(i40e_shaper_profile_list, i40e_tm_shaper_profile);
+
+/* Struct to store all the Traffic Manager configuration. */
+struct i40e_tm_conf {
+       struct i40e_shaper_profile_list shaper_profile_list;
+};
+
 /*
  * Structure to store private data specific for PF instance.
  */
@@ -715,6 +730,7 @@ struct i40e_pf {
        struct i40e_flow_list flow_list;
        bool mpls_replace_flag;  /* 1 - MPLS filter replace is done */
        bool qinq_replace_flag;  /* QINQ filter replace is done */
+       struct i40e_tm_conf tm_conf;
 };
 
 enum pending_msg {
@@ -930,6 +946,8 @@ uint64_t i40e_translate_input_set_reg(enum i40e_mac_type type, uint64_t input);
 void i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val);
 
 int i40e_tm_ops_get(struct rte_eth_dev *dev, void *ops);
+void i40e_tm_conf_init(struct rte_eth_dev *dev);
+void i40e_tm_conf_uninit(struct rte_eth_dev *dev);
 
 #define I40E_DEV_TO_PCI(eth_dev) \
        RTE_DEV_TO_PCI((eth_dev)->device)
index 9fc2f45..5780815 100644 (file)
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_malloc.h>
+
 #include "base/i40e_prototype.h"
 #include "i40e_ethdev.h"
 
 static int i40e_tm_capabilities_get(struct rte_eth_dev *dev,
                                    struct rte_tm_capabilities *cap,
                                    struct rte_tm_error *error);
+static int i40e_shaper_profile_add(struct rte_eth_dev *dev,
+                                  uint32_t shaper_profile_id,
+                                  struct rte_tm_shaper_params *profile,
+                                  struct rte_tm_error *error);
 
 const struct rte_tm_ops i40e_tm_ops = {
        .capabilities_get = i40e_tm_capabilities_get,
+       .shaper_profile_add = i40e_shaper_profile_add,
 };
 
 int
@@ -54,6 +61,30 @@ i40e_tm_ops_get(struct rte_eth_dev *dev __rte_unused,
        return 0;
 }
 
+void
+i40e_tm_conf_init(struct rte_eth_dev *dev)
+{
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+       /* initialize shaper profile list */
+       TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
+}
+
+void
+i40e_tm_conf_uninit(struct rte_eth_dev *dev)
+{
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct i40e_tm_shaper_profile *shaper_profile;
+
+       /* Remove all shaper profiles */
+       while ((shaper_profile =
+              TAILQ_FIRST(&pf->tm_conf.shaper_profile_list))) {
+               TAILQ_REMOVE(&pf->tm_conf.shaper_profile_list,
+                            shaper_profile, node);
+               rte_free(shaper_profile);
+       }
+}
+
 static inline uint16_t
 i40e_tc_nb_get(struct rte_eth_dev *dev)
 {
@@ -135,3 +166,91 @@ i40e_tm_capabilities_get(struct rte_eth_dev *dev,
 
        return 0;
 }
+
+static inline struct i40e_tm_shaper_profile *
+i40e_shaper_profile_search(struct rte_eth_dev *dev,
+                          uint32_t shaper_profile_id)
+{
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct i40e_shaper_profile_list *shaper_profile_list =
+               &pf->tm_conf.shaper_profile_list;
+       struct i40e_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
+i40e_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
+i40e_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 i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct i40e_tm_shaper_profile *shaper_profile;
+       int ret;
+
+       if (!profile || !error)
+               return -EINVAL;
+
+       ret = i40e_shaper_profile_param_check(profile, error);
+       if (ret)
+               return ret;
+
+       shaper_profile = i40e_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("i40e_tm_shaper_profile",
+                                    sizeof(struct i40e_tm_shaper_profile),
+                                    0);
+       if (!shaper_profile)
+               return -ENOMEM;
+       shaper_profile->shaper_profile_id = shaper_profile_id;
+       (void)rte_memcpy(&shaper_profile->profile, profile,
+                        sizeof(struct rte_tm_shaper_params));
+       TAILQ_INSERT_TAIL(&pf->tm_conf.shaper_profile_list,
+                         shaper_profile, node);
+
+       return 0;
+}