/*
 * Copyright (c) 2013, Cisco Systems, Inc. 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
 * 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/errno.h>
#include <linux/module.h>
#include <linux/pci.h>

#include "usnic_ib.h"
#include "vnic_resource.h"
#include "usnic_log.h"
#include "usnic_vnic.h"

struct usnic_vnic {
	struct vnic_dev			*vdev;
	struct vnic_dev_bar		bar[PCI_NUM_RESOURCES];
	struct usnic_vnic_res_chunk	chunks[USNIC_VNIC_RES_TYPE_MAX];
	spinlock_t			res_lock;
};

static enum vnic_res_type _to_vnic_res_type(enum usnic_vnic_res_type res_type)
{
#define DEFINE_USNIC_VNIC_RES_AT(usnic_vnic_res_t, vnic_res_type, desc, val) \
		vnic_res_type,
#define DEFINE_USNIC_VNIC_RES(usnic_vnic_res_t, vnic_res_type, desc) \
		vnic_res_type,
	static enum vnic_res_type usnic_vnic_type_2_vnic_type[] = {
						USNIC_VNIC_RES_TYPES};
#undef DEFINE_USNIC_VNIC_RES
#undef DEFINE_USNIC_VNIC_RES_AT

	if (res_type >= USNIC_VNIC_RES_TYPE_MAX)
		return RES_TYPE_MAX;

	return usnic_vnic_type_2_vnic_type[res_type];
}

const char *usnic_vnic_res_type_to_str(enum usnic_vnic_res_type res_type)
{
#define DEFINE_USNIC_VNIC_RES_AT(usnic_vnic_res_t, vnic_res_type, desc, val) \
		desc,
#define DEFINE_USNIC_VNIC_RES(usnic_vnic_res_t, vnic_res_type, desc) \
		desc,
	static const char * const usnic_vnic_res_type_desc[] = {
						USNIC_VNIC_RES_TYPES};
#undef DEFINE_USNIC_VNIC_RES
#undef DEFINE_USNIC_VNIC_RES_AT

	if (res_type >= USNIC_VNIC_RES_TYPE_MAX)
		return "unknown";

	return usnic_vnic_res_type_desc[res_type];

}

const char *usnic_vnic_pci_name(struct usnic_vnic *vnic)
{
	return pci_name(usnic_vnic_get_pdev(vnic));
}

int usnic_vnic_dump(struct usnic_vnic *vnic, char *buf,
			int buf_sz,
			void *hdr_obj,
			int (*printtitle)(void *, char*, int),
			int (*printcols)(char *, int),
			int (*printrow)(void *, char *, int))
{
	struct usnic_vnic_res_chunk *chunk;
	struct usnic_vnic_res *res;
	struct vnic_dev_bar *bar0;
	int i, j, offset;

	offset = 0;
	bar0 = usnic_vnic_get_bar(vnic, 0);
	offset += scnprintf(buf + offset, buf_sz - offset,
			"VF:%hu BAR0 bus_addr=%pa vaddr=0x%p size=%ld ",
			usnic_vnic_get_index(vnic),
			&bar0->bus_addr,
			bar0->vaddr, bar0->len);
	if (printtitle)
		offset += printtitle(hdr_obj, buf + offset, buf_sz - offset);
	offset += scnprintf(buf + offset, buf_sz - offset, "\n");
	offset += scnprintf(buf + offset, buf_sz - offset,
			"|RES\t|CTRL_PIN\t\t|IN_USE\t");
	if (printcols)
		offset += printcols(buf + offset, buf_sz - offset);
	offset += scnprintf(buf + offset, buf_sz - offset, "\n");

	spin_lock(&vnic->res_lock);
	for (i = 0; i < ARRAY_SIZE(vnic->chunks); i++) {
		chunk = &vnic->chunks[i];
		for (j = 0; j < chunk->cnt; j++) {
			res = chunk->res[j];
			offset += scnprintf(buf + offset, buf_sz - offset,
					"|%s[%u]\t|0x%p\t|%u\t",
					usnic_vnic_res_type_to_str(res->type),
					res->vnic_idx, res->ctrl, !!res->owner);
			if (printrow) {
				offset += printrow(res->owner, buf + offset,
							buf_sz - offset);
			}
			offset += scnprintf(buf + offset, buf_sz - offset,
						"\n");
		}
	}
	spin_unlock(&vnic->res_lock);
	return offset;
}

void usnic_vnic_res_spec_update(struct usnic_vnic_res_spec *spec,
				enum usnic_vnic_res_type trgt_type,
				u16 cnt)
{
	int i;

	for (i = 0; i < USNIC_VNIC_RES_TYPE_MAX; i++) {
		if (spec->resources[i].type == trgt_type) {
			spec->resources[i].cnt = cnt;
			return;
		}
	}

	WARN_ON(1);
}

int usnic_vnic_res_spec_satisfied(const struct usnic_vnic_res_spec *min_spec,
					struct usnic_vnic_res_spec *res_spec)
{
	int found, i, j;

	for (i = 0; i < USNIC_VNIC_RES_TYPE_MAX; i++) {
		found = 0;

		for (j = 0; j < USNIC_VNIC_RES_TYPE_MAX; j++) {
			if (res_spec->resources[i].type !=
				min_spec->resources[i].type)
				continue;
			found = 1;
			if (min_spec->resources[i].cnt >
					res_spec->resources[i].cnt)
				return -EINVAL;
			break;
		}

		if (!found)
			return -EINVAL;
	}
	return 0;
}

int usnic_vnic_spec_dump(char *buf, int buf_sz,
				struct usnic_vnic_res_spec *res_spec)
{
	enum usnic_vnic_res_type res_type;
	int res_cnt;
	int i;
	int offset = 0;

	for (i = 0; i < USNIC_VNIC_RES_TYPE_MAX; i++) {
		res_type = res_spec->resources[i].type;
		res_cnt = res_spec->resources[i].cnt;
		offset += scnprintf(buf + offset, buf_sz - offset,
				"Res: %s Cnt: %d ",
				usnic_vnic_res_type_to_str(res_type),
				res_cnt);
	}

	return offset;
}

int usnic_vnic_check_room(struct usnic_vnic *vnic,
				struct usnic_vnic_res_spec *res_spec)
{
	int i;
	enum usnic_vnic_res_type res_type;
	int res_cnt;

	for (i = 0; i < USNIC_VNIC_RES_TYPE_MAX; i++) {
		res_type = res_spec->resources[i].type;
		res_cnt = res_spec->resources[i].cnt;

		if (res_type == USNIC_VNIC_RES_TYPE_EOL)
			break;

		if (res_cnt > usnic_vnic_res_free_cnt(vnic, res_type))
			return -EBUSY;
	}

	return 0;
}

int usnic_vnic_res_cnt(struct usnic_vnic *vnic,
				enum usnic_vnic_res_type type)
{
	return vnic->chunks[type].cnt;
}

int usnic_vnic_res_free_cnt(struct usnic_vnic *vnic,
				enum usnic_vnic_res_type type)
{
	return vnic->chunks[type].free_cnt;
}

struct usnic_vnic_res_chunk *
usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type,
				int cnt, void *owner)
{
	struct usnic_vnic_res_chunk *src, *ret;
	struct usnic_vnic_res *res;
	int i;

	if (usnic_vnic_res_free_cnt(vnic, type) < cnt || cnt < 0 || !owner)
		return ERR_PTR(-EINVAL);

	ret = kzalloc(sizeof(*ret), GFP_ATOMIC);
	if (!ret)
		return ERR_PTR(-ENOMEM);

	if (cnt > 0) {
		ret->res = kcalloc(cnt, sizeof(*(ret->res)), GFP_ATOMIC);
		if (!ret->res) {
			kfree(ret);
			return ERR_PTR(-ENOMEM);
		}

		spin_lock(&vnic->res_lock);
		src = &vnic->chunks[type];
		for (i = 0; i < src->cnt && ret->cnt < cnt; i++) {
			res = src->res[i];
			if (!res->owner) {
				src->free_cnt--;
				res->owner = owner;
				ret->res[ret->cnt++] = res;
			}
		}

		spin_unlock(&vnic->res_lock);
	}
	ret->type = type;
	ret->vnic = vnic;
	WARN_ON(ret->cnt != cnt);

	return ret;
}

void usnic_vnic_put_resources(struct usnic_vnic_res_chunk *chunk)
{

	struct usnic_vnic_res *res;
	int i;
	struct usnic_vnic *vnic = chunk->vnic;

	if (chunk->cnt > 0) {
		spin_lock(&vnic->res_lock);
		while ((i = --chunk->cnt) >= 0) {
			res = chunk->res[i];
			chunk->res[i] = NULL;
			res->owner = NULL;
			vnic->chunks[res->type].free_cnt++;
		}
		spin_unlock(&vnic->res_lock);
	}

	kfree(chunk->res);
	kfree(chunk);
}

u16 usnic_vnic_get_index(struct usnic_vnic *vnic)
{
	return usnic_vnic_get_pdev(vnic)->devfn - 1;
}

static int usnic_vnic_alloc_res_chunk(struct usnic_vnic *vnic,
					enum usnic_vnic_res_type type,
					struct usnic_vnic_res_chunk *chunk)
{
	int cnt, err, i;
	struct usnic_vnic_res *res;

	cnt = vnic_dev_get_res_count(vnic->vdev, _to_vnic_res_type(type));
	if (cnt < 1) {
		usnic_err("Wrong res count with cnt %d\n", cnt);
		return -EINVAL;
	}

	chunk->cnt = chunk->free_cnt = cnt;
	chunk->res = kzalloc(sizeof(*(chunk->res))*cnt, GFP_KERNEL);
	if (!chunk->res)
		return -ENOMEM;

	for (i = 0; i < cnt; i++) {
		res = kzalloc(sizeof(*res), GFP_KERNEL);
		if (!res) {
			err = -ENOMEM;
			goto fail;
		}
		res->type = type;
		res->vnic_idx = i;
		res->vnic = vnic;
		res->ctrl = vnic_dev_get_res(vnic->vdev,
						_to_vnic_res_type(type), i);
		chunk->res[i] = res;
	}

	chunk->vnic = vnic;
	return 0;
fail:
	for (i--; i >= 0; i--)
		kfree(chunk->res[i]);
	kfree(chunk->res);
	return err;
}

static void usnic_vnic_free_res_chunk(struct usnic_vnic_res_chunk *chunk)
{
	int i;
	for (i = 0; i < chunk->cnt; i++)
		kfree(chunk->res[i]);
	kfree(chunk->res);
}

static int usnic_vnic_discover_resources(struct pci_dev *pdev,
						struct usnic_vnic *vnic)
{
	enum usnic_vnic_res_type res_type;
	int i;
	int err = 0;

	for (i = 0; i < ARRAY_SIZE(vnic->bar); i++) {
		if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
			continue;
		vnic->bar[i].len = pci_resource_len(pdev, i);
		vnic->bar[i].vaddr = pci_iomap(pdev, i, vnic->bar[i].len);
		if (!vnic->bar[i].vaddr) {
			usnic_err("Cannot memory-map BAR %d, aborting\n",
					i);
			err = -ENODEV;
			goto out_clean_bar;
		}
		vnic->bar[i].bus_addr = pci_resource_start(pdev, i);
	}

	vnic->vdev = vnic_dev_register(NULL, pdev, pdev, vnic->bar,
			ARRAY_SIZE(vnic->bar));
	if (!vnic->vdev) {
		usnic_err("Failed to register device %s\n",
				pci_name(pdev));
		err = -EINVAL;
		goto out_clean_bar;
	}

	for (res_type = USNIC_VNIC_RES_TYPE_EOL + 1;
			res_type < USNIC_VNIC_RES_TYPE_MAX; res_type++) {
		err = usnic_vnic_alloc_res_chunk(vnic, res_type,
						&vnic->chunks[res_type]);
		if (err)
			goto out_clean_chunks;
	}

	return 0;

out_clean_chunks:
	for (res_type--; res_type > USNIC_VNIC_RES_TYPE_EOL; res_type--)
		usnic_vnic_free_res_chunk(&vnic->chunks[res_type]);
	vnic_dev_unregister(vnic->vdev);
out_clean_bar:
	for (i = 0; i < ARRAY_SIZE(vnic->bar); i++) {
		if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
			continue;
		if (!vnic->bar[i].vaddr)
			break;

		iounmap(vnic->bar[i].vaddr);
	}

	return err;
}

struct pci_dev *usnic_vnic_get_pdev(struct usnic_vnic *vnic)
{
	return vnic_dev_get_pdev(vnic->vdev);
}

struct vnic_dev_bar *usnic_vnic_get_bar(struct usnic_vnic *vnic,
				int bar_num)
{
	return (bar_num < ARRAY_SIZE(vnic->bar)) ? &vnic->bar[bar_num] : NULL;
}

static void usnic_vnic_release_resources(struct usnic_vnic *vnic)
{
	int i;
	struct pci_dev *pdev;
	enum usnic_vnic_res_type res_type;

	pdev = usnic_vnic_get_pdev(vnic);

	for (res_type = USNIC_VNIC_RES_TYPE_EOL + 1;
			res_type < USNIC_VNIC_RES_TYPE_MAX; res_type++)
		usnic_vnic_free_res_chunk(&vnic->chunks[res_type]);

	vnic_dev_unregister(vnic->vdev);

	for (i = 0; i < ARRAY_SIZE(vnic->bar); i++) {
		if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
			continue;
		iounmap(vnic->bar[i].vaddr);
	}
}

struct usnic_vnic *usnic_vnic_alloc(struct pci_dev *pdev)
{
	struct usnic_vnic *vnic;
	int err = 0;

	if (!pci_is_enabled(pdev)) {
		usnic_err("PCI dev %s is disabled\n", pci_name(pdev));
		return ERR_PTR(-EINVAL);
	}

	vnic = kzalloc(sizeof(*vnic), GFP_KERNEL);
	if (!vnic)
		return ERR_PTR(-ENOMEM);

	spin_lock_init(&vnic->res_lock);

	err = usnic_vnic_discover_resources(pdev, vnic);
	if (err) {
		usnic_err("Failed to discover %s resources with err %d\n",
				pci_name(pdev), err);
		goto out_free_vnic;
	}

	usnic_dbg("Allocated vnic for %s\n", usnic_vnic_pci_name(vnic));

	return vnic;

out_free_vnic:
	kfree(vnic);

	return ERR_PTR(err);
}

void usnic_vnic_free(struct usnic_vnic *vnic)
{
	usnic_vnic_release_resources(vnic);
	kfree(vnic);
}
