// SPDX-License-Identifier: GPL-2.0-only
/*
 *  FUJITSU Extended Socket Network Device driver
 *  Copyright (c) 2015 FUJITSU LIMITED
 */

#include "fjes_hw.h"
#include "fjes.h"
#include "fjes_trace.h"

static void fjes_hw_update_zone_task(struct work_struct *);
static void fjes_hw_epstop_task(struct work_struct *);

/* supported MTU list */
const u32 fjes_support_mtu[] = {
	FJES_MTU_DEFINE(8 * 1024),
	FJES_MTU_DEFINE(16 * 1024),
	FJES_MTU_DEFINE(32 * 1024),
	FJES_MTU_DEFINE(64 * 1024),
	0
};

u32 fjes_hw_rd32(struct fjes_hw *hw, u32 reg)
{
	u8 *base = hw->base;
	u32 value = 0;

	value = readl(&base[reg]);

	return value;
}

static u8 *fjes_hw_iomap(struct fjes_hw *hw)
{
	u8 *base;

	if (!request_mem_region(hw->hw_res.start, hw->hw_res.size,
				fjes_driver_name)) {
		pr_err("request_mem_region failed\n");
		return NULL;
	}

	base = (u8 *)ioremap(hw->hw_res.start, hw->hw_res.size);

	return base;
}

static void fjes_hw_iounmap(struct fjes_hw *hw)
{
	iounmap(hw->base);
	release_mem_region(hw->hw_res.start, hw->hw_res.size);
}

int fjes_hw_reset(struct fjes_hw *hw)
{
	union REG_DCTL dctl;
	int timeout;

	dctl.reg = 0;
	dctl.bits.reset = 1;
	wr32(XSCT_DCTL, dctl.reg);

	timeout = FJES_DEVICE_RESET_TIMEOUT * 1000;
	dctl.reg = rd32(XSCT_DCTL);
	while ((dctl.bits.reset == 1) && (timeout > 0)) {
		msleep(1000);
		dctl.reg = rd32(XSCT_DCTL);
		timeout -= 1000;
	}

	return timeout > 0 ? 0 : -EIO;
}

static int fjes_hw_get_max_epid(struct fjes_hw *hw)
{
	union REG_MAX_EP info;

	info.reg = rd32(XSCT_MAX_EP);

	return info.bits.maxep;
}

static int fjes_hw_get_my_epid(struct fjes_hw *hw)
{
	union REG_OWNER_EPID info;

	info.reg = rd32(XSCT_OWNER_EPID);

	return info.bits.epid;
}

static int fjes_hw_alloc_shared_status_region(struct fjes_hw *hw)
{
	size_t size;

	size = sizeof(struct fjes_device_shared_info) +
	    (sizeof(u8) * hw->max_epid);
	hw->hw_info.share = kzalloc(size, GFP_KERNEL);
	if (!hw->hw_info.share)
		return -ENOMEM;

	hw->hw_info.share->epnum = hw->max_epid;

	return 0;
}

static void fjes_hw_free_shared_status_region(struct fjes_hw *hw)
{
	kfree(hw->hw_info.share);
	hw->hw_info.share = NULL;
}

static int fjes_hw_alloc_epbuf(struct epbuf_handler *epbh)
{
	void *mem;

	mem = vzalloc(EP_BUFFER_SIZE);
	if (!mem)
		return -ENOMEM;

	epbh->buffer = mem;
	epbh->size = EP_BUFFER_SIZE;

	epbh->info = (union ep_buffer_info *)mem;
	epbh->ring = (u8 *)(mem + sizeof(union ep_buffer_info));

	return 0;
}

static void fjes_hw_free_epbuf(struct epbuf_handler *epbh)
{
	vfree(epbh->buffer);
	epbh->buffer = NULL;
	epbh->size = 0;

	epbh->info = NULL;
	epbh->ring = NULL;
}

void fjes_hw_setup_epbuf(struct epbuf_handler *epbh, const u8 *mac_addr,
			 u32 mtu)
{
	union ep_buffer_info *info = epbh->info;
	u16 vlan_id[EP_BUFFER_SUPPORT_VLAN_MAX];
	int i;

	for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
		vlan_id[i] = info->v1i.vlan_id[i];

	memset(info, 0, sizeof(union ep_buffer_info));

	info->v1i.version = 0;  /* version 0 */

	for (i = 0; i < ETH_ALEN; i++)
		info->v1i.mac_addr[i] = mac_addr[i];

	info->v1i.head = 0;
	info->v1i.tail = 1;

	info->v1i.info_size = sizeof(union ep_buffer_info);
	info->v1i.buffer_size = epbh->size - info->v1i.info_size;

	info->v1i.frame_max = FJES_MTU_TO_FRAME_SIZE(mtu);
	info->v1i.count_max =
	    EP_RING_NUM(info->v1i.buffer_size, info->v1i.frame_max);

	for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
		info->v1i.vlan_id[i] = vlan_id[i];

	info->v1i.rx_status |= FJES_RX_MTU_CHANGING_DONE;
}

void
fjes_hw_init_command_registers(struct fjes_hw *hw,
			       struct fjes_device_command_param *param)
{
	/* Request Buffer length */
	wr32(XSCT_REQBL, (__le32)(param->req_len));
	/* Response Buffer Length */
	wr32(XSCT_RESPBL, (__le32)(param->res_len));

	/* Request Buffer Address */
	wr32(XSCT_REQBAL,
	     (__le32)(param->req_start & GENMASK_ULL(31, 0)));
	wr32(XSCT_REQBAH,
	     (__le32)((param->req_start & GENMASK_ULL(63, 32)) >> 32));

	/* Response Buffer Address */
	wr32(XSCT_RESPBAL,
	     (__le32)(param->res_start & GENMASK_ULL(31, 0)));
	wr32(XSCT_RESPBAH,
	     (__le32)((param->res_start & GENMASK_ULL(63, 32)) >> 32));

	/* Share status address */
	wr32(XSCT_SHSTSAL,
	     (__le32)(param->share_start & GENMASK_ULL(31, 0)));
	wr32(XSCT_SHSTSAH,
	     (__le32)((param->share_start & GENMASK_ULL(63, 32)) >> 32));
}

static int fjes_hw_setup(struct fjes_hw *hw)
{
	u8 mac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
	struct fjes_device_command_param param;
	struct ep_share_mem_info *buf_pair;
	unsigned long flags;
	size_t mem_size;
	int result;
	int epidx;
	void *buf;

	hw->hw_info.max_epid = &hw->max_epid;
	hw->hw_info.my_epid = &hw->my_epid;

	buf = kcalloc(hw->max_epid, sizeof(struct ep_share_mem_info),
		      GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	hw->ep_shm_info = (struct ep_share_mem_info *)buf;

	mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid);
	hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL);
	if (!(hw->hw_info.req_buf))
		return -ENOMEM;

	hw->hw_info.req_buf_size = mem_size;

	mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid);
	hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL);
	if (!(hw->hw_info.res_buf))
		return -ENOMEM;

	hw->hw_info.res_buf_size = mem_size;

	result = fjes_hw_alloc_shared_status_region(hw);
	if (result)
		return result;

	hw->hw_info.buffer_share_bit = 0;
	hw->hw_info.buffer_unshare_reserve_bit = 0;

	for (epidx = 0; epidx < hw->max_epid; epidx++) {
		if (epidx != hw->my_epid) {
			buf_pair = &hw->ep_shm_info[epidx];

			result = fjes_hw_alloc_epbuf(&buf_pair->tx);
			if (result)
				return result;

			result = fjes_hw_alloc_epbuf(&buf_pair->rx);
			if (result)
				return result;

			spin_lock_irqsave(&hw->rx_status_lock, flags);
			fjes_hw_setup_epbuf(&buf_pair->tx, mac,
					    fjes_support_mtu[0]);
			fjes_hw_setup_epbuf(&buf_pair->rx, mac,
					    fjes_support_mtu[0]);
			spin_unlock_irqrestore(&hw->rx_status_lock, flags);
		}
	}

	memset(&param, 0, sizeof(param));

	param.req_len = hw->hw_info.req_buf_size;
	param.req_start = __pa(hw->hw_info.req_buf);
	param.res_len = hw->hw_info.res_buf_size;
	param.res_start = __pa(hw->hw_info.res_buf);

	param.share_start = __pa(hw->hw_info.share->ep_status);

	fjes_hw_init_command_registers(hw, &param);

	return 0;
}

static void fjes_hw_cleanup(struct fjes_hw *hw)
{
	int epidx;

	if (!hw->ep_shm_info)
		return;

	fjes_hw_free_shared_status_region(hw);

	kfree(hw->hw_info.req_buf);
	hw->hw_info.req_buf = NULL;

	kfree(hw->hw_info.res_buf);
	hw->hw_info.res_buf = NULL;

	for (epidx = 0; epidx < hw->max_epid ; epidx++) {
		if (epidx == hw->my_epid)
			continue;
		fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx);
		fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx);
	}

	kfree(hw->ep_shm_info);
	hw->ep_shm_info = NULL;
}

int fjes_hw_init(struct fjes_hw *hw)
{
	int ret;

	hw->base = fjes_hw_iomap(hw);
	if (!hw->base)
		return -EIO;

	ret = fjes_hw_reset(hw);
	if (ret)
		return ret;

	fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true);

	INIT_WORK(&hw->update_zone_task, fjes_hw_update_zone_task);
	INIT_WORK(&hw->epstop_task, fjes_hw_epstop_task);

	mutex_init(&hw->hw_info.lock);
	spin_lock_init(&hw->rx_status_lock);

	hw->max_epid = fjes_hw_get_max_epid(hw);
	hw->my_epid = fjes_hw_get_my_epid(hw);

	if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid))
		return -ENXIO;

	ret = fjes_hw_setup(hw);

	hw->hw_info.trace = vzalloc(FJES_DEBUG_BUFFER_SIZE);
	hw->hw_info.trace_size = FJES_DEBUG_BUFFER_SIZE;

	return ret;
}

void fjes_hw_exit(struct fjes_hw *hw)
{
	int ret;

	if (hw->base) {

		if (hw->debug_mode) {
			/* disable debug mode */
			mutex_lock(&hw->hw_info.lock);
			fjes_hw_stop_debug(hw);
			mutex_unlock(&hw->hw_info.lock);
		}
		vfree(hw->hw_info.trace);
		hw->hw_info.trace = NULL;
		hw->hw_info.trace_size = 0;
		hw->debug_mode = 0;

		ret = fjes_hw_reset(hw);
		if (ret)
			pr_err("%s: reset error", __func__);

		fjes_hw_iounmap(hw);
		hw->base = NULL;
	}

	fjes_hw_cleanup(hw);

	cancel_work_sync(&hw->update_zone_task);
	cancel_work_sync(&hw->epstop_task);
}

static enum fjes_dev_command_response_e
fjes_hw_issue_request_command(struct fjes_hw *hw,
			      enum fjes_dev_command_request_type type)
{
	enum fjes_dev_command_response_e ret = FJES_CMD_STATUS_UNKNOWN;
	union REG_CR cr;
	union REG_CS cs;
	int timeout = FJES_COMMAND_REQ_TIMEOUT * 1000;

	cr.reg = 0;
	cr.bits.req_start = 1;
	cr.bits.req_code = type;
	wr32(XSCT_CR, cr.reg);
	cr.reg = rd32(XSCT_CR);

	if (cr.bits.error == 0) {
		timeout = FJES_COMMAND_REQ_TIMEOUT * 1000;
		cs.reg = rd32(XSCT_CS);

		while ((cs.bits.complete != 1) && timeout > 0) {
			msleep(1000);
			cs.reg = rd32(XSCT_CS);
			timeout -= 1000;
		}

		if (cs.bits.complete == 1)
			ret = FJES_CMD_STATUS_NORMAL;
		else if (timeout <= 0)
			ret = FJES_CMD_STATUS_TIMEOUT;

	} else {
		switch (cr.bits.err_info) {
		case FJES_CMD_REQ_ERR_INFO_PARAM:
			ret = FJES_CMD_STATUS_ERROR_PARAM;
			break;
		case FJES_CMD_REQ_ERR_INFO_STATUS:
			ret = FJES_CMD_STATUS_ERROR_STATUS;
			break;
		default:
			ret = FJES_CMD_STATUS_UNKNOWN;
			break;
		}
	}

	trace_fjes_hw_issue_request_command(&cr, &cs, timeout, ret);

	return ret;
}

int fjes_hw_request_info(struct fjes_hw *hw)
{
	union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
	union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
	enum fjes_dev_command_response_e ret;
	int result;

	memset(req_buf, 0, hw->hw_info.req_buf_size);
	memset(res_buf, 0, hw->hw_info.res_buf_size);

	req_buf->info.length = FJES_DEV_COMMAND_INFO_REQ_LEN;

	res_buf->info.length = 0;
	res_buf->info.code = 0;

	ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_INFO);
	trace_fjes_hw_request_info(hw, res_buf);

	result = 0;

	if (FJES_DEV_COMMAND_INFO_RES_LEN((*hw->hw_info.max_epid)) !=
		res_buf->info.length) {
		trace_fjes_hw_request_info_err("Invalid res_buf");
		result = -ENOMSG;
	} else if (ret == FJES_CMD_STATUS_NORMAL) {
		switch (res_buf->info.code) {
		case FJES_CMD_REQ_RES_CODE_NORMAL:
			result = 0;
			break;
		default:
			result = -EPERM;
			break;
		}
	} else {
		switch (ret) {
		case FJES_CMD_STATUS_UNKNOWN:
			result = -EPERM;
			break;
		case FJES_CMD_STATUS_TIMEOUT:
			trace_fjes_hw_request_info_err("Timeout");
			result = -EBUSY;
			break;
		case FJES_CMD_STATUS_ERROR_PARAM:
			result = -EPERM;
			break;
		case FJES_CMD_STATUS_ERROR_STATUS:
			result = -EPERM;
			break;
		default:
			result = -EPERM;
			break;
		}
	}

	return result;
}

int fjes_hw_register_buff_addr(struct fjes_hw *hw, int dest_epid,
			       struct ep_share_mem_info *buf_pair)
{
	union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
	union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
	enum fjes_dev_command_response_e ret;
	int page_count;
	int timeout;
	int i, idx;
	void *addr;
	int result;

	if (test_bit(dest_epid, &hw->hw_info.buffer_share_bit))
		return 0;

	memset(req_buf, 0, hw->hw_info.req_buf_size);
	memset(res_buf, 0, hw->hw_info.res_buf_size);

	req_buf->share_buffer.length = FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(
						buf_pair->tx.size,
						buf_pair->rx.size);
	req_buf->share_buffer.epid = dest_epid;

	idx = 0;
	req_buf->share_buffer.buffer[idx++] = buf_pair->tx.size;
	page_count = buf_pair->tx.size / EP_BUFFER_INFO_SIZE;
	for (i = 0; i < page_count; i++) {
		addr = ((u8 *)(buf_pair->tx.buffer)) +
				(i * EP_BUFFER_INFO_SIZE);
		req_buf->share_buffer.buffer[idx++] =
				(__le64)(page_to_phys(vmalloc_to_page(addr)) +
						offset_in_page(addr));
	}

	req_buf->share_buffer.buffer[idx++] = buf_pair->rx.size;
	page_count = buf_pair->rx.size / EP_BUFFER_INFO_SIZE;
	for (i = 0; i < page_count; i++) {
		addr = ((u8 *)(buf_pair->rx.buffer)) +
				(i * EP_BUFFER_INFO_SIZE);
		req_buf->share_buffer.buffer[idx++] =
				(__le64)(page_to_phys(vmalloc_to_page(addr)) +
						offset_in_page(addr));
	}

	res_buf->share_buffer.length = 0;
	res_buf->share_buffer.code = 0;

	trace_fjes_hw_register_buff_addr_req(req_buf, buf_pair);

	ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_SHARE_BUFFER);

	timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000;
	while ((ret == FJES_CMD_STATUS_NORMAL) &&
	       (res_buf->share_buffer.length ==
		FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) &&
	       (res_buf->share_buffer.code == FJES_CMD_REQ_RES_CODE_BUSY) &&
	       (timeout > 0)) {
			msleep(200 + hw->my_epid * 20);
			timeout -= (200 + hw->my_epid * 20);

			res_buf->share_buffer.length = 0;
			res_buf->share_buffer.code = 0;

			ret = fjes_hw_issue_request_command(
					hw, FJES_CMD_REQ_SHARE_BUFFER);
	}

	result = 0;

	trace_fjes_hw_register_buff_addr(res_buf, timeout);

	if (res_buf->share_buffer.length !=
			FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) {
		trace_fjes_hw_register_buff_addr_err("Invalid res_buf");
		result = -ENOMSG;
	} else if (ret == FJES_CMD_STATUS_NORMAL) {
		switch (res_buf->share_buffer.code) {
		case FJES_CMD_REQ_RES_CODE_NORMAL:
			result = 0;
			set_bit(dest_epid, &hw->hw_info.buffer_share_bit);
			break;
		case FJES_CMD_REQ_RES_CODE_BUSY:
			trace_fjes_hw_register_buff_addr_err("Busy Timeout");
			result = -EBUSY;
			break;
		default:
			result = -EPERM;
			break;
		}
	} else {
		switch (ret) {
		case FJES_CMD_STATUS_UNKNOWN:
			result = -EPERM;
			break;
		case FJES_CMD_STATUS_TIMEOUT:
			trace_fjes_hw_register_buff_addr_err("Timeout");
			result = -EBUSY;
			break;
		case FJES_CMD_STATUS_ERROR_PARAM:
		case FJES_CMD_STATUS_ERROR_STATUS:
		default:
			result = -EPERM;
			break;
		}
	}

	return result;
}

int fjes_hw_unregister_buff_addr(struct fjes_hw *hw, int dest_epid)
{
	union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
	union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
	struct fjes_device_shared_info *share = hw->hw_info.share;
	enum fjes_dev_command_response_e ret;
	int timeout;
	int result;

	if (!hw->base)
		return -EPERM;

	if (!req_buf || !res_buf || !share)
		return -EPERM;

	if (!test_bit(dest_epid, &hw->hw_info.buffer_share_bit))
		return 0;

	memset(req_buf, 0, hw->hw_info.req_buf_size);
	memset(res_buf, 0, hw->hw_info.res_buf_size);

	req_buf->unshare_buffer.length =
			FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN;
	req_buf->unshare_buffer.epid = dest_epid;

	res_buf->unshare_buffer.length = 0;
	res_buf->unshare_buffer.code = 0;

	trace_fjes_hw_unregister_buff_addr_req(req_buf);
	ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER);

	timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000;
	while ((ret == FJES_CMD_STATUS_NORMAL) &&
	       (res_buf->unshare_buffer.length ==
		FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) &&
	       (res_buf->unshare_buffer.code ==
		FJES_CMD_REQ_RES_CODE_BUSY) &&
	       (timeout > 0)) {
		msleep(200 + hw->my_epid * 20);
		timeout -= (200 + hw->my_epid * 20);

		res_buf->unshare_buffer.length = 0;
		res_buf->unshare_buffer.code = 0;

		ret =
		fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER);
	}

	result = 0;

	trace_fjes_hw_unregister_buff_addr(res_buf, timeout);

	if (res_buf->unshare_buffer.length !=
			FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) {
		trace_fjes_hw_unregister_buff_addr_err("Invalid res_buf");
		result = -ENOMSG;
	} else if (ret == FJES_CMD_STATUS_NORMAL) {
		switch (res_buf->unshare_buffer.code) {
		case FJES_CMD_REQ_RES_CODE_NORMAL:
			result = 0;
			clear_bit(dest_epid, &hw->hw_info.buffer_share_bit);
			break;
		case FJES_CMD_REQ_RES_CODE_BUSY:
			trace_fjes_hw_unregister_buff_addr_err("Busy Timeout");
			result = -EBUSY;
			break;
		default:
			result = -EPERM;
			break;
		}
	} else {
		switch (ret) {
		case FJES_CMD_STATUS_UNKNOWN:
			result = -EPERM;
			break;
		case FJES_CMD_STATUS_TIMEOUT:
			trace_fjes_hw_unregister_buff_addr_err("Timeout");
			result = -EBUSY;
			break;
		case FJES_CMD_STATUS_ERROR_PARAM:
		case FJES_CMD_STATUS_ERROR_STATUS:
		default:
			result = -EPERM;
			break;
		}
	}

	return result;
}

int fjes_hw_raise_interrupt(struct fjes_hw *hw, int dest_epid,
			    enum REG_ICTL_MASK  mask)
{
	u32 ig = mask | dest_epid;

	wr32(XSCT_IG, cpu_to_le32(ig));

	return 0;
}

u32 fjes_hw_capture_interrupt_status(struct fjes_hw *hw)
{
	u32 cur_is;

	cur_is = rd32(XSCT_IS);

	return cur_is;
}

void fjes_hw_set_irqmask(struct fjes_hw *hw,
			 enum REG_ICTL_MASK intr_mask, bool mask)
{
	if (mask)
		wr32(XSCT_IMS, intr_mask);
	else
		wr32(XSCT_IMC, intr_mask);
}

bool fjes_hw_epid_is_same_zone(struct fjes_hw *hw, int epid)
{
	if (epid >= hw->max_epid)
		return false;

	if ((hw->ep_shm_info[epid].es_status !=
			FJES_ZONING_STATUS_ENABLE) ||
		(hw->ep_shm_info[hw->my_epid].zone ==
			FJES_ZONING_ZONE_TYPE_NONE))
		return false;
	else
		return (hw->ep_shm_info[epid].zone ==
				hw->ep_shm_info[hw->my_epid].zone);
}

int fjes_hw_epid_is_shared(struct fjes_device_shared_info *share,
			   int dest_epid)
{
	int value = false;

	if (dest_epid < share->epnum)
		value = share->ep_status[dest_epid];

	return value;
}

static bool fjes_hw_epid_is_stop_requested(struct fjes_hw *hw, int src_epid)
{
	return test_bit(src_epid, &hw->txrx_stop_req_bit);
}

static bool fjes_hw_epid_is_stop_process_done(struct fjes_hw *hw, int src_epid)
{
	return (hw->ep_shm_info[src_epid].tx.info->v1i.rx_status &
			FJES_RX_STOP_REQ_DONE);
}

enum ep_partner_status
fjes_hw_get_partner_ep_status(struct fjes_hw *hw, int epid)
{
	enum ep_partner_status status;

	if (fjes_hw_epid_is_shared(hw->hw_info.share, epid)) {
		if (fjes_hw_epid_is_stop_requested(hw, epid)) {
			status = EP_PARTNER_WAITING;
		} else {
			if (fjes_hw_epid_is_stop_process_done(hw, epid))
				status = EP_PARTNER_COMPLETE;
			else
				status = EP_PARTNER_SHARED;
		}
	} else {
		status = EP_PARTNER_UNSHARE;
	}

	return status;
}

void fjes_hw_raise_epstop(struct fjes_hw *hw)
{
	enum ep_partner_status status;
	unsigned long flags;
	int epidx;

	for (epidx = 0; epidx < hw->max_epid; epidx++) {
		if (epidx == hw->my_epid)
			continue;

		status = fjes_hw_get_partner_ep_status(hw, epidx);
		switch (status) {
		case EP_PARTNER_SHARED:
			fjes_hw_raise_interrupt(hw, epidx,
						REG_ICTL_MASK_TXRX_STOP_REQ);
			hw->ep_shm_info[epidx].ep_stats.send_intr_unshare += 1;
			break;
		default:
			break;
		}

		set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
		set_bit(epidx, &hw->txrx_stop_req_bit);

		spin_lock_irqsave(&hw->rx_status_lock, flags);
		hw->ep_shm_info[epidx].tx.info->v1i.rx_status |=
				FJES_RX_STOP_REQ_REQUEST;
		spin_unlock_irqrestore(&hw->rx_status_lock, flags);
	}
}

int fjes_hw_wait_epstop(struct fjes_hw *hw)
{
	enum ep_partner_status status;
	union ep_buffer_info *info;
	int wait_time = 0;
	int epidx;

	while (hw->hw_info.buffer_unshare_reserve_bit &&
	       (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)) {
		for (epidx = 0; epidx < hw->max_epid; epidx++) {
			if (epidx == hw->my_epid)
				continue;
			status = fjes_hw_epid_is_shared(hw->hw_info.share,
							epidx);
			info = hw->ep_shm_info[epidx].rx.info;
			if ((!status ||
			     (info->v1i.rx_status &
			      FJES_RX_STOP_REQ_DONE)) &&
			    test_bit(epidx,
				     &hw->hw_info.buffer_unshare_reserve_bit)) {
				clear_bit(epidx,
					  &hw->hw_info.buffer_unshare_reserve_bit);
			}
		}

		msleep(100);
		wait_time += 100;
	}

	for (epidx = 0; epidx < hw->max_epid; epidx++) {
		if (epidx == hw->my_epid)
			continue;
		if (test_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit))
			clear_bit(epidx,
				  &hw->hw_info.buffer_unshare_reserve_bit);
	}

	return (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)
			? 0 : -EBUSY;
}

bool fjes_hw_check_epbuf_version(struct epbuf_handler *epbh, u32 version)
{
	union ep_buffer_info *info = epbh->info;

	return (info->common.version == version);
}

bool fjes_hw_check_mtu(struct epbuf_handler *epbh, u32 mtu)
{
	union ep_buffer_info *info = epbh->info;

	return ((info->v1i.frame_max == FJES_MTU_TO_FRAME_SIZE(mtu)) &&
		info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE);
}

bool fjes_hw_check_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
{
	union ep_buffer_info *info = epbh->info;
	bool ret = false;
	int i;

	if (vlan_id == 0) {
		ret = true;
	} else {
		for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
			if (vlan_id == info->v1i.vlan_id[i]) {
				ret = true;
				break;
			}
		}
	}
	return ret;
}

bool fjes_hw_set_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
{
	union ep_buffer_info *info = epbh->info;
	int i;

	for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
		if (info->v1i.vlan_id[i] == 0) {
			info->v1i.vlan_id[i] = vlan_id;
			return true;
		}
	}
	return false;
}

void fjes_hw_del_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
{
	union ep_buffer_info *info = epbh->info;
	int i;

	if (0 != vlan_id) {
		for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
			if (vlan_id == info->v1i.vlan_id[i])
				info->v1i.vlan_id[i] = 0;
		}
	}
}

bool fjes_hw_epbuf_rx_is_empty(struct epbuf_handler *epbh)
{
	union ep_buffer_info *info = epbh->info;

	if (!(info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE))
		return true;

	if (info->v1i.count_max == 0)
		return true;

	return EP_RING_EMPTY(info->v1i.head, info->v1i.tail,
			     info->v1i.count_max);
}

void *fjes_hw_epbuf_rx_curpkt_get_addr(struct epbuf_handler *epbh,
				       size_t *psize)
{
	union ep_buffer_info *info = epbh->info;
	struct esmem_frame *ring_frame;
	void *frame;

	ring_frame = (struct esmem_frame *)&(epbh->ring[EP_RING_INDEX
					     (info->v1i.head,
					      info->v1i.count_max) *
					     info->v1i.frame_max]);

	*psize = (size_t)ring_frame->frame_size;

	frame = ring_frame->frame_data;

	return frame;
}

void fjes_hw_epbuf_rx_curpkt_drop(struct epbuf_handler *epbh)
{
	union ep_buffer_info *info = epbh->info;

	if (fjes_hw_epbuf_rx_is_empty(epbh))
		return;

	EP_RING_INDEX_INC(epbh->info->v1i.head, info->v1i.count_max);
}

int fjes_hw_epbuf_tx_pkt_send(struct epbuf_handler *epbh,
			      void *frame, size_t size)
{
	union ep_buffer_info *info = epbh->info;
	struct esmem_frame *ring_frame;

	if (EP_RING_FULL(info->v1i.head, info->v1i.tail, info->v1i.count_max))
		return -ENOBUFS;

	ring_frame = (struct esmem_frame *)&(epbh->ring[EP_RING_INDEX
					     (info->v1i.tail - 1,
					      info->v1i.count_max) *
					     info->v1i.frame_max]);

	ring_frame->frame_size = size;
	memcpy((void *)(ring_frame->frame_data), (void *)frame, size);

	EP_RING_INDEX_INC(epbh->info->v1i.tail, info->v1i.count_max);

	return 0;
}

static void fjes_hw_update_zone_task(struct work_struct *work)
{
	struct fjes_hw *hw = container_of(work,
			struct fjes_hw, update_zone_task);

	struct my_s {u8 es_status; u8 zone; } *info;
	union fjes_device_command_res *res_buf;
	enum ep_partner_status pstatus;

	struct fjes_adapter *adapter;
	struct net_device *netdev;
	unsigned long flags;

	ulong unshare_bit = 0;
	ulong share_bit = 0;
	ulong irq_bit = 0;

	int epidx;
	int ret;

	adapter = (struct fjes_adapter *)hw->back;
	netdev = adapter->netdev;
	res_buf = hw->hw_info.res_buf;
	info = (struct my_s *)&res_buf->info.info;

	mutex_lock(&hw->hw_info.lock);

	ret = fjes_hw_request_info(hw);
	switch (ret) {
	case -ENOMSG:
	case -EBUSY:
	default:
		if (!work_pending(&adapter->force_close_task)) {
			adapter->force_reset = true;
			schedule_work(&adapter->force_close_task);
		}
		break;

	case 0:

		for (epidx = 0; epidx < hw->max_epid; epidx++) {
			if (epidx == hw->my_epid) {
				hw->ep_shm_info[epidx].es_status =
					info[epidx].es_status;
				hw->ep_shm_info[epidx].zone =
					info[epidx].zone;
				continue;
			}

			pstatus = fjes_hw_get_partner_ep_status(hw, epidx);
			switch (pstatus) {
			case EP_PARTNER_UNSHARE:
			default:
				if ((info[epidx].zone !=
					FJES_ZONING_ZONE_TYPE_NONE) &&
				    (info[epidx].es_status ==
					FJES_ZONING_STATUS_ENABLE) &&
				    (info[epidx].zone ==
					info[hw->my_epid].zone))
					set_bit(epidx, &share_bit);
				else
					set_bit(epidx, &unshare_bit);
				break;

			case EP_PARTNER_COMPLETE:
			case EP_PARTNER_WAITING:
				if ((info[epidx].zone ==
					FJES_ZONING_ZONE_TYPE_NONE) ||
				    (info[epidx].es_status !=
					FJES_ZONING_STATUS_ENABLE) ||
				    (info[epidx].zone !=
					info[hw->my_epid].zone)) {
					set_bit(epidx,
						&adapter->unshare_watch_bitmask);
					set_bit(epidx,
						&hw->hw_info.buffer_unshare_reserve_bit);
				}
				break;

			case EP_PARTNER_SHARED:
				if ((info[epidx].zone ==
					FJES_ZONING_ZONE_TYPE_NONE) ||
				    (info[epidx].es_status !=
					FJES_ZONING_STATUS_ENABLE) ||
				    (info[epidx].zone !=
					info[hw->my_epid].zone))
					set_bit(epidx, &irq_bit);
				break;
			}

			hw->ep_shm_info[epidx].es_status =
				info[epidx].es_status;
			hw->ep_shm_info[epidx].zone = info[epidx].zone;
		}
		break;
	}

	mutex_unlock(&hw->hw_info.lock);

	for (epidx = 0; epidx < hw->max_epid; epidx++) {
		if (epidx == hw->my_epid)
			continue;

		if (test_bit(epidx, &share_bit)) {
			spin_lock_irqsave(&hw->rx_status_lock, flags);
			fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
					    netdev->dev_addr, netdev->mtu);
			spin_unlock_irqrestore(&hw->rx_status_lock, flags);

			mutex_lock(&hw->hw_info.lock);

			ret = fjes_hw_register_buff_addr(
				hw, epidx, &hw->ep_shm_info[epidx]);

			switch (ret) {
			case 0:
				break;
			case -ENOMSG:
			case -EBUSY:
			default:
				if (!work_pending(&adapter->force_close_task)) {
					adapter->force_reset = true;
					schedule_work(
					  &adapter->force_close_task);
				}
				break;
			}
			mutex_unlock(&hw->hw_info.lock);

			hw->ep_shm_info[epidx].ep_stats
					      .com_regist_buf_exec += 1;
		}

		if (test_bit(epidx, &unshare_bit)) {
			mutex_lock(&hw->hw_info.lock);

			ret = fjes_hw_unregister_buff_addr(hw, epidx);

			switch (ret) {
			case 0:
				break;
			case -ENOMSG:
			case -EBUSY:
			default:
				if (!work_pending(&adapter->force_close_task)) {
					adapter->force_reset = true;
					schedule_work(
					  &adapter->force_close_task);
				}
				break;
			}

			mutex_unlock(&hw->hw_info.lock);

			hw->ep_shm_info[epidx].ep_stats
					      .com_unregist_buf_exec += 1;

			if (ret == 0) {
				spin_lock_irqsave(&hw->rx_status_lock, flags);
				fjes_hw_setup_epbuf(
					&hw->ep_shm_info[epidx].tx,
					netdev->dev_addr, netdev->mtu);
				spin_unlock_irqrestore(&hw->rx_status_lock,
						       flags);
			}
		}

		if (test_bit(epidx, &irq_bit)) {
			fjes_hw_raise_interrupt(hw, epidx,
						REG_ICTL_MASK_TXRX_STOP_REQ);

			hw->ep_shm_info[epidx].ep_stats.send_intr_unshare += 1;

			set_bit(epidx, &hw->txrx_stop_req_bit);
			spin_lock_irqsave(&hw->rx_status_lock, flags);
			hw->ep_shm_info[epidx].tx.
				info->v1i.rx_status |=
					FJES_RX_STOP_REQ_REQUEST;
			spin_unlock_irqrestore(&hw->rx_status_lock, flags);
			set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
		}
	}

	if (irq_bit || adapter->unshare_watch_bitmask) {
		if (!work_pending(&adapter->unshare_watch_task))
			queue_work(adapter->control_wq,
				   &adapter->unshare_watch_task);
	}
}

static void fjes_hw_epstop_task(struct work_struct *work)
{
	struct fjes_hw *hw = container_of(work, struct fjes_hw, epstop_task);
	struct fjes_adapter *adapter = (struct fjes_adapter *)hw->back;
	unsigned long flags;

	ulong remain_bit;
	int epid_bit;

	while ((remain_bit = hw->epstop_req_bit)) {
		for (epid_bit = 0; remain_bit; remain_bit >>= 1, epid_bit++) {
			if (remain_bit & 1) {
				spin_lock_irqsave(&hw->rx_status_lock, flags);
				hw->ep_shm_info[epid_bit].
					tx.info->v1i.rx_status |=
						FJES_RX_STOP_REQ_DONE;
				spin_unlock_irqrestore(&hw->rx_status_lock,
						       flags);

				clear_bit(epid_bit, &hw->epstop_req_bit);
				set_bit(epid_bit,
					&adapter->unshare_watch_bitmask);

				if (!work_pending(&adapter->unshare_watch_task))
					queue_work(
						adapter->control_wq,
						&adapter->unshare_watch_task);
			}
		}
	}
}

int fjes_hw_start_debug(struct fjes_hw *hw)
{
	union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
	union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
	enum fjes_dev_command_response_e ret;
	int page_count;
	int result = 0;
	void *addr;
	int i;

	if (!hw->hw_info.trace)
		return -EPERM;
	memset(hw->hw_info.trace, 0, FJES_DEBUG_BUFFER_SIZE);

	memset(req_buf, 0, hw->hw_info.req_buf_size);
	memset(res_buf, 0, hw->hw_info.res_buf_size);

	req_buf->start_trace.length =
		FJES_DEV_COMMAND_START_DBG_REQ_LEN(hw->hw_info.trace_size);
	req_buf->start_trace.mode = hw->debug_mode;
	req_buf->start_trace.buffer_len = hw->hw_info.trace_size;
	page_count = hw->hw_info.trace_size / FJES_DEBUG_PAGE_SIZE;
	for (i = 0; i < page_count; i++) {
		addr = ((u8 *)hw->hw_info.trace) + i * FJES_DEBUG_PAGE_SIZE;
		req_buf->start_trace.buffer[i] =
			(__le64)(page_to_phys(vmalloc_to_page(addr)) +
			offset_in_page(addr));
	}

	res_buf->start_trace.length = 0;
	res_buf->start_trace.code = 0;

	trace_fjes_hw_start_debug_req(req_buf);
	ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_START_DEBUG);
	trace_fjes_hw_start_debug(res_buf);

	if (res_buf->start_trace.length !=
		FJES_DEV_COMMAND_START_DBG_RES_LEN) {
		result = -ENOMSG;
		trace_fjes_hw_start_debug_err("Invalid res_buf");
	} else if (ret == FJES_CMD_STATUS_NORMAL) {
		switch (res_buf->start_trace.code) {
		case FJES_CMD_REQ_RES_CODE_NORMAL:
			result = 0;
			break;
		default:
			result = -EPERM;
			break;
		}
	} else {
		switch (ret) {
		case FJES_CMD_STATUS_UNKNOWN:
			result = -EPERM;
			break;
		case FJES_CMD_STATUS_TIMEOUT:
			trace_fjes_hw_start_debug_err("Busy Timeout");
			result = -EBUSY;
			break;
		case FJES_CMD_STATUS_ERROR_PARAM:
		case FJES_CMD_STATUS_ERROR_STATUS:
		default:
			result = -EPERM;
			break;
		}
	}

	return result;
}

int fjes_hw_stop_debug(struct fjes_hw *hw)
{
	union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
	union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
	enum fjes_dev_command_response_e ret;
	int result = 0;

	if (!hw->hw_info.trace)
		return -EPERM;

	memset(req_buf, 0, hw->hw_info.req_buf_size);
	memset(res_buf, 0, hw->hw_info.res_buf_size);
	req_buf->stop_trace.length = FJES_DEV_COMMAND_STOP_DBG_REQ_LEN;

	res_buf->stop_trace.length = 0;
	res_buf->stop_trace.code = 0;

	ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_STOP_DEBUG);
	trace_fjes_hw_stop_debug(res_buf);

	if (res_buf->stop_trace.length != FJES_DEV_COMMAND_STOP_DBG_RES_LEN) {
		trace_fjes_hw_stop_debug_err("Invalid res_buf");
		result = -ENOMSG;
	} else if (ret == FJES_CMD_STATUS_NORMAL) {
		switch (res_buf->stop_trace.code) {
		case FJES_CMD_REQ_RES_CODE_NORMAL:
			result = 0;
			hw->debug_mode = 0;
			break;
		default:
			result = -EPERM;
			break;
		}
	} else {
		switch (ret) {
		case FJES_CMD_STATUS_UNKNOWN:
			result = -EPERM;
			break;
		case FJES_CMD_STATUS_TIMEOUT:
			result = -EBUSY;
			trace_fjes_hw_stop_debug_err("Busy Timeout");
			break;
		case FJES_CMD_STATUS_ERROR_PARAM:
		case FJES_CMD_STATUS_ERROR_STATUS:
		default:
			result = -EPERM;
			break;
		}
	}

	return result;
}
