/*
 * Copyright (c) 2013-2016, Mellanox Technologies. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mlx5/driver.h>
#include "mlx5_core.h"

/* Scheduling element fw management */
int mlx5_create_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
				       void *ctx, u32 *element_id)
{
	u32 out[MLX5_ST_SZ_DW(create_scheduling_element_in)] = {};
	u32 in[MLX5_ST_SZ_DW(create_scheduling_element_in)] = {};
	void *schedc;
	int err;

	schedc = MLX5_ADDR_OF(create_scheduling_element_in, in,
			      scheduling_context);
	MLX5_SET(create_scheduling_element_in, in, opcode,
		 MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT);
	MLX5_SET(create_scheduling_element_in, in, scheduling_hierarchy,
		 hierarchy);
	memcpy(schedc, ctx, MLX5_ST_SZ_BYTES(scheduling_context));

	err = mlx5_cmd_exec_inout(dev, create_scheduling_element, in, out);
	if (err)
		return err;

	*element_id = MLX5_GET(create_scheduling_element_out, out,
			       scheduling_element_id);
	return 0;
}

int mlx5_modify_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
				       void *ctx, u32 element_id,
				       u32 modify_bitmask)
{
	u32 in[MLX5_ST_SZ_DW(modify_scheduling_element_in)] = {};
	void *schedc;

	schedc = MLX5_ADDR_OF(modify_scheduling_element_in, in,
			      scheduling_context);
	MLX5_SET(modify_scheduling_element_in, in, opcode,
		 MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT);
	MLX5_SET(modify_scheduling_element_in, in, scheduling_element_id,
		 element_id);
	MLX5_SET(modify_scheduling_element_in, in, modify_bitmask,
		 modify_bitmask);
	MLX5_SET(modify_scheduling_element_in, in, scheduling_hierarchy,
		 hierarchy);
	memcpy(schedc, ctx, MLX5_ST_SZ_BYTES(scheduling_context));

	return mlx5_cmd_exec_in(dev, modify_scheduling_element, in);
}

int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
					u32 element_id)
{
	u32 in[MLX5_ST_SZ_DW(destroy_scheduling_element_in)] = {};

	MLX5_SET(destroy_scheduling_element_in, in, opcode,
		 MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT);
	MLX5_SET(destroy_scheduling_element_in, in, scheduling_element_id,
		 element_id);
	MLX5_SET(destroy_scheduling_element_in, in, scheduling_hierarchy,
		 hierarchy);

	return mlx5_cmd_exec_in(dev, destroy_scheduling_element, in);
}

static bool mlx5_rl_are_equal_raw(struct mlx5_rl_entry *entry, void *rl_in,
				  u16 uid)
{
	return (!memcmp(entry->rl_raw, rl_in, sizeof(entry->rl_raw)) &&
		entry->uid == uid);
}

/* Finds an entry where we can register the given rate
 * If the rate already exists, return the entry where it is registered,
 * otherwise return the first available entry.
 * If the table is full, return NULL
 */
static struct mlx5_rl_entry *find_rl_entry(struct mlx5_rl_table *table,
					   void *rl_in, u16 uid, bool dedicated)
{
	struct mlx5_rl_entry *ret_entry = NULL;
	bool empty_found = false;
	int i;

	for (i = 0; i < table->max_size; i++) {
		if (dedicated) {
			if (!table->rl_entry[i].refcount)
				return &table->rl_entry[i];
			continue;
		}

		if (table->rl_entry[i].refcount) {
			if (table->rl_entry[i].dedicated)
				continue;
			if (mlx5_rl_are_equal_raw(&table->rl_entry[i], rl_in,
						  uid))
				return &table->rl_entry[i];
		} else if (!empty_found) {
			empty_found = true;
			ret_entry = &table->rl_entry[i];
		}
	}

	return ret_entry;
}

static int mlx5_set_pp_rate_limit_cmd(struct mlx5_core_dev *dev,
				      struct mlx5_rl_entry *entry, bool set)
{
	u32 in[MLX5_ST_SZ_DW(set_pp_rate_limit_in)] = {};
	void *pp_context;

	pp_context = MLX5_ADDR_OF(set_pp_rate_limit_in, in, ctx);
	MLX5_SET(set_pp_rate_limit_in, in, opcode,
		 MLX5_CMD_OP_SET_PP_RATE_LIMIT);
	MLX5_SET(set_pp_rate_limit_in, in, uid, entry->uid);
	MLX5_SET(set_pp_rate_limit_in, in, rate_limit_index, entry->index);
	if (set)
		memcpy(pp_context, entry->rl_raw, sizeof(entry->rl_raw));
	return mlx5_cmd_exec_in(dev, set_pp_rate_limit, in);
}

bool mlx5_rl_is_in_range(struct mlx5_core_dev *dev, u32 rate)
{
	struct mlx5_rl_table *table = &dev->priv.rl_table;

	return (rate <= table->max_rate && rate >= table->min_rate);
}
EXPORT_SYMBOL(mlx5_rl_is_in_range);

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_raw(struct mlx5_core_dev *dev, void *rl_in, u16 uid,
			 bool dedicated_entry, u16 *index)
{
	struct mlx5_rl_table *table = &dev->priv.rl_table;
	struct mlx5_rl_entry *entry;
	int err = 0;
	u32 rate;

	rate = MLX5_GET(set_pp_rate_limit_context, rl_in, rate_limit);
	mutex_lock(&table->rl_lock);

	if (!rate || !mlx5_rl_is_in_range(dev, rate)) {
		mlx5_core_err(dev, "Invalid rate: %u, should be %u to %u\n",
			      rate, table->min_rate, table->max_rate);
		err = -EINVAL;
		goto out;
	}

	entry = find_rl_entry(table, rl_in, uid, dedicated_entry);
	if (!entry) {
		mlx5_core_err(dev, "Max number of %u rates reached\n",
			      table->max_size);
		err = -ENOSPC;
		goto out;
	}
	if (entry->refcount) {
		/* rate already configured */
		entry->refcount++;
	} else {
		memcpy(entry->rl_raw, rl_in, sizeof(entry->rl_raw));
		entry->uid = uid;
		/* new rate limit */
		err = mlx5_set_pp_rate_limit_cmd(dev, entry, true);
		if (err) {
			mlx5_core_err(
				dev,
				"Failed configuring rate limit(err %d): rate %u, max_burst_sz %u, typical_pkt_sz %u\n",
				err, rate,
				MLX5_GET(set_pp_rate_limit_context, rl_in,
					 burst_upper_bound),
				MLX5_GET(set_pp_rate_limit_context, rl_in,
					 typical_packet_size));
			goto out;
		}

		entry->refcount = 1;
		entry->dedicated = dedicated_entry;
	}
	*index = entry->index;

out:
	mutex_unlock(&table->rl_lock);
	return err;
}
EXPORT_SYMBOL(mlx5_rl_add_rate_raw);

void mlx5_rl_remove_rate_raw(struct mlx5_core_dev *dev, u16 index)
{
	struct mlx5_rl_table *table = &dev->priv.rl_table;
	struct mlx5_rl_entry *entry;

	mutex_lock(&table->rl_lock);
	entry = &table->rl_entry[index - 1];
	entry->refcount--;
	if (!entry->refcount)
		/* need to remove rate */
		mlx5_set_pp_rate_limit_cmd(dev, entry, false);
	mutex_unlock(&table->rl_lock);
}
EXPORT_SYMBOL(mlx5_rl_remove_rate_raw);

int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u16 *index,
		     struct mlx5_rate_limit *rl)
{
	u8 rl_raw[MLX5_ST_SZ_BYTES(set_pp_rate_limit_context)] = {};

	MLX5_SET(set_pp_rate_limit_context, rl_raw, rate_limit, rl->rate);
	MLX5_SET(set_pp_rate_limit_context, rl_raw, burst_upper_bound,
		 rl->max_burst_sz);
	MLX5_SET(set_pp_rate_limit_context, rl_raw, typical_packet_size,
		 rl->typical_pkt_sz);

	return mlx5_rl_add_rate_raw(dev, rl_raw,
				    MLX5_CAP_QOS(dev, packet_pacing_uid) ?
					MLX5_SHARED_RESOURCE_UID : 0,
				    false, index);
}
EXPORT_SYMBOL(mlx5_rl_add_rate);

void mlx5_rl_remove_rate(struct mlx5_core_dev *dev, struct mlx5_rate_limit *rl)
{
	u8 rl_raw[MLX5_ST_SZ_BYTES(set_pp_rate_limit_context)] = {};
	struct mlx5_rl_table *table = &dev->priv.rl_table;
	struct mlx5_rl_entry *entry = NULL;

	/* 0 is a reserved value for unlimited rate */
	if (rl->rate == 0)
		return;

	MLX5_SET(set_pp_rate_limit_context, rl_raw, rate_limit, rl->rate);
	MLX5_SET(set_pp_rate_limit_context, rl_raw, burst_upper_bound,
		 rl->max_burst_sz);
	MLX5_SET(set_pp_rate_limit_context, rl_raw, typical_packet_size,
		 rl->typical_pkt_sz);

	mutex_lock(&table->rl_lock);
	entry = find_rl_entry(table, rl_raw,
			      MLX5_CAP_QOS(dev, packet_pacing_uid) ?
				MLX5_SHARED_RESOURCE_UID : 0, false);
	if (!entry || !entry->refcount) {
		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, entry, false);

out:
	mutex_unlock(&table->rl_lock);
}
EXPORT_SYMBOL(mlx5_rl_remove_rate);

int mlx5_init_rl_table(struct mlx5_core_dev *dev)
{
	struct mlx5_rl_table *table = &dev->priv.rl_table;
	int i;

	mutex_init(&table->rl_lock);
	if (!MLX5_CAP_GEN(dev, qos) || !MLX5_CAP_QOS(dev, packet_pacing)) {
		table->max_size = 0;
		return 0;
	}

	/* First entry is reserved for unlimited rate */
	table->max_size = MLX5_CAP_QOS(dev, packet_pacing_rate_table_size) - 1;
	table->max_rate = MLX5_CAP_QOS(dev, packet_pacing_max_rate);
	table->min_rate = MLX5_CAP_QOS(dev, packet_pacing_min_rate);

	table->rl_entry = kcalloc(table->max_size, sizeof(struct mlx5_rl_entry),
				  GFP_KERNEL);
	if (!table->rl_entry)
		return -ENOMEM;

	/* The index represents the index in HW rate limit table
	 * Index 0 is reserved for unlimited rate
	 */
	for (i = 0; i < table->max_size; i++)
		table->rl_entry[i].index = i + 1;

	/* Index 0 is reserved */
	mlx5_core_info(dev, "Rate limit: %u rates are supported, range: %uMbps to %uMbps\n",
		       table->max_size,
		       table->min_rate >> 10,
		       table->max_rate >> 10);

	return 0;
}

void mlx5_cleanup_rl_table(struct mlx5_core_dev *dev)
{
	struct mlx5_rl_table *table = &dev->priv.rl_table;
	int i;

	/* Clear all configured rates */
	for (i = 0; i < table->max_size; i++)
		if (table->rl_entry[i].refcount)
			mlx5_set_pp_rate_limit_cmd(dev, &table->rl_entry[i],
						   false);

	kfree(dev->priv.rl_table.rl_entry);
}
