/* QLogic qed NIC Driver
 * Copyright (c) 2015-2017  QLogic Corporation
 *
 * 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/types.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/string.h>
#include "qed.h"
#include "qed_iscsi.h"
#include "qed_ll2.h"
#include "qed_ooo.h"

static struct qed_ooo_archipelago
*qed_ooo_seek_archipelago(struct qed_hwfn *p_hwfn,
			  struct qed_ooo_info
			  *p_ooo_info,
			  u32 cid)
{
	struct qed_ooo_archipelago *p_archipelago = NULL;

	list_for_each_entry(p_archipelago,
			    &p_ooo_info->archipelagos_list, list_entry) {
		if (p_archipelago->cid == cid)
			return p_archipelago;
	}

	return NULL;
}

static struct qed_ooo_isle *qed_ooo_seek_isle(struct qed_hwfn *p_hwfn,
					      struct qed_ooo_info *p_ooo_info,
					      u32 cid, u8 isle)
{
	struct qed_ooo_archipelago *p_archipelago = NULL;
	struct qed_ooo_isle *p_isle = NULL;
	u8 the_num_of_isle = 1;

	p_archipelago = qed_ooo_seek_archipelago(p_hwfn, p_ooo_info, cid);
	if (!p_archipelago) {
		DP_NOTICE(p_hwfn,
			  "Connection %d is not found in OOO list\n", cid);
		return NULL;
	}

	list_for_each_entry(p_isle, &p_archipelago->isles_list, list_entry) {
		if (the_num_of_isle == isle)
			return p_isle;
		the_num_of_isle++;
	}

	return NULL;
}

void qed_ooo_save_history_entry(struct qed_hwfn *p_hwfn,
				struct qed_ooo_info *p_ooo_info,
				struct ooo_opaque *p_cqe)
{
	struct qed_ooo_history *p_history = &p_ooo_info->ooo_history;

	if (p_history->head_idx == p_history->num_of_cqes)
		p_history->head_idx = 0;
	p_history->p_cqes[p_history->head_idx] = *p_cqe;
	p_history->head_idx++;
}

struct qed_ooo_info *qed_ooo_alloc(struct qed_hwfn *p_hwfn)
{
	struct qed_ooo_info *p_ooo_info;
	u16 max_num_archipelagos = 0;
	u16 max_num_isles = 0;
	u32 i;

	if (p_hwfn->hw_info.personality != QED_PCI_ISCSI) {
		DP_NOTICE(p_hwfn,
			  "Failed to allocate qed_ooo_info: unknown personality\n");
		return NULL;
	}

	max_num_archipelagos = p_hwfn->pf_params.iscsi_pf_params.num_cons;
	max_num_isles = QED_MAX_NUM_ISLES + max_num_archipelagos;

	if (!max_num_archipelagos) {
		DP_NOTICE(p_hwfn,
			  "Failed to allocate qed_ooo_info: unknown amount of connections\n");
		return NULL;
	}

	p_ooo_info = kzalloc(sizeof(*p_ooo_info), GFP_KERNEL);
	if (!p_ooo_info)
		return NULL;

	INIT_LIST_HEAD(&p_ooo_info->free_buffers_list);
	INIT_LIST_HEAD(&p_ooo_info->ready_buffers_list);
	INIT_LIST_HEAD(&p_ooo_info->free_isles_list);
	INIT_LIST_HEAD(&p_ooo_info->free_archipelagos_list);
	INIT_LIST_HEAD(&p_ooo_info->archipelagos_list);

	p_ooo_info->p_isles_mem = kcalloc(max_num_isles,
					  sizeof(struct qed_ooo_isle),
					  GFP_KERNEL);
	if (!p_ooo_info->p_isles_mem)
		goto no_isles_mem;

	for (i = 0; i < max_num_isles; i++) {
		INIT_LIST_HEAD(&p_ooo_info->p_isles_mem[i].buffers_list);
		list_add_tail(&p_ooo_info->p_isles_mem[i].list_entry,
			      &p_ooo_info->free_isles_list);
	}

	p_ooo_info->p_archipelagos_mem =
				kcalloc(max_num_archipelagos,
					sizeof(struct qed_ooo_archipelago),
					GFP_KERNEL);
	if (!p_ooo_info->p_archipelagos_mem)
		goto no_archipelagos_mem;

	for (i = 0; i < max_num_archipelagos; i++) {
		INIT_LIST_HEAD(&p_ooo_info->p_archipelagos_mem[i].isles_list);
		list_add_tail(&p_ooo_info->p_archipelagos_mem[i].list_entry,
			      &p_ooo_info->free_archipelagos_list);
	}

	p_ooo_info->ooo_history.p_cqes =
				kcalloc(QED_MAX_NUM_OOO_HISTORY_ENTRIES,
					sizeof(struct ooo_opaque),
					GFP_KERNEL);
	if (!p_ooo_info->ooo_history.p_cqes)
		goto no_history_mem;

	p_ooo_info->ooo_history.num_of_cqes = QED_MAX_NUM_OOO_HISTORY_ENTRIES;

	return p_ooo_info;

no_history_mem:
	kfree(p_ooo_info->p_archipelagos_mem);
no_archipelagos_mem:
	kfree(p_ooo_info->p_isles_mem);
no_isles_mem:
	kfree(p_ooo_info);
	return NULL;
}

void qed_ooo_release_connection_isles(struct qed_hwfn *p_hwfn,
				      struct qed_ooo_info *p_ooo_info, u32 cid)
{
	struct qed_ooo_archipelago *p_archipelago;
	struct qed_ooo_buffer *p_buffer;
	struct qed_ooo_isle *p_isle;
	bool b_found = false;

	if (list_empty(&p_ooo_info->archipelagos_list))
		return;

	list_for_each_entry(p_archipelago,
			    &p_ooo_info->archipelagos_list, list_entry) {
		if (p_archipelago->cid == cid) {
			list_del(&p_archipelago->list_entry);
			b_found = true;
			break;
		}
	}

	if (!b_found)
		return;

	while (!list_empty(&p_archipelago->isles_list)) {
		p_isle = list_first_entry(&p_archipelago->isles_list,
					  struct qed_ooo_isle, list_entry);

		list_del(&p_isle->list_entry);

		while (!list_empty(&p_isle->buffers_list)) {
			p_buffer = list_first_entry(&p_isle->buffers_list,
						    struct qed_ooo_buffer,
						    list_entry);

			if (!p_buffer)
				break;

			list_del(&p_buffer->list_entry);
			list_add_tail(&p_buffer->list_entry,
				      &p_ooo_info->free_buffers_list);
		}
		list_add_tail(&p_isle->list_entry,
			      &p_ooo_info->free_isles_list);
	}

	list_add_tail(&p_archipelago->list_entry,
		      &p_ooo_info->free_archipelagos_list);
}

void qed_ooo_release_all_isles(struct qed_hwfn *p_hwfn,
			       struct qed_ooo_info *p_ooo_info)
{
	struct qed_ooo_archipelago *p_arch;
	struct qed_ooo_buffer *p_buffer;
	struct qed_ooo_isle *p_isle;

	while (!list_empty(&p_ooo_info->archipelagos_list)) {
		p_arch = list_first_entry(&p_ooo_info->archipelagos_list,
					  struct qed_ooo_archipelago,
					  list_entry);

		list_del(&p_arch->list_entry);

		while (!list_empty(&p_arch->isles_list)) {
			p_isle = list_first_entry(&p_arch->isles_list,
						  struct qed_ooo_isle,
						  list_entry);

			list_del(&p_isle->list_entry);

			while (!list_empty(&p_isle->buffers_list)) {
				p_buffer =
				    list_first_entry(&p_isle->buffers_list,
						     struct qed_ooo_buffer,
						     list_entry);

				if (!p_buffer)
					break;

			list_del(&p_buffer->list_entry);
				list_add_tail(&p_buffer->list_entry,
					      &p_ooo_info->free_buffers_list);
			}
			list_add_tail(&p_isle->list_entry,
				      &p_ooo_info->free_isles_list);
		}
		list_add_tail(&p_arch->list_entry,
			      &p_ooo_info->free_archipelagos_list);
	}
	if (!list_empty(&p_ooo_info->ready_buffers_list))
		list_splice_tail_init(&p_ooo_info->ready_buffers_list,
				      &p_ooo_info->free_buffers_list);
}

void qed_ooo_setup(struct qed_hwfn *p_hwfn, struct qed_ooo_info *p_ooo_info)
{
	qed_ooo_release_all_isles(p_hwfn, p_ooo_info);
	memset(p_ooo_info->ooo_history.p_cqes, 0,
	       p_ooo_info->ooo_history.num_of_cqes *
	       sizeof(struct ooo_opaque));
	p_ooo_info->ooo_history.head_idx = 0;
}

void qed_ooo_free(struct qed_hwfn *p_hwfn, struct qed_ooo_info *p_ooo_info)
{
	struct qed_ooo_buffer *p_buffer;

	qed_ooo_release_all_isles(p_hwfn, p_ooo_info);
	while (!list_empty(&p_ooo_info->free_buffers_list)) {
		p_buffer = list_first_entry(&p_ooo_info->free_buffers_list,
					    struct qed_ooo_buffer, list_entry);

		if (!p_buffer)
			break;

		list_del(&p_buffer->list_entry);
		dma_free_coherent(&p_hwfn->cdev->pdev->dev,
				  p_buffer->rx_buffer_size,
				  p_buffer->rx_buffer_virt_addr,
				  p_buffer->rx_buffer_phys_addr);
		kfree(p_buffer);
	}

	kfree(p_ooo_info->p_isles_mem);
	kfree(p_ooo_info->p_archipelagos_mem);
	kfree(p_ooo_info->ooo_history.p_cqes);
	kfree(p_ooo_info);
}

void qed_ooo_put_free_buffer(struct qed_hwfn *p_hwfn,
			     struct qed_ooo_info *p_ooo_info,
			     struct qed_ooo_buffer *p_buffer)
{
	list_add_tail(&p_buffer->list_entry, &p_ooo_info->free_buffers_list);
}

struct qed_ooo_buffer *qed_ooo_get_free_buffer(struct qed_hwfn *p_hwfn,
					       struct qed_ooo_info *p_ooo_info)
{
	struct qed_ooo_buffer *p_buffer = NULL;

	if (!list_empty(&p_ooo_info->free_buffers_list)) {
		p_buffer = list_first_entry(&p_ooo_info->free_buffers_list,
					    struct qed_ooo_buffer, list_entry);

		list_del(&p_buffer->list_entry);
	}

	return p_buffer;
}

void qed_ooo_put_ready_buffer(struct qed_hwfn *p_hwfn,
			      struct qed_ooo_info *p_ooo_info,
			      struct qed_ooo_buffer *p_buffer, u8 on_tail)
{
	if (on_tail)
		list_add_tail(&p_buffer->list_entry,
			      &p_ooo_info->ready_buffers_list);
	else
		list_add(&p_buffer->list_entry,
			 &p_ooo_info->ready_buffers_list);
}

struct qed_ooo_buffer *qed_ooo_get_ready_buffer(struct qed_hwfn *p_hwfn,
						struct qed_ooo_info *p_ooo_info)
{
	struct qed_ooo_buffer *p_buffer = NULL;

	if (!list_empty(&p_ooo_info->ready_buffers_list)) {
		p_buffer = list_first_entry(&p_ooo_info->ready_buffers_list,
					    struct qed_ooo_buffer, list_entry);

		list_del(&p_buffer->list_entry);
	}

	return p_buffer;
}

void qed_ooo_delete_isles(struct qed_hwfn *p_hwfn,
			  struct qed_ooo_info *p_ooo_info,
			  u32 cid, u8 drop_isle, u8 drop_size)
{
	struct qed_ooo_archipelago *p_archipelago = NULL;
	struct qed_ooo_isle *p_isle = NULL;
	u8 isle_idx;

	p_archipelago = qed_ooo_seek_archipelago(p_hwfn, p_ooo_info, cid);
	for (isle_idx = 0; isle_idx < drop_size; isle_idx++) {
		p_isle = qed_ooo_seek_isle(p_hwfn, p_ooo_info, cid, drop_isle);
		if (!p_isle) {
			DP_NOTICE(p_hwfn,
				  "Isle %d is not found(cid %d)\n",
				  drop_isle, cid);
			return;
		}
		if (list_empty(&p_isle->buffers_list))
			DP_NOTICE(p_hwfn,
				  "Isle %d is empty(cid %d)\n", drop_isle, cid);
		else
			list_splice_tail_init(&p_isle->buffers_list,
					      &p_ooo_info->free_buffers_list);

		list_del(&p_isle->list_entry);
		p_ooo_info->cur_isles_number--;
		list_add(&p_isle->list_entry, &p_ooo_info->free_isles_list);
	}

	if (list_empty(&p_archipelago->isles_list)) {
		list_del(&p_archipelago->list_entry);
		list_add(&p_archipelago->list_entry,
			 &p_ooo_info->free_archipelagos_list);
	}
}

void qed_ooo_add_new_isle(struct qed_hwfn *p_hwfn,
			  struct qed_ooo_info *p_ooo_info,
			  u32 cid, u8 ooo_isle,
			  struct qed_ooo_buffer *p_buffer)
{
	struct qed_ooo_archipelago *p_archipelago = NULL;
	struct qed_ooo_isle *p_prev_isle = NULL;
	struct qed_ooo_isle *p_isle = NULL;

	if (ooo_isle > 1) {
		p_prev_isle = qed_ooo_seek_isle(p_hwfn,
						p_ooo_info, cid, ooo_isle - 1);
		if (!p_prev_isle) {
			DP_NOTICE(p_hwfn,
				  "Isle %d is not found(cid %d)\n",
				  ooo_isle - 1, cid);
			return;
		}
	}
	p_archipelago = qed_ooo_seek_archipelago(p_hwfn, p_ooo_info, cid);
	if (!p_archipelago && (ooo_isle != 1)) {
		DP_NOTICE(p_hwfn,
			  "Connection %d is not found in OOO list\n", cid);
		return;
	}

	if (!list_empty(&p_ooo_info->free_isles_list)) {
		p_isle = list_first_entry(&p_ooo_info->free_isles_list,
					  struct qed_ooo_isle, list_entry);

		list_del(&p_isle->list_entry);
		if (!list_empty(&p_isle->buffers_list)) {
			DP_NOTICE(p_hwfn, "Free isle is not empty\n");
			INIT_LIST_HEAD(&p_isle->buffers_list);
		}
	} else {
		DP_NOTICE(p_hwfn, "No more free isles\n");
		return;
	}

	if (!p_archipelago &&
	    !list_empty(&p_ooo_info->free_archipelagos_list)) {
		p_archipelago =
		    list_first_entry(&p_ooo_info->free_archipelagos_list,
				     struct qed_ooo_archipelago, list_entry);

		list_del(&p_archipelago->list_entry);
		if (!list_empty(&p_archipelago->isles_list)) {
			DP_NOTICE(p_hwfn,
				  "Free OOO connection is not empty\n");
			INIT_LIST_HEAD(&p_archipelago->isles_list);
		}
		p_archipelago->cid = cid;
		list_add(&p_archipelago->list_entry,
			 &p_ooo_info->archipelagos_list);
	} else if (!p_archipelago) {
		DP_NOTICE(p_hwfn, "No more free OOO connections\n");
		list_add(&p_isle->list_entry,
			 &p_ooo_info->free_isles_list);
		list_add(&p_buffer->list_entry,
			 &p_ooo_info->free_buffers_list);
		return;
	}

	list_add(&p_buffer->list_entry, &p_isle->buffers_list);
	p_ooo_info->cur_isles_number++;
	p_ooo_info->gen_isles_number++;

	if (p_ooo_info->cur_isles_number > p_ooo_info->max_isles_number)
		p_ooo_info->max_isles_number = p_ooo_info->cur_isles_number;

	if (!p_prev_isle)
		list_add(&p_isle->list_entry, &p_archipelago->isles_list);
	else
		list_add(&p_isle->list_entry, &p_prev_isle->list_entry);
}

void qed_ooo_add_new_buffer(struct qed_hwfn *p_hwfn,
			    struct qed_ooo_info *p_ooo_info,
			    u32 cid,
			    u8 ooo_isle,
			    struct qed_ooo_buffer *p_buffer, u8 buffer_side)
{
	struct qed_ooo_isle *p_isle = NULL;

	p_isle = qed_ooo_seek_isle(p_hwfn, p_ooo_info, cid, ooo_isle);
	if (!p_isle) {
		DP_NOTICE(p_hwfn,
			  "Isle %d is not found(cid %d)\n", ooo_isle, cid);
		return;
	}

	if (buffer_side == QED_OOO_LEFT_BUF)
		list_add(&p_buffer->list_entry, &p_isle->buffers_list);
	else
		list_add_tail(&p_buffer->list_entry, &p_isle->buffers_list);
}

void qed_ooo_join_isles(struct qed_hwfn *p_hwfn,
			struct qed_ooo_info *p_ooo_info, u32 cid, u8 left_isle)
{
	struct qed_ooo_archipelago *p_archipelago = NULL;
	struct qed_ooo_isle *p_right_isle = NULL;
	struct qed_ooo_isle *p_left_isle = NULL;

	p_right_isle = qed_ooo_seek_isle(p_hwfn, p_ooo_info, cid,
					 left_isle + 1);
	if (!p_right_isle) {
		DP_NOTICE(p_hwfn,
			  "Right isle %d is not found(cid %d)\n",
			  left_isle + 1, cid);
		return;
	}

	p_archipelago = qed_ooo_seek_archipelago(p_hwfn, p_ooo_info, cid);
	list_del(&p_right_isle->list_entry);
	p_ooo_info->cur_isles_number--;
	if (left_isle) {
		p_left_isle = qed_ooo_seek_isle(p_hwfn, p_ooo_info, cid,
						left_isle);
		if (!p_left_isle) {
			DP_NOTICE(p_hwfn,
				  "Left isle %d is not found(cid %d)\n",
				  left_isle, cid);
			return;
		}
		list_splice_tail_init(&p_right_isle->buffers_list,
				      &p_left_isle->buffers_list);
	} else {
		list_splice_tail_init(&p_right_isle->buffers_list,
				      &p_ooo_info->ready_buffers_list);
		if (list_empty(&p_archipelago->isles_list)) {
			list_del(&p_archipelago->list_entry);
			list_add(&p_archipelago->list_entry,
				 &p_ooo_info->free_archipelagos_list);
		}
	}
	list_add_tail(&p_right_isle->list_entry, &p_ooo_info->free_isles_list);
}
