net/ixgbe: support adding TM shaper profile
authorWenzhuo Lu <wenzhuo.lu@intel.com>
Thu, 29 Jun 2017 04:23:50 +0000 (12:23 +0800)
committerCristian Dumitrescu <cristian.dumitrescu@intel.com>
Tue, 11 Jul 2017 18:07:12 +0000 (20:07 +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/ixgbe/ixgbe_ethdev.c
drivers/net/ixgbe/ixgbe_ethdev.h
drivers/net/ixgbe/ixgbe_tm.c

index dbcb20e..bf74c64 100644 (file)
@@ -1351,6 +1351,9 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
        /* initialize bandwidth configuration info */
        memset(bw_conf, 0, sizeof(struct ixgbe_bw_conf));
 
+       /* initialize Traffic Manager configuration */
+       ixgbe_tm_conf_init(eth_dev);
+
        return 0;
 }
 
@@ -1404,6 +1407,9 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
        /* clear all the filters list */
        ixgbe_filterlist_flush();
 
+       /* Remove all Traffic Manager configuration */
+       ixgbe_tm_conf_uninit(eth_dev);
+
        return 0;
 }
 
index 762d04d..064d427 100644 (file)
@@ -437,6 +437,21 @@ struct ixgbe_bw_conf {
        uint8_t tc_num; /* Number of TCs. */
 };
 
+/* Struct to store Traffic Manager shaper profile. */
+struct ixgbe_tm_shaper_profile {
+       TAILQ_ENTRY(ixgbe_tm_shaper_profile) node;
+       uint32_t shaper_profile_id;
+       uint32_t reference_count;
+       struct rte_tm_shaper_params profile;
+};
+
+TAILQ_HEAD(ixgbe_shaper_profile_list, ixgbe_tm_shaper_profile);
+
+/* The configuration of Traffic Manager */
+struct ixgbe_tm_conf {
+       struct ixgbe_shaper_profile_list shaper_profile_list;
+};
+
 /*
  * Structure to store private data for each driver instance (for each port).
  */
@@ -465,6 +480,7 @@ struct ixgbe_adapter {
        struct rte_timecounter      systime_tc;
        struct rte_timecounter      rx_tstamp_tc;
        struct rte_timecounter      tx_tstamp_tc;
+       struct ixgbe_tm_conf        tm_conf;
 };
 
 #define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
@@ -512,6 +528,9 @@ struct ixgbe_adapter {
 #define IXGBE_DEV_PRIVATE_TO_BW_CONF(adapter) \
        (&((struct ixgbe_adapter *)adapter)->bw_conf)
 
+#define IXGBE_DEV_PRIVATE_TO_TM_CONF(adapter) \
+       (&((struct ixgbe_adapter *)adapter)->tm_conf)
+
 /*
  * RX/TX function prototypes
  */
@@ -674,6 +693,8 @@ int ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf,
                            uint16_t tx_rate, uint64_t q_msk);
 bool is_ixgbe_supported(struct rte_eth_dev *dev);
 int ixgbe_tm_ops_get(struct rte_eth_dev *dev, void *ops);
+void ixgbe_tm_conf_init(struct rte_eth_dev *dev);
+void ixgbe_tm_conf_uninit(struct rte_eth_dev *dev);
 
 static inline int
 ixgbe_ethertype_filter_lookup(struct ixgbe_filter_info *filter_info,
index f47a60d..9c355b4 100644 (file)
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_malloc.h>
+
 #include "ixgbe_ethdev.h"
 
 static int ixgbe_tm_capabilities_get(struct rte_eth_dev *dev,
                                     struct rte_tm_capabilities *cap,
                                     struct rte_tm_error *error);
+static int ixgbe_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 ixgbe_tm_ops = {
        .capabilities_get = ixgbe_tm_capabilities_get,
+       .shaper_profile_add = ixgbe_shaper_profile_add,
 };
 
 int
@@ -53,6 +60,32 @@ ixgbe_tm_ops_get(struct rte_eth_dev *dev __rte_unused,
        return 0;
 }
 
+void
+ixgbe_tm_conf_init(struct rte_eth_dev *dev)
+{
+       struct ixgbe_tm_conf *tm_conf =
+               IXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private);
+
+       /* initialize shaper profile list */
+       TAILQ_INIT(&tm_conf->shaper_profile_list);
+}
+
+void
+ixgbe_tm_conf_uninit(struct rte_eth_dev *dev)
+{
+       struct ixgbe_tm_conf *tm_conf =
+               IXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private);
+       struct ixgbe_tm_shaper_profile *shaper_profile;
+
+       /* Remove all shaper profiles */
+       while ((shaper_profile =
+              TAILQ_FIRST(&tm_conf->shaper_profile_list))) {
+               TAILQ_REMOVE(&tm_conf->shaper_profile_list,
+                            shaper_profile, node);
+               rte_free(shaper_profile);
+       }
+}
+
 static inline uint8_t
 ixgbe_tc_nb_get(struct rte_eth_dev *dev)
 {
@@ -141,3 +174,93 @@ ixgbe_tm_capabilities_get(struct rte_eth_dev *dev,
 
        return 0;
 }
+
+static inline struct ixgbe_tm_shaper_profile *
+ixgbe_shaper_profile_search(struct rte_eth_dev *dev,
+                           uint32_t shaper_profile_id)
+{
+       struct ixgbe_tm_conf *tm_conf =
+               IXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private);
+       struct ixgbe_shaper_profile_list *shaper_profile_list =
+               &tm_conf->shaper_profile_list;
+       struct ixgbe_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
+ixgbe_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
+ixgbe_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 ixgbe_tm_conf *tm_conf =
+               IXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private);
+       struct ixgbe_tm_shaper_profile *shaper_profile;
+       int ret;
+
+       if (!profile || !error)
+               return -EINVAL;
+
+       ret = ixgbe_shaper_profile_param_check(profile, error);
+       if (ret)
+               return ret;
+
+       shaper_profile = ixgbe_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("ixgbe_tm_shaper_profile",
+                                    sizeof(struct ixgbe_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(&tm_conf->shaper_profile_list,
+                         shaper_profile, node);
+
+       return 0;
+}