/*
 * Copyright (c) 2013-2015, 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/io-mapping.h>
#include <linux/mlx5/driver.h>
#include "mlx5_core.h"

int mlx5_cmd_alloc_uar(struct mlx5_core_dev *dev, u32 *uarn)
{
	u32 out[MLX5_ST_SZ_DW(alloc_uar_out)] = {};
	u32 in[MLX5_ST_SZ_DW(alloc_uar_in)] = {};
	int err;

	MLX5_SET(alloc_uar_in, in, opcode, MLX5_CMD_OP_ALLOC_UAR);
	err = mlx5_cmd_exec_inout(dev, alloc_uar, in, out);
	if (!err)
		*uarn = MLX5_GET(alloc_uar_out, out, uar);
	return err;
}
EXPORT_SYMBOL(mlx5_cmd_alloc_uar);

int mlx5_cmd_free_uar(struct mlx5_core_dev *dev, u32 uarn)
{
	u32 in[MLX5_ST_SZ_DW(dealloc_uar_in)] = {};

	MLX5_SET(dealloc_uar_in, in, opcode, MLX5_CMD_OP_DEALLOC_UAR);
	MLX5_SET(dealloc_uar_in, in, uar, uarn);
	return mlx5_cmd_exec_in(dev, dealloc_uar, in);
}
EXPORT_SYMBOL(mlx5_cmd_free_uar);

static int uars_per_sys_page(struct mlx5_core_dev *mdev)
{
	if (MLX5_CAP_GEN(mdev, uar_4k))
		return MLX5_CAP_GEN(mdev, num_of_uars_per_page);

	return 1;
}

static u64 uar2pfn(struct mlx5_core_dev *mdev, u32 index)
{
	u32 system_page_index;

	if (MLX5_CAP_GEN(mdev, uar_4k))
		system_page_index = index >> (PAGE_SHIFT - MLX5_ADAPTER_PAGE_SHIFT);
	else
		system_page_index = index;

	return (mdev->bar_addr >> PAGE_SHIFT) + system_page_index;
}

static void up_rel_func(struct kref *kref)
{
	struct mlx5_uars_page *up = container_of(kref, struct mlx5_uars_page, ref_count);

	list_del(&up->list);
	iounmap(up->map);
	if (mlx5_cmd_free_uar(up->mdev, up->index))
		mlx5_core_warn(up->mdev, "failed to free uar index %d\n", up->index);
	bitmap_free(up->reg_bitmap);
	bitmap_free(up->fp_bitmap);
	kfree(up);
}

static struct mlx5_uars_page *alloc_uars_page(struct mlx5_core_dev *mdev,
					      bool map_wc)
{
	struct mlx5_uars_page *up;
	int err = -ENOMEM;
	phys_addr_t pfn;
	int bfregs;
	int i;

	bfregs = uars_per_sys_page(mdev) * MLX5_BFREGS_PER_UAR;
	up = kzalloc(sizeof(*up), GFP_KERNEL);
	if (!up)
		return ERR_PTR(err);

	up->mdev = mdev;
	up->reg_bitmap = bitmap_zalloc(bfregs, GFP_KERNEL);
	if (!up->reg_bitmap)
		goto error1;

	up->fp_bitmap = bitmap_zalloc(bfregs, GFP_KERNEL);
	if (!up->fp_bitmap)
		goto error1;

	for (i = 0; i < bfregs; i++)
		if ((i % MLX5_BFREGS_PER_UAR) < MLX5_NON_FP_BFREGS_PER_UAR)
			set_bit(i, up->reg_bitmap);
		else
			set_bit(i, up->fp_bitmap);

	up->bfregs = bfregs;
	up->fp_avail = bfregs * MLX5_FP_BFREGS_PER_UAR / MLX5_BFREGS_PER_UAR;
	up->reg_avail = bfregs * MLX5_NON_FP_BFREGS_PER_UAR / MLX5_BFREGS_PER_UAR;

	err = mlx5_cmd_alloc_uar(mdev, &up->index);
	if (err) {
		mlx5_core_warn(mdev, "mlx5_cmd_alloc_uar() failed, %d\n", err);
		goto error1;
	}

	pfn = uar2pfn(mdev, up->index);
	if (map_wc) {
		up->map = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE);
		if (!up->map) {
			err = -EAGAIN;
			goto error2;
		}
	} else {
		up->map = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
		if (!up->map) {
			err = -ENOMEM;
			goto error2;
		}
	}
	kref_init(&up->ref_count);
	mlx5_core_dbg(mdev, "allocated UAR page: index %d, total bfregs %d\n",
		      up->index, up->bfregs);
	return up;

error2:
	if (mlx5_cmd_free_uar(mdev, up->index))
		mlx5_core_warn(mdev, "failed to free uar index %d\n", up->index);
error1:
	bitmap_free(up->fp_bitmap);
	bitmap_free(up->reg_bitmap);
	kfree(up);
	return ERR_PTR(err);
}

struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev)
{
	struct mlx5_uars_page *ret;

	mutex_lock(&mdev->priv.bfregs.reg_head.lock);
	if (!list_empty(&mdev->priv.bfregs.reg_head.list)) {
		ret = list_first_entry(&mdev->priv.bfregs.reg_head.list,
				       struct mlx5_uars_page, list);
		kref_get(&ret->ref_count);
		goto out;
	}
	ret = alloc_uars_page(mdev, false);
	if (IS_ERR(ret))
		goto out;
	list_add(&ret->list, &mdev->priv.bfregs.reg_head.list);
out:
	mutex_unlock(&mdev->priv.bfregs.reg_head.lock);

	return ret;
}
EXPORT_SYMBOL(mlx5_get_uars_page);

void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up)
{
	mutex_lock(&mdev->priv.bfregs.reg_head.lock);
	kref_put(&up->ref_count, up_rel_func);
	mutex_unlock(&mdev->priv.bfregs.reg_head.lock);
}
EXPORT_SYMBOL(mlx5_put_uars_page);

static unsigned long map_offset(struct mlx5_core_dev *mdev, int dbi)
{
	/* return the offset in bytes from the start of the page to the
	 * blue flame area of the UAR
	 */
	return dbi / MLX5_BFREGS_PER_UAR * MLX5_ADAPTER_PAGE_SIZE +
	       (dbi % MLX5_BFREGS_PER_UAR) *
	       (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) + MLX5_BF_OFFSET;
}

static int alloc_bfreg(struct mlx5_core_dev *mdev, struct mlx5_sq_bfreg *bfreg,
		       bool map_wc, bool fast_path)
{
	struct mlx5_bfreg_data *bfregs;
	struct mlx5_uars_page *up;
	struct list_head *head;
	unsigned long *bitmap;
	unsigned int *avail;
	struct mutex *lock;  /* pointer to right mutex */
	int dbi;

	bfregs = &mdev->priv.bfregs;
	if (map_wc) {
		head = &bfregs->wc_head.list;
		lock = &bfregs->wc_head.lock;
	} else {
		head = &bfregs->reg_head.list;
		lock = &bfregs->reg_head.lock;
	}
	mutex_lock(lock);
	if (list_empty(head)) {
		up = alloc_uars_page(mdev, map_wc);
		if (IS_ERR(up)) {
			mutex_unlock(lock);
			return PTR_ERR(up);
		}
		list_add(&up->list, head);
	} else {
		up = list_entry(head->next, struct mlx5_uars_page, list);
		kref_get(&up->ref_count);
	}
	if (fast_path) {
		bitmap = up->fp_bitmap;
		avail = &up->fp_avail;
	} else {
		bitmap = up->reg_bitmap;
		avail = &up->reg_avail;
	}
	dbi = find_first_bit(bitmap, up->bfregs);
	clear_bit(dbi, bitmap);
	(*avail)--;
	if (!(*avail))
		list_del(&up->list);

	bfreg->map = up->map + map_offset(mdev, dbi);
	bfreg->up = up;
	bfreg->wc = map_wc;
	bfreg->index = up->index + dbi / MLX5_BFREGS_PER_UAR;
	mutex_unlock(lock);

	return 0;
}

int mlx5_alloc_bfreg(struct mlx5_core_dev *mdev, struct mlx5_sq_bfreg *bfreg,
		     bool map_wc, bool fast_path)
{
	int err;

	err = alloc_bfreg(mdev, bfreg, map_wc, fast_path);
	if (!err)
		return 0;

	if (err == -EAGAIN && map_wc)
		return alloc_bfreg(mdev, bfreg, false, fast_path);

	return err;
}
EXPORT_SYMBOL(mlx5_alloc_bfreg);

static unsigned int addr_to_dbi_in_syspage(struct mlx5_core_dev *dev,
					   struct mlx5_uars_page *up,
					   struct mlx5_sq_bfreg *bfreg)
{
	unsigned int uar_idx;
	unsigned int bfreg_idx;
	unsigned int bf_reg_size;

	bf_reg_size = 1 << MLX5_CAP_GEN(dev, log_bf_reg_size);

	uar_idx = (bfreg->map - up->map) >> MLX5_ADAPTER_PAGE_SHIFT;
	bfreg_idx = (((uintptr_t)bfreg->map % MLX5_ADAPTER_PAGE_SIZE) - MLX5_BF_OFFSET) / bf_reg_size;

	return uar_idx * MLX5_BFREGS_PER_UAR + bfreg_idx;
}

void mlx5_free_bfreg(struct mlx5_core_dev *mdev, struct mlx5_sq_bfreg *bfreg)
{
	struct mlx5_bfreg_data *bfregs;
	struct mlx5_uars_page *up;
	struct mutex *lock; /* pointer to right mutex */
	unsigned int dbi;
	bool fp;
	unsigned int *avail;
	unsigned long *bitmap;
	struct list_head *head;

	bfregs = &mdev->priv.bfregs;
	if (bfreg->wc) {
		head = &bfregs->wc_head.list;
		lock = &bfregs->wc_head.lock;
	} else {
		head = &bfregs->reg_head.list;
		lock = &bfregs->reg_head.lock;
	}
	up = bfreg->up;
	dbi = addr_to_dbi_in_syspage(mdev, up, bfreg);
	fp = (dbi % MLX5_BFREGS_PER_UAR) >= MLX5_NON_FP_BFREGS_PER_UAR;
	if (fp) {
		avail = &up->fp_avail;
		bitmap = up->fp_bitmap;
	} else {
		avail = &up->reg_avail;
		bitmap = up->reg_bitmap;
	}
	mutex_lock(lock);
	(*avail)++;
	set_bit(dbi, bitmap);
	if (*avail == 1)
		list_add_tail(&up->list, head);

	kref_put(&up->ref_count, up_rel_func);
	mutex_unlock(lock);
}
EXPORT_SYMBOL(mlx5_free_bfreg);
