// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
 * Copyright (c) 2015-2017  QLogic Corporation
 * Copyright (c) 2019-2020 Marvell International Ltd.
 */

#include <linux/types.h>
#include <asm/byteorder.h>
#include <asm/param.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/workqueue.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#define __PREVENT_DUMP_MEM_ARR__
#define __PREVENT_PXP_GLOBAL_WIN__
#include "qed.h"
#include "qed_cxt.h"
#include "qed_dev_api.h"
#include "qed_fcoe.h"
#include "qed_hsi.h"
#include "qed_hw.h"
#include "qed_int.h"
#include "qed_iro_hsi.h"
#include "qed_ll2.h"
#include "qed_mcp.h"
#include "qed_reg_addr.h"
#include "qed_sp.h"
#include "qed_sriov.h"
#include <linux/qed/qed_fcoe_if.h>

struct qed_fcoe_conn {
	struct list_head list_entry;
	bool free_on_delete;

	u16 conn_id;
	u32 icid;
	u32 fw_cid;
	u8 layer_code;

	dma_addr_t sq_pbl_addr;
	dma_addr_t sq_curr_page_addr;
	dma_addr_t sq_next_page_addr;
	dma_addr_t xferq_pbl_addr;
	void *xferq_pbl_addr_virt_addr;
	dma_addr_t xferq_addr[4];
	void *xferq_addr_virt_addr[4];
	dma_addr_t confq_pbl_addr;
	void *confq_pbl_addr_virt_addr;
	dma_addr_t confq_addr[2];
	void *confq_addr_virt_addr[2];

	dma_addr_t terminate_params;

	u16 dst_mac_addr_lo;
	u16 dst_mac_addr_mid;
	u16 dst_mac_addr_hi;
	u16 src_mac_addr_lo;
	u16 src_mac_addr_mid;
	u16 src_mac_addr_hi;

	u16 tx_max_fc_pay_len;
	u16 e_d_tov_timer_val;
	u16 rec_tov_timer_val;
	u16 rx_max_fc_pay_len;
	u16 vlan_tag;
	u16 physical_q0;

	struct fc_addr_nw s_id;
	u8 max_conc_seqs_c3;
	struct fc_addr_nw d_id;
	u8 flags;
	u8 def_q_idx;
};

static int
qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
		       enum spq_mode comp_mode,
		       struct qed_spq_comp_cb *p_comp_addr)
{
	struct qed_fcoe_pf_params *fcoe_pf_params = NULL;
	struct fcoe_init_ramrod_params *p_ramrod = NULL;
	struct fcoe_init_func_ramrod_data *p_data;
	struct fcoe_conn_context *p_cxt = NULL;
	struct qed_spq_entry *p_ent = NULL;
	struct qed_sp_init_data init_data;
	struct qed_cxt_info cxt_info;
	u32 dummy_cid;
	int rc = 0;
	__le16 tmp;
	u8 i;

	/* Get SPQ entry */
	memset(&init_data, 0, sizeof(init_data));
	init_data.cid = qed_spq_get_cid(p_hwfn);
	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
	init_data.comp_mode = comp_mode;
	init_data.p_comp_data = p_comp_addr;

	rc = qed_sp_init_request(p_hwfn, &p_ent,
				 FCOE_RAMROD_CMD_ID_INIT_FUNC,
				 PROTOCOLID_FCOE, &init_data);
	if (rc)
		return rc;

	p_ramrod = &p_ent->ramrod.fcoe_init;
	p_data = &p_ramrod->init_ramrod_data;
	fcoe_pf_params = &p_hwfn->pf_params.fcoe_pf_params;

	/* Sanity */
	if (fcoe_pf_params->num_cqs > p_hwfn->hw_info.feat_num[QED_FCOE_CQ]) {
		DP_ERR(p_hwfn,
		       "Cannot satisfy CQ amount. CQs requested %d, CQs available %d. Aborting function start\n",
		       fcoe_pf_params->num_cqs,
		       p_hwfn->hw_info.feat_num[QED_FCOE_CQ]);
		rc = -EINVAL;
		goto err;
	}

	p_data->mtu = cpu_to_le16(fcoe_pf_params->mtu);
	tmp = cpu_to_le16(fcoe_pf_params->sq_num_pbl_pages);
	p_data->sq_num_pages_in_pbl = tmp;

	rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_FCOE, &dummy_cid);
	if (rc)
		goto err;

	cxt_info.iid = dummy_cid;
	rc = qed_cxt_get_cid_info(p_hwfn, &cxt_info);
	if (rc) {
		DP_NOTICE(p_hwfn, "Cannot find context info for dummy cid=%d\n",
			  dummy_cid);
		goto err;
	}
	p_cxt = cxt_info.p_cxt;
	memset(p_cxt, 0, sizeof(*p_cxt));

	SET_FIELD(p_cxt->tstorm_ag_context.flags3,
		  TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_EN, 1);

	fcoe_pf_params->dummy_icid = (u16)dummy_cid;

	tmp = cpu_to_le16(fcoe_pf_params->num_tasks);
	p_data->func_params.num_tasks = tmp;
	p_data->func_params.log_page_size = fcoe_pf_params->log_page_size;
	p_data->func_params.debug_mode = fcoe_pf_params->debug_mode;

	DMA_REGPAIR_LE(p_data->q_params.glbl_q_params_addr,
		       fcoe_pf_params->glbl_q_params_addr);

	tmp = cpu_to_le16(fcoe_pf_params->cq_num_entries);
	p_data->q_params.cq_num_entries = tmp;

	tmp = cpu_to_le16(fcoe_pf_params->cmdq_num_entries);
	p_data->q_params.cmdq_num_entries = tmp;

	p_data->q_params.num_queues = fcoe_pf_params->num_cqs;

	tmp = (__force __le16)p_hwfn->hw_info.resc_start[QED_CMDQS_CQS];
	p_data->q_params.queue_relative_offset = (__force u8)tmp;

	for (i = 0; i < fcoe_pf_params->num_cqs; i++) {
		tmp = cpu_to_le16(qed_get_igu_sb_id(p_hwfn, i));
		p_data->q_params.cq_cmdq_sb_num_arr[i] = tmp;
	}

	p_data->q_params.cq_sb_pi = fcoe_pf_params->gl_rq_pi;
	p_data->q_params.cmdq_sb_pi = fcoe_pf_params->gl_cmd_pi;

	p_data->q_params.bdq_resource_id = (u8)RESC_START(p_hwfn, QED_BDQ);

	DMA_REGPAIR_LE(p_data->q_params.bdq_pbl_base_address[BDQ_ID_RQ],
		       fcoe_pf_params->bdq_pbl_base_addr[BDQ_ID_RQ]);
	p_data->q_params.bdq_pbl_num_entries[BDQ_ID_RQ] =
	    fcoe_pf_params->bdq_pbl_num_entries[BDQ_ID_RQ];
	tmp = cpu_to_le16(fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_RQ]);
	p_data->q_params.bdq_xoff_threshold[BDQ_ID_RQ] = tmp;
	tmp = cpu_to_le16(fcoe_pf_params->bdq_xon_threshold[BDQ_ID_RQ]);
	p_data->q_params.bdq_xon_threshold[BDQ_ID_RQ] = tmp;

	DMA_REGPAIR_LE(p_data->q_params.bdq_pbl_base_address[BDQ_ID_IMM_DATA],
		       fcoe_pf_params->bdq_pbl_base_addr[BDQ_ID_IMM_DATA]);
	p_data->q_params.bdq_pbl_num_entries[BDQ_ID_IMM_DATA] =
	    fcoe_pf_params->bdq_pbl_num_entries[BDQ_ID_IMM_DATA];
	tmp = cpu_to_le16(fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_IMM_DATA]);
	p_data->q_params.bdq_xoff_threshold[BDQ_ID_IMM_DATA] = tmp;
	tmp = cpu_to_le16(fcoe_pf_params->bdq_xon_threshold[BDQ_ID_IMM_DATA]);
	p_data->q_params.bdq_xon_threshold[BDQ_ID_IMM_DATA] = tmp;
	tmp = cpu_to_le16(fcoe_pf_params->rq_buffer_size);
	p_data->q_params.rq_buffer_size = tmp;

	if (fcoe_pf_params->is_target) {
		SET_FIELD(p_data->q_params.q_validity,
			  SCSI_INIT_FUNC_QUEUES_RQ_VALID, 1);
		if (p_data->q_params.bdq_pbl_num_entries[BDQ_ID_IMM_DATA])
			SET_FIELD(p_data->q_params.q_validity,
				  SCSI_INIT_FUNC_QUEUES_IMM_DATA_VALID, 1);
		SET_FIELD(p_data->q_params.q_validity,
			  SCSI_INIT_FUNC_QUEUES_CMD_VALID, 1);
	} else {
		SET_FIELD(p_data->q_params.q_validity,
			  SCSI_INIT_FUNC_QUEUES_RQ_VALID, 1);
	}

	rc = qed_spq_post(p_hwfn, p_ent, NULL);

	return rc;

err:
	qed_sp_destroy_request(p_hwfn, p_ent);
	return rc;
}

static int
qed_sp_fcoe_conn_offload(struct qed_hwfn *p_hwfn,
			 struct qed_fcoe_conn *p_conn,
			 enum spq_mode comp_mode,
			 struct qed_spq_comp_cb *p_comp_addr)
{
	struct fcoe_conn_offload_ramrod_params *p_ramrod = NULL;
	struct fcoe_conn_offload_ramrod_data *p_data;
	struct qed_spq_entry *p_ent = NULL;
	struct qed_sp_init_data init_data;
	u16 physical_q0;
	__le16 tmp;
	int rc;

	/* Get SPQ entry */
	memset(&init_data, 0, sizeof(init_data));
	init_data.cid = p_conn->icid;
	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
	init_data.comp_mode = comp_mode;
	init_data.p_comp_data = p_comp_addr;

	rc = qed_sp_init_request(p_hwfn, &p_ent,
				 FCOE_RAMROD_CMD_ID_OFFLOAD_CONN,
				 PROTOCOLID_FCOE, &init_data);
	if (rc)
		return rc;

	p_ramrod = &p_ent->ramrod.fcoe_conn_ofld;
	p_data = &p_ramrod->offload_ramrod_data;

	/* Transmission PQ is the first of the PF */
	physical_q0 = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_OFLD);
	p_conn->physical_q0 = physical_q0;
	p_data->physical_q0 = cpu_to_le16(physical_q0);

	p_data->conn_id = cpu_to_le16(p_conn->conn_id);
	DMA_REGPAIR_LE(p_data->sq_pbl_addr, p_conn->sq_pbl_addr);
	DMA_REGPAIR_LE(p_data->sq_curr_page_addr, p_conn->sq_curr_page_addr);
	DMA_REGPAIR_LE(p_data->sq_next_page_addr, p_conn->sq_next_page_addr);
	DMA_REGPAIR_LE(p_data->xferq_pbl_addr, p_conn->xferq_pbl_addr);
	DMA_REGPAIR_LE(p_data->xferq_curr_page_addr, p_conn->xferq_addr[0]);
	DMA_REGPAIR_LE(p_data->xferq_next_page_addr, p_conn->xferq_addr[1]);

	DMA_REGPAIR_LE(p_data->respq_pbl_addr, p_conn->confq_pbl_addr);
	DMA_REGPAIR_LE(p_data->respq_curr_page_addr, p_conn->confq_addr[0]);
	DMA_REGPAIR_LE(p_data->respq_next_page_addr, p_conn->confq_addr[1]);

	p_data->dst_mac_addr_lo = cpu_to_le16(p_conn->dst_mac_addr_lo);
	p_data->dst_mac_addr_mid = cpu_to_le16(p_conn->dst_mac_addr_mid);
	p_data->dst_mac_addr_hi = cpu_to_le16(p_conn->dst_mac_addr_hi);
	p_data->src_mac_addr_lo = cpu_to_le16(p_conn->src_mac_addr_lo);
	p_data->src_mac_addr_mid = cpu_to_le16(p_conn->src_mac_addr_mid);
	p_data->src_mac_addr_hi = cpu_to_le16(p_conn->src_mac_addr_hi);

	tmp = cpu_to_le16(p_conn->tx_max_fc_pay_len);
	p_data->tx_max_fc_pay_len = tmp;
	tmp = cpu_to_le16(p_conn->e_d_tov_timer_val);
	p_data->e_d_tov_timer_val = tmp;
	tmp = cpu_to_le16(p_conn->rec_tov_timer_val);
	p_data->rec_rr_tov_timer_val = tmp;
	tmp = cpu_to_le16(p_conn->rx_max_fc_pay_len);
	p_data->rx_max_fc_pay_len = tmp;

	p_data->vlan_tag = cpu_to_le16(p_conn->vlan_tag);
	p_data->s_id.addr_hi = p_conn->s_id.addr_hi;
	p_data->s_id.addr_mid = p_conn->s_id.addr_mid;
	p_data->s_id.addr_lo = p_conn->s_id.addr_lo;
	p_data->max_conc_seqs_c3 = p_conn->max_conc_seqs_c3;
	p_data->d_id.addr_hi = p_conn->d_id.addr_hi;
	p_data->d_id.addr_mid = p_conn->d_id.addr_mid;
	p_data->d_id.addr_lo = p_conn->d_id.addr_lo;
	p_data->flags = p_conn->flags;
	if (test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits))
		SET_FIELD(p_data->flags,
			  FCOE_CONN_OFFLOAD_RAMROD_DATA_B_SINGLE_VLAN, 1);
	p_data->def_q_idx = p_conn->def_q_idx;

	return qed_spq_post(p_hwfn, p_ent, NULL);
}

static int
qed_sp_fcoe_conn_destroy(struct qed_hwfn *p_hwfn,
			 struct qed_fcoe_conn *p_conn,
			 enum spq_mode comp_mode,
			 struct qed_spq_comp_cb *p_comp_addr)
{
	struct fcoe_conn_terminate_ramrod_params *p_ramrod = NULL;
	struct qed_spq_entry *p_ent = NULL;
	struct qed_sp_init_data init_data;
	int rc = 0;

	/* Get SPQ entry */
	memset(&init_data, 0, sizeof(init_data));
	init_data.cid = p_conn->icid;
	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
	init_data.comp_mode = comp_mode;
	init_data.p_comp_data = p_comp_addr;

	rc = qed_sp_init_request(p_hwfn, &p_ent,
				 FCOE_RAMROD_CMD_ID_TERMINATE_CONN,
				 PROTOCOLID_FCOE, &init_data);
	if (rc)
		return rc;

	p_ramrod = &p_ent->ramrod.fcoe_conn_terminate;
	DMA_REGPAIR_LE(p_ramrod->terminate_ramrod_data.terminate_params_addr,
		       p_conn->terminate_params);

	return qed_spq_post(p_hwfn, p_ent, NULL);
}

static int
qed_sp_fcoe_func_stop(struct qed_hwfn *p_hwfn,
		      struct qed_ptt *p_ptt,
		      enum spq_mode comp_mode,
		      struct qed_spq_comp_cb *p_comp_addr)
{
	struct qed_spq_entry *p_ent = NULL;
	struct qed_sp_init_data init_data;
	u32 active_segs = 0;
	int rc = 0;

	/* Get SPQ entry */
	memset(&init_data, 0, sizeof(init_data));
	init_data.cid = p_hwfn->pf_params.fcoe_pf_params.dummy_icid;
	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
	init_data.comp_mode = comp_mode;
	init_data.p_comp_data = p_comp_addr;

	rc = qed_sp_init_request(p_hwfn, &p_ent,
				 FCOE_RAMROD_CMD_ID_DESTROY_FUNC,
				 PROTOCOLID_FCOE, &init_data);
	if (rc)
		return rc;

	active_segs = qed_rd(p_hwfn, p_ptt, TM_REG_PF_ENABLE_TASK);
	active_segs &= ~BIT(QED_CXT_FCOE_TID_SEG);
	qed_wr(p_hwfn, p_ptt, TM_REG_PF_ENABLE_TASK, active_segs);

	return qed_spq_post(p_hwfn, p_ent, NULL);
}

static int
qed_fcoe_allocate_connection(struct qed_hwfn *p_hwfn,
			     struct qed_fcoe_conn **p_out_conn)
{
	struct qed_fcoe_conn *p_conn = NULL;
	void *p_addr;
	u32 i;

	spin_lock_bh(&p_hwfn->p_fcoe_info->lock);
	if (!list_empty(&p_hwfn->p_fcoe_info->free_list))
		p_conn =
		    list_first_entry(&p_hwfn->p_fcoe_info->free_list,
				     struct qed_fcoe_conn, list_entry);
	if (p_conn) {
		list_del(&p_conn->list_entry);
		spin_unlock_bh(&p_hwfn->p_fcoe_info->lock);
		*p_out_conn = p_conn;
		return 0;
	}
	spin_unlock_bh(&p_hwfn->p_fcoe_info->lock);

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

	p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
				    QED_CHAIN_PAGE_SIZE,
				    &p_conn->xferq_pbl_addr, GFP_KERNEL);
	if (!p_addr)
		goto nomem_pbl_xferq;
	p_conn->xferq_pbl_addr_virt_addr = p_addr;

	for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) {
		p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
					    QED_CHAIN_PAGE_SIZE,
					    &p_conn->xferq_addr[i], GFP_KERNEL);
		if (!p_addr)
			goto nomem_xferq;
		p_conn->xferq_addr_virt_addr[i] = p_addr;

		p_addr = p_conn->xferq_pbl_addr_virt_addr;
		((dma_addr_t *)p_addr)[i] = p_conn->xferq_addr[i];
	}

	p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
				    QED_CHAIN_PAGE_SIZE,
				    &p_conn->confq_pbl_addr, GFP_KERNEL);
	if (!p_addr)
		goto nomem_xferq;
	p_conn->confq_pbl_addr_virt_addr = p_addr;

	for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) {
		p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
					    QED_CHAIN_PAGE_SIZE,
					    &p_conn->confq_addr[i], GFP_KERNEL);
		if (!p_addr)
			goto nomem_confq;
		p_conn->confq_addr_virt_addr[i] = p_addr;

		p_addr = p_conn->confq_pbl_addr_virt_addr;
		((dma_addr_t *)p_addr)[i] = p_conn->confq_addr[i];
	}

	p_conn->free_on_delete = true;
	*p_out_conn = p_conn;
	return 0;

nomem_confq:
	dma_free_coherent(&p_hwfn->cdev->pdev->dev,
			  QED_CHAIN_PAGE_SIZE,
			  p_conn->confq_pbl_addr_virt_addr,
			  p_conn->confq_pbl_addr);
	for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++)
		if (p_conn->confq_addr_virt_addr[i])
			dma_free_coherent(&p_hwfn->cdev->pdev->dev,
					  QED_CHAIN_PAGE_SIZE,
					  p_conn->confq_addr_virt_addr[i],
					  p_conn->confq_addr[i]);
nomem_xferq:
	dma_free_coherent(&p_hwfn->cdev->pdev->dev,
			  QED_CHAIN_PAGE_SIZE,
			  p_conn->xferq_pbl_addr_virt_addr,
			  p_conn->xferq_pbl_addr);
	for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++)
		if (p_conn->xferq_addr_virt_addr[i])
			dma_free_coherent(&p_hwfn->cdev->pdev->dev,
					  QED_CHAIN_PAGE_SIZE,
					  p_conn->xferq_addr_virt_addr[i],
					  p_conn->xferq_addr[i]);
nomem_pbl_xferq:
	kfree(p_conn);
	return -ENOMEM;
}

static void qed_fcoe_free_connection(struct qed_hwfn *p_hwfn,
				     struct qed_fcoe_conn *p_conn)
{
	u32 i;

	if (!p_conn)
		return;

	if (p_conn->confq_pbl_addr_virt_addr)
		dma_free_coherent(&p_hwfn->cdev->pdev->dev,
				  QED_CHAIN_PAGE_SIZE,
				  p_conn->confq_pbl_addr_virt_addr,
				  p_conn->confq_pbl_addr);

	for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) {
		if (!p_conn->confq_addr_virt_addr[i])
			continue;
		dma_free_coherent(&p_hwfn->cdev->pdev->dev,
				  QED_CHAIN_PAGE_SIZE,
				  p_conn->confq_addr_virt_addr[i],
				  p_conn->confq_addr[i]);
	}

	if (p_conn->xferq_pbl_addr_virt_addr)
		dma_free_coherent(&p_hwfn->cdev->pdev->dev,
				  QED_CHAIN_PAGE_SIZE,
				  p_conn->xferq_pbl_addr_virt_addr,
				  p_conn->xferq_pbl_addr);

	for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) {
		if (!p_conn->xferq_addr_virt_addr[i])
			continue;
		dma_free_coherent(&p_hwfn->cdev->pdev->dev,
				  QED_CHAIN_PAGE_SIZE,
				  p_conn->xferq_addr_virt_addr[i],
				  p_conn->xferq_addr[i]);
	}
	kfree(p_conn);
}

static void __iomem *qed_fcoe_get_db_addr(struct qed_hwfn *p_hwfn, u32 cid)
{
	return (u8 __iomem *)p_hwfn->doorbells +
	       qed_db_addr(cid, DQ_DEMS_LEGACY);
}

static void __iomem *qed_fcoe_get_primary_bdq_prod(struct qed_hwfn *p_hwfn,
						   u8 bdq_id)
{
	if (RESC_NUM(p_hwfn, QED_BDQ)) {
		return (u8 __iomem *)p_hwfn->regview +
		    GET_GTT_BDQ_REG_ADDR(GTT_BAR0_MAP_REG_MSDM_RAM,
					 MSTORM_SCSI_BDQ_EXT_PROD,
					 RESC_START(p_hwfn, QED_BDQ), bdq_id);
	} else {
		DP_NOTICE(p_hwfn, "BDQ is not allocated!\n");
		return NULL;
	}
}

static void __iomem *qed_fcoe_get_secondary_bdq_prod(struct qed_hwfn *p_hwfn,
						     u8 bdq_id)
{
	if (RESC_NUM(p_hwfn, QED_BDQ)) {
		return (u8 __iomem *)p_hwfn->regview +
		    GET_GTT_BDQ_REG_ADDR(GTT_BAR0_MAP_REG_TSDM_RAM,
					 TSTORM_SCSI_BDQ_EXT_PROD,
					 RESC_START(p_hwfn, QED_BDQ), bdq_id);
	} else {
		DP_NOTICE(p_hwfn, "BDQ is not allocated!\n");
		return NULL;
	}
}

int qed_fcoe_alloc(struct qed_hwfn *p_hwfn)
{
	struct qed_fcoe_info *p_fcoe_info;

	/* Allocate LL2's set struct */
	p_fcoe_info = kzalloc(sizeof(*p_fcoe_info), GFP_KERNEL);
	if (!p_fcoe_info) {
		DP_NOTICE(p_hwfn, "Failed to allocate qed_fcoe_info'\n");
		return -ENOMEM;
	}
	INIT_LIST_HEAD(&p_fcoe_info->free_list);

	p_hwfn->p_fcoe_info = p_fcoe_info;
	return 0;
}

void qed_fcoe_setup(struct qed_hwfn *p_hwfn)
{
	struct fcoe_task_context *p_task_ctx = NULL;
	u32 i, lc;
	int rc;

	spin_lock_init(&p_hwfn->p_fcoe_info->lock);
	for (i = 0; i < p_hwfn->pf_params.fcoe_pf_params.num_tasks; i++) {
		rc = qed_cxt_get_task_ctx(p_hwfn, i,
					  QED_CTX_WORKING_MEM,
					  (void **)&p_task_ctx);
		if (rc)
			continue;

		memset(p_task_ctx, 0, sizeof(struct fcoe_task_context));

		lc = 0;
		SET_FIELD(lc, TIMERS_CONTEXT_VALIDLC0, 1);
		p_task_ctx->timer_context.logical_client_0 = cpu_to_le32(lc);

		lc = 0;
		SET_FIELD(lc, TIMERS_CONTEXT_VALIDLC1, 1);
		p_task_ctx->timer_context.logical_client_1 = cpu_to_le32(lc);

		SET_FIELD(p_task_ctx->tstorm_ag_context.flags0,
			  TSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE, 1);
	}
}

void qed_fcoe_free(struct qed_hwfn *p_hwfn)
{
	struct qed_fcoe_conn *p_conn = NULL;

	if (!p_hwfn->p_fcoe_info)
		return;

	while (!list_empty(&p_hwfn->p_fcoe_info->free_list)) {
		p_conn = list_first_entry(&p_hwfn->p_fcoe_info->free_list,
					  struct qed_fcoe_conn, list_entry);
		if (!p_conn)
			break;
		list_del(&p_conn->list_entry);
		qed_fcoe_free_connection(p_hwfn, p_conn);
	}

	kfree(p_hwfn->p_fcoe_info);
	p_hwfn->p_fcoe_info = NULL;
}

static int
qed_fcoe_acquire_connection(struct qed_hwfn *p_hwfn,
			    struct qed_fcoe_conn *p_in_conn,
			    struct qed_fcoe_conn **p_out_conn)
{
	struct qed_fcoe_conn *p_conn = NULL;
	int rc = 0;
	u32 icid;

	spin_lock_bh(&p_hwfn->p_fcoe_info->lock);
	rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_FCOE, &icid);
	spin_unlock_bh(&p_hwfn->p_fcoe_info->lock);
	if (rc)
		return rc;

	/* Use input connection [if provided] or allocate a new one */
	if (p_in_conn) {
		p_conn = p_in_conn;
	} else {
		rc = qed_fcoe_allocate_connection(p_hwfn, &p_conn);
		if (rc) {
			spin_lock_bh(&p_hwfn->p_fcoe_info->lock);
			qed_cxt_release_cid(p_hwfn, icid);
			spin_unlock_bh(&p_hwfn->p_fcoe_info->lock);
			return rc;
		}
	}

	p_conn->icid = icid;
	p_conn->fw_cid = (p_hwfn->hw_info.opaque_fid << 16) | icid;
	*p_out_conn = p_conn;

	return rc;
}

static void qed_fcoe_release_connection(struct qed_hwfn *p_hwfn,
					struct qed_fcoe_conn *p_conn)
{
	spin_lock_bh(&p_hwfn->p_fcoe_info->lock);
	list_add_tail(&p_conn->list_entry, &p_hwfn->p_fcoe_info->free_list);
	qed_cxt_release_cid(p_hwfn, p_conn->icid);
	spin_unlock_bh(&p_hwfn->p_fcoe_info->lock);
}

static void _qed_fcoe_get_tstats(struct qed_hwfn *p_hwfn,
				 struct qed_ptt *p_ptt,
				 struct qed_fcoe_stats *p_stats)
{
	struct fcoe_rx_stat tstats;
	u32 tstats_addr;

	memset(&tstats, 0, sizeof(tstats));
	tstats_addr = BAR0_MAP_REG_TSDM_RAM +
	    TSTORM_FCOE_RX_STATS_OFFSET(p_hwfn->rel_pf_id);
	qed_memcpy_from(p_hwfn, p_ptt, &tstats, tstats_addr, sizeof(tstats));

	p_stats->fcoe_rx_byte_cnt = HILO_64_REGPAIR(tstats.fcoe_rx_byte_cnt);
	p_stats->fcoe_rx_data_pkt_cnt =
	    HILO_64_REGPAIR(tstats.fcoe_rx_data_pkt_cnt);
	p_stats->fcoe_rx_xfer_pkt_cnt =
	    HILO_64_REGPAIR(tstats.fcoe_rx_xfer_pkt_cnt);
	p_stats->fcoe_rx_other_pkt_cnt =
	    HILO_64_REGPAIR(tstats.fcoe_rx_other_pkt_cnt);

	p_stats->fcoe_silent_drop_pkt_cmdq_full_cnt =
	    le32_to_cpu(tstats.fcoe_silent_drop_pkt_cmdq_full_cnt);
	p_stats->fcoe_silent_drop_pkt_rq_full_cnt =
	    le32_to_cpu(tstats.fcoe_silent_drop_pkt_rq_full_cnt);
	p_stats->fcoe_silent_drop_pkt_crc_error_cnt =
	    le32_to_cpu(tstats.fcoe_silent_drop_pkt_crc_error_cnt);
	p_stats->fcoe_silent_drop_pkt_task_invalid_cnt =
	    le32_to_cpu(tstats.fcoe_silent_drop_pkt_task_invalid_cnt);
	p_stats->fcoe_silent_drop_total_pkt_cnt =
	    le32_to_cpu(tstats.fcoe_silent_drop_total_pkt_cnt);
}

static void _qed_fcoe_get_pstats(struct qed_hwfn *p_hwfn,
				 struct qed_ptt *p_ptt,
				 struct qed_fcoe_stats *p_stats)
{
	struct fcoe_tx_stat pstats;
	u32 pstats_addr;

	memset(&pstats, 0, sizeof(pstats));
	pstats_addr = BAR0_MAP_REG_PSDM_RAM +
	    PSTORM_FCOE_TX_STATS_OFFSET(p_hwfn->rel_pf_id);
	qed_memcpy_from(p_hwfn, p_ptt, &pstats, pstats_addr, sizeof(pstats));

	p_stats->fcoe_tx_byte_cnt = HILO_64_REGPAIR(pstats.fcoe_tx_byte_cnt);
	p_stats->fcoe_tx_data_pkt_cnt =
	    HILO_64_REGPAIR(pstats.fcoe_tx_data_pkt_cnt);
	p_stats->fcoe_tx_xfer_pkt_cnt =
	    HILO_64_REGPAIR(pstats.fcoe_tx_xfer_pkt_cnt);
	p_stats->fcoe_tx_other_pkt_cnt =
	    HILO_64_REGPAIR(pstats.fcoe_tx_other_pkt_cnt);
}

static int qed_fcoe_get_stats(struct qed_hwfn *p_hwfn,
			      struct qed_fcoe_stats *p_stats)
{
	struct qed_ptt *p_ptt;

	memset(p_stats, 0, sizeof(*p_stats));

	p_ptt = qed_ptt_acquire(p_hwfn);

	if (!p_ptt) {
		DP_ERR(p_hwfn, "Failed to acquire ptt\n");
		return -EINVAL;
	}

	_qed_fcoe_get_tstats(p_hwfn, p_ptt, p_stats);
	_qed_fcoe_get_pstats(p_hwfn, p_ptt, p_stats);

	qed_ptt_release(p_hwfn, p_ptt);

	return 0;
}

struct qed_hash_fcoe_con {
	struct hlist_node node;
	struct qed_fcoe_conn *con;
};

static int qed_fill_fcoe_dev_info(struct qed_dev *cdev,
				  struct qed_dev_fcoe_info *info)
{
	struct qed_hwfn *hwfn = QED_AFFIN_HWFN(cdev);
	int rc;

	memset(info, 0, sizeof(*info));
	rc = qed_fill_dev_info(cdev, &info->common);

	info->primary_dbq_rq_addr =
	    qed_fcoe_get_primary_bdq_prod(hwfn, BDQ_ID_RQ);
	info->secondary_bdq_rq_addr =
	    qed_fcoe_get_secondary_bdq_prod(hwfn, BDQ_ID_RQ);

	info->wwpn = hwfn->mcp_info->func_info.wwn_port;
	info->wwnn = hwfn->mcp_info->func_info.wwn_node;

	info->num_cqs = FEAT_NUM(hwfn, QED_FCOE_CQ);

	return rc;
}

static void qed_register_fcoe_ops(struct qed_dev *cdev,
				  struct qed_fcoe_cb_ops *ops, void *cookie)
{
	cdev->protocol_ops.fcoe = ops;
	cdev->ops_cookie = cookie;
}

static struct qed_hash_fcoe_con *qed_fcoe_get_hash(struct qed_dev *cdev,
						   u32 handle)
{
	struct qed_hash_fcoe_con *hash_con = NULL;

	if (!(cdev->flags & QED_FLAG_STORAGE_STARTED))
		return NULL;

	hash_for_each_possible(cdev->connections, hash_con, node, handle) {
		if (hash_con->con->icid == handle)
			break;
	}

	if (!hash_con || (hash_con->con->icid != handle))
		return NULL;

	return hash_con;
}

static int qed_fcoe_stop(struct qed_dev *cdev)
{
	struct qed_ptt *p_ptt;
	int rc;

	if (!(cdev->flags & QED_FLAG_STORAGE_STARTED)) {
		DP_NOTICE(cdev, "fcoe already stopped\n");
		return 0;
	}

	if (!hash_empty(cdev->connections)) {
		DP_NOTICE(cdev,
			  "Can't stop fcoe - not all connections were returned\n");
		return -EINVAL;
	}

	p_ptt = qed_ptt_acquire(QED_AFFIN_HWFN(cdev));
	if (!p_ptt)
		return -EAGAIN;

	/* Stop the fcoe */
	rc = qed_sp_fcoe_func_stop(QED_AFFIN_HWFN(cdev), p_ptt,
				   QED_SPQ_MODE_EBLOCK, NULL);
	cdev->flags &= ~QED_FLAG_STORAGE_STARTED;
	qed_ptt_release(QED_AFFIN_HWFN(cdev), p_ptt);

	return rc;
}

static int qed_fcoe_start(struct qed_dev *cdev, struct qed_fcoe_tid *tasks)
{
	int rc;

	if (cdev->flags & QED_FLAG_STORAGE_STARTED) {
		DP_NOTICE(cdev, "fcoe already started;\n");
		return 0;
	}

	rc = qed_sp_fcoe_func_start(QED_AFFIN_HWFN(cdev), QED_SPQ_MODE_EBLOCK,
				    NULL);
	if (rc) {
		DP_NOTICE(cdev, "Failed to start fcoe\n");
		return rc;
	}

	cdev->flags |= QED_FLAG_STORAGE_STARTED;
	hash_init(cdev->connections);

	if (tasks) {
		struct qed_tid_mem *tid_info = kzalloc(sizeof(*tid_info),
						       GFP_ATOMIC);

		if (!tid_info) {
			DP_NOTICE(cdev,
				  "Failed to allocate tasks information\n");
			qed_fcoe_stop(cdev);
			return -ENOMEM;
		}

		rc = qed_cxt_get_tid_mem_info(QED_AFFIN_HWFN(cdev), tid_info);
		if (rc) {
			DP_NOTICE(cdev, "Failed to gather task information\n");
			qed_fcoe_stop(cdev);
			kfree(tid_info);
			return rc;
		}

		/* Fill task information */
		tasks->size = tid_info->tid_size;
		tasks->num_tids_per_block = tid_info->num_tids_per_block;
		memcpy(tasks->blocks, tid_info->blocks,
		       MAX_TID_BLOCKS_FCOE * sizeof(u8 *));

		kfree(tid_info);
	}

	return 0;
}

static int qed_fcoe_acquire_conn(struct qed_dev *cdev,
				 u32 *handle,
				 u32 *fw_cid, void __iomem **p_doorbell)
{
	struct qed_hash_fcoe_con *hash_con;
	int rc;

	/* Allocate a hashed connection */
	hash_con = kzalloc(sizeof(*hash_con), GFP_KERNEL);
	if (!hash_con) {
		DP_NOTICE(cdev, "Failed to allocate hashed connection\n");
		return -ENOMEM;
	}

	/* Acquire the connection */
	rc = qed_fcoe_acquire_connection(QED_AFFIN_HWFN(cdev), NULL,
					 &hash_con->con);
	if (rc) {
		DP_NOTICE(cdev, "Failed to acquire Connection\n");
		kfree(hash_con);
		return rc;
	}

	/* Added the connection to hash table */
	*handle = hash_con->con->icid;
	*fw_cid = hash_con->con->fw_cid;
	hash_add(cdev->connections, &hash_con->node, *handle);

	if (p_doorbell)
		*p_doorbell = qed_fcoe_get_db_addr(QED_AFFIN_HWFN(cdev),
						   *handle);

	return 0;
}

static int qed_fcoe_release_conn(struct qed_dev *cdev, u32 handle)
{
	struct qed_hash_fcoe_con *hash_con;

	hash_con = qed_fcoe_get_hash(cdev, handle);
	if (!hash_con) {
		DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
			  handle);
		return -EINVAL;
	}

	hlist_del(&hash_con->node);
	qed_fcoe_release_connection(QED_AFFIN_HWFN(cdev), hash_con->con);
	kfree(hash_con);

	return 0;
}

static int qed_fcoe_offload_conn(struct qed_dev *cdev,
				 u32 handle,
				 struct qed_fcoe_params_offload *conn_info)
{
	struct qed_hash_fcoe_con *hash_con;
	struct qed_fcoe_conn *con;

	hash_con = qed_fcoe_get_hash(cdev, handle);
	if (!hash_con) {
		DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
			  handle);
		return -EINVAL;
	}

	/* Update the connection with information from the params */
	con = hash_con->con;

	con->sq_pbl_addr = conn_info->sq_pbl_addr;
	con->sq_curr_page_addr = conn_info->sq_curr_page_addr;
	con->sq_next_page_addr = conn_info->sq_next_page_addr;
	con->tx_max_fc_pay_len = conn_info->tx_max_fc_pay_len;
	con->e_d_tov_timer_val = conn_info->e_d_tov_timer_val;
	con->rec_tov_timer_val = conn_info->rec_tov_timer_val;
	con->rx_max_fc_pay_len = conn_info->rx_max_fc_pay_len;
	con->vlan_tag = conn_info->vlan_tag;
	con->max_conc_seqs_c3 = conn_info->max_conc_seqs_c3;
	con->flags = conn_info->flags;
	con->def_q_idx = conn_info->def_q_idx;

	con->src_mac_addr_hi = (conn_info->src_mac[5] << 8) |
	    conn_info->src_mac[4];
	con->src_mac_addr_mid = (conn_info->src_mac[3] << 8) |
	    conn_info->src_mac[2];
	con->src_mac_addr_lo = (conn_info->src_mac[1] << 8) |
	    conn_info->src_mac[0];
	con->dst_mac_addr_hi = (conn_info->dst_mac[5] << 8) |
	    conn_info->dst_mac[4];
	con->dst_mac_addr_mid = (conn_info->dst_mac[3] << 8) |
	    conn_info->dst_mac[2];
	con->dst_mac_addr_lo = (conn_info->dst_mac[1] << 8) |
	    conn_info->dst_mac[0];

	con->s_id.addr_hi = conn_info->s_id.addr_hi;
	con->s_id.addr_mid = conn_info->s_id.addr_mid;
	con->s_id.addr_lo = conn_info->s_id.addr_lo;
	con->d_id.addr_hi = conn_info->d_id.addr_hi;
	con->d_id.addr_mid = conn_info->d_id.addr_mid;
	con->d_id.addr_lo = conn_info->d_id.addr_lo;

	return qed_sp_fcoe_conn_offload(QED_AFFIN_HWFN(cdev), con,
					QED_SPQ_MODE_EBLOCK, NULL);
}

static int qed_fcoe_destroy_conn(struct qed_dev *cdev,
				 u32 handle, dma_addr_t terminate_params)
{
	struct qed_hash_fcoe_con *hash_con;
	struct qed_fcoe_conn *con;

	hash_con = qed_fcoe_get_hash(cdev, handle);
	if (!hash_con) {
		DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
			  handle);
		return -EINVAL;
	}

	/* Update the connection with information from the params */
	con = hash_con->con;
	con->terminate_params = terminate_params;

	return qed_sp_fcoe_conn_destroy(QED_AFFIN_HWFN(cdev), con,
					QED_SPQ_MODE_EBLOCK, NULL);
}

static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats)
{
	return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats);
}

void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
				 struct qed_mcp_fcoe_stats *stats)
{
	struct qed_fcoe_stats proto_stats;

	/* Retrieve FW statistics */
	memset(&proto_stats, 0, sizeof(proto_stats));
	if (qed_fcoe_stats(cdev, &proto_stats)) {
		DP_VERBOSE(cdev, QED_MSG_STORAGE,
			   "Failed to collect FCoE statistics\n");
		return;
	}

	/* Translate FW statistics into struct */
	stats->rx_pkts = proto_stats.fcoe_rx_data_pkt_cnt +
			 proto_stats.fcoe_rx_xfer_pkt_cnt +
			 proto_stats.fcoe_rx_other_pkt_cnt;
	stats->tx_pkts = proto_stats.fcoe_tx_data_pkt_cnt +
			 proto_stats.fcoe_tx_xfer_pkt_cnt +
			 proto_stats.fcoe_tx_other_pkt_cnt;
	stats->fcs_err = proto_stats.fcoe_silent_drop_pkt_crc_error_cnt;

	/* Request protocol driver to fill-in the rest */
	if (cdev->protocol_ops.fcoe && cdev->ops_cookie) {
		struct qed_fcoe_cb_ops *ops = cdev->protocol_ops.fcoe;
		void *cookie = cdev->ops_cookie;

		if (ops->get_login_failures)
			stats->login_failure = ops->get_login_failures(cookie);
	}
}

static const struct qed_fcoe_ops qed_fcoe_ops_pass = {
	.common = &qed_common_ops_pass,
	.ll2 = &qed_ll2_ops_pass,
	.fill_dev_info = &qed_fill_fcoe_dev_info,
	.start = &qed_fcoe_start,
	.stop = &qed_fcoe_stop,
	.register_ops = &qed_register_fcoe_ops,
	.acquire_conn = &qed_fcoe_acquire_conn,
	.release_conn = &qed_fcoe_release_conn,
	.offload_conn = &qed_fcoe_offload_conn,
	.destroy_conn = &qed_fcoe_destroy_conn,
	.get_stats = &qed_fcoe_stats,
};

const struct qed_fcoe_ops *qed_get_fcoe_ops(void)
{
	return &qed_fcoe_ops_pass;
}
EXPORT_SYMBOL(qed_get_fcoe_ops);

void qed_put_fcoe_ops(void)
{
}
EXPORT_SYMBOL(qed_put_fcoe_ops);
