net/mlx5e: Add channel events counter
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / rl.c
index d3c33e9eea7292412974802c4c38ded8898ed55c..bc86dffdc43c524574412b53345ea948acc2e446 100644 (file)
@@ -107,16 +107,16 @@ int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
  * If the table is full, return NULL
  */
 static struct mlx5_rl_entry *find_rl_entry(struct mlx5_rl_table *table,
-                                          u32 rate)
+                                          struct mlx5_rate_limit *rl)
 {
        struct mlx5_rl_entry *ret_entry = NULL;
        bool empty_found = false;
        int i;
 
        for (i = 0; i < table->max_size; i++) {
-               if (table->rl_entry[i].rate == rate)
+               if (mlx5_rl_are_equal(&table->rl_entry[i].rl, rl))
                        return &table->rl_entry[i];
-               if (!empty_found && !table->rl_entry[i].rate) {
+               if (!empty_found && !table->rl_entry[i].rl.rate) {
                        empty_found = true;
                        ret_entry = &table->rl_entry[i];
                }
@@ -126,7 +126,8 @@ static struct mlx5_rl_entry *find_rl_entry(struct mlx5_rl_table *table,
 }
 
 static int mlx5_set_pp_rate_limit_cmd(struct mlx5_core_dev *dev,
-                                  u32 rate, u16 index)
+                                     u16 index,
+                                     struct mlx5_rate_limit *rl)
 {
        u32 in[MLX5_ST_SZ_DW(set_pp_rate_limit_in)]   = {0};
        u32 out[MLX5_ST_SZ_DW(set_pp_rate_limit_out)] = {0};
@@ -134,7 +135,9 @@ static int mlx5_set_pp_rate_limit_cmd(struct mlx5_core_dev *dev,
        MLX5_SET(set_pp_rate_limit_in, in, opcode,
                 MLX5_CMD_OP_SET_PP_RATE_LIMIT);
        MLX5_SET(set_pp_rate_limit_in, in, rate_limit_index, index);
-       MLX5_SET(set_pp_rate_limit_in, in, rate_limit, rate);
+       MLX5_SET(set_pp_rate_limit_in, in, rate_limit, rl->rate);
+       MLX5_SET(set_pp_rate_limit_in, in, burst_upper_bound, rl->max_burst_sz);
+       MLX5_SET(set_pp_rate_limit_in, in, typical_packet_size, rl->typical_pkt_sz);
        return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
@@ -146,7 +149,17 @@ bool mlx5_rl_is_in_range(struct mlx5_core_dev *dev, u32 rate)
 }
 EXPORT_SYMBOL(mlx5_rl_is_in_range);
 
-int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u32 rate, u16 *index)
+bool mlx5_rl_are_equal(struct mlx5_rate_limit *rl_0,
+                      struct mlx5_rate_limit *rl_1)
+{
+       return ((rl_0->rate == rl_1->rate) &&
+               (rl_0->max_burst_sz == rl_1->max_burst_sz) &&
+               (rl_0->typical_pkt_sz == rl_1->typical_pkt_sz));
+}
+EXPORT_SYMBOL(mlx5_rl_are_equal);
+
+int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u16 *index,
+                    struct mlx5_rate_limit *rl)
 {
        struct mlx5_rl_table *table = &dev->priv.rl_table;
        struct mlx5_rl_entry *entry;
@@ -154,14 +167,14 @@ int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u32 rate, u16 *index)
 
        mutex_lock(&table->rl_lock);
 
-       if (!rate || !mlx5_rl_is_in_range(dev, rate)) {
+       if (!rl->rate || !mlx5_rl_is_in_range(dev, rl->rate)) {
                mlx5_core_err(dev, "Invalid rate: %u, should be %u to %u\n",
-                             rate, table->min_rate, table->max_rate);
+                             rl->rate, table->min_rate, table->max_rate);
                err = -EINVAL;
                goto out;
        }
 
-       entry = find_rl_entry(table, rate);
+       entry = find_rl_entry(table, rl);
        if (!entry) {
                mlx5_core_err(dev, "Max number of %u rates reached\n",
                              table->max_size);
@@ -173,13 +186,15 @@ int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u32 rate, u16 *index)
                entry->refcount++;
        } else {
                /* new rate limit */
-               err = mlx5_set_pp_rate_limit_cmd(dev, rate, entry->index);
+               err = mlx5_set_pp_rate_limit_cmd(dev, entry->index, rl);
                if (err) {
-                       mlx5_core_err(dev, "Failed configuring rate: %u (%d)\n",
-                                     rate, err);
+                       mlx5_core_err(dev, "Failed configuring rate limit(err %d): \
+                                     rate %u, max_burst_sz %u, typical_pkt_sz %u\n",
+                                     err, rl->rate, rl->max_burst_sz,
+                                     rl->typical_pkt_sz);
                        goto out;
                }
-               entry->rate = rate;
+               entry->rl = *rl;
                entry->refcount = 1;
        }
        *index = entry->index;
@@ -190,27 +205,30 @@ out:
 }
 EXPORT_SYMBOL(mlx5_rl_add_rate);
 
-void mlx5_rl_remove_rate(struct mlx5_core_dev *dev, u32 rate)
+void mlx5_rl_remove_rate(struct mlx5_core_dev *dev, struct mlx5_rate_limit *rl)
 {
        struct mlx5_rl_table *table = &dev->priv.rl_table;
        struct mlx5_rl_entry *entry = NULL;
+       struct mlx5_rate_limit reset_rl = {0};
 
        /* 0 is a reserved value for unlimited rate */
-       if (rate == 0)
+       if (rl->rate == 0)
                return;
 
        mutex_lock(&table->rl_lock);
-       entry = find_rl_entry(table, rate);
+       entry = find_rl_entry(table, rl);
        if (!entry || !entry->refcount) {
-               mlx5_core_warn(dev, "Rate %u is not configured\n", rate);
+               mlx5_core_warn(dev, "Rate %u, max_burst_sz %u typical_pkt_sz %u \
+                              are not configured\n",
+                              rl->rate, rl->max_burst_sz, rl->typical_pkt_sz);
                goto out;
        }
 
        entry->refcount--;
        if (!entry->refcount) {
                /* need to remove rate */
-               mlx5_set_pp_rate_limit_cmd(dev, 0, entry->index);
-               entry->rate = 0;
+               mlx5_set_pp_rate_limit_cmd(dev, entry->index, &reset_rl);
+               entry->rl = reset_rl;
        }
 
 out:
@@ -257,13 +275,14 @@ int mlx5_init_rl_table(struct mlx5_core_dev *dev)
 void mlx5_cleanup_rl_table(struct mlx5_core_dev *dev)
 {
        struct mlx5_rl_table *table = &dev->priv.rl_table;
+       struct mlx5_rate_limit rl = {0};
        int i;
 
        /* Clear all configured rates */
        for (i = 0; i < table->max_size; i++)
-               if (table->rl_entry[i].rate)
-                       mlx5_set_pp_rate_limit_cmd(dev, 0,
-                                                  table->rl_entry[i].index);
+               if (table->rl_entry[i].rl.rate)
+                       mlx5_set_pp_rate_limit_cmd(dev, table->rl_entry[i].index,
+                                                  &rl);
 
        kfree(dev->priv.rl_table.rl_entry);
 }