// SPDX-License-Identifier: GPL-2.0
/*  Marvell RPM CN10K driver
 *
 * Copyright (C) 2020 Marvell.
 */

#include <linux/bitfield.h>
#include <linux/pci.h>
#include "rvu.h"
#include "cgx.h"
#include "rvu_reg.h"

/* RVU LMTST */
#define LMT_TBL_OP_READ		0
#define LMT_TBL_OP_WRITE	1
#define LMT_MAP_TABLE_SIZE	(128 * 1024)
#define LMT_MAPTBL_ENTRY_SIZE	16

/* Function to perform operations (read/write) on lmtst map table */
static int lmtst_map_table_ops(struct rvu *rvu, u32 index, u64 *val,
			       int lmt_tbl_op)
{
	void __iomem *lmt_map_base;
	u64 tbl_base;

	tbl_base = rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_MAP_BASE);

	lmt_map_base = ioremap_wc(tbl_base, LMT_MAP_TABLE_SIZE);
	if (!lmt_map_base) {
		dev_err(rvu->dev, "Failed to setup lmt map table mapping!!\n");
		return -ENOMEM;
	}

	if (lmt_tbl_op == LMT_TBL_OP_READ) {
		*val = readq(lmt_map_base + index);
	} else {
		writeq((*val), (lmt_map_base + index));
		/* Flushing the AP interceptor cache to make APR_LMT_MAP_ENTRY_S
		 * changes effective. Write 1 for flush and read is being used as a
		 * barrier and sets up a data dependency. Write to 0 after a write
		 * to 1 to complete the flush.
		 */
		rvu_write64(rvu, BLKADDR_APR, APR_AF_LMT_CTL, BIT_ULL(0));
		rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_CTL);
		rvu_write64(rvu, BLKADDR_APR, APR_AF_LMT_CTL, 0x00);
	}

	iounmap(lmt_map_base);
	return 0;
}

static u32 rvu_get_lmtst_tbl_index(struct rvu *rvu, u16 pcifunc)
{
	return ((rvu_get_pf(pcifunc) * rvu->hw->total_vfs) +
		(pcifunc & RVU_PFVF_FUNC_MASK)) * LMT_MAPTBL_ENTRY_SIZE;
}

static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
			   u64 iova, u64 *lmt_addr)
{
	u64 pa, val, pf;
	int err;

	if (!iova) {
		dev_err(rvu->dev, "%s Requested Null address for transulation\n", __func__);
		return -EINVAL;
	}

	rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_REQ, iova);
	pf = rvu_get_pf(pcifunc) & 0x1F;
	val = BIT_ULL(63) | BIT_ULL(14) | BIT_ULL(13) | pf << 8 |
	      ((pcifunc & RVU_PFVF_FUNC_MASK) & 0xFF);
	rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TXN_REQ, val);

	err = rvu_poll_reg(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS, BIT_ULL(0), false);
	if (err) {
		dev_err(rvu->dev, "%s LMTLINE iova transulation failed\n", __func__);
		return err;
	}
	val = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS);
	if (val & ~0x1ULL) {
		dev_err(rvu->dev, "%s LMTLINE iova transulation failed err:%llx\n", __func__, val);
		return -EIO;
	}
	/* PA[51:12] = RVU_AF_SMMU_TLN_FLIT1[60:21]
	 * PA[11:0] = IOVA[11:0]
	 */
	pa = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TLN_FLIT1) >> 21;
	pa &= GENMASK_ULL(39, 0);
	*lmt_addr = (pa << 12) | (iova  & 0xFFF);

	return 0;
}

static int rvu_update_lmtaddr(struct rvu *rvu, u16 pcifunc, u64 lmt_addr)
{
	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
	u32 tbl_idx;
	int err = 0;
	u64 val;

	/* Read the current lmt addr of pcifunc */
	tbl_idx = rvu_get_lmtst_tbl_index(rvu, pcifunc);
	err = lmtst_map_table_ops(rvu, tbl_idx, &val, LMT_TBL_OP_READ);
	if (err) {
		dev_err(rvu->dev,
			"Failed to read LMT map table: index 0x%x err %d\n",
			tbl_idx, err);
		return err;
	}

	/* Storing the seondary's lmt base address as this needs to be
	 * reverted in FLR. Also making sure this default value doesn't
	 * get overwritten on multiple calls to this mailbox.
	 */
	if (!pfvf->lmt_base_addr)
		pfvf->lmt_base_addr = val;

	/* Update the LMT table with new addr */
	err = lmtst_map_table_ops(rvu, tbl_idx, &lmt_addr, LMT_TBL_OP_WRITE);
	if (err) {
		dev_err(rvu->dev,
			"Failed to update LMT map table: index 0x%x err %d\n",
			tbl_idx, err);
		return err;
	}
	return 0;
}

int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
				     struct lmtst_tbl_setup_req *req,
				     struct msg_rsp *rsp)
{
	u64 lmt_addr, val;
	u32 pri_tbl_idx;
	int err = 0;

	/* Check if PF_FUNC wants to use it's own local memory as LMTLINE
	 * region, if so, convert that IOVA to physical address and
	 * populate LMT table with that address
	 */
	if (req->use_local_lmt_region) {
		err = rvu_get_lmtaddr(rvu, req->hdr.pcifunc,
				      req->lmt_iova, &lmt_addr);
		if (err < 0)
			return err;

		/* Update the lmt addr for this PFFUNC in the LMT table */
		err = rvu_update_lmtaddr(rvu, req->hdr.pcifunc, lmt_addr);
		if (err)
			return err;
	}

	/* Reconfiguring lmtst map table in lmt region shared mode i.e. make
	 * multiple PF_FUNCs to share an LMTLINE region, so primary/base
	 * pcifunc (which is passed as an argument to mailbox) is the one
	 * whose lmt base address will be shared among other secondary
	 * pcifunc (will be the one who is calling this mailbox).
	 */
	if (req->base_pcifunc) {
		/* Calculating the LMT table index equivalent to primary
		 * pcifunc.
		 */
		pri_tbl_idx = rvu_get_lmtst_tbl_index(rvu, req->base_pcifunc);

		/* Read the base lmt addr of the primary pcifunc */
		err = lmtst_map_table_ops(rvu, pri_tbl_idx, &val,
					  LMT_TBL_OP_READ);
		if (err) {
			dev_err(rvu->dev,
				"Failed to read LMT map table: index 0x%x err %d\n",
				pri_tbl_idx, err);
			return err;
		}

		/* Update the base lmt addr of secondary with primary's base
		 * lmt addr.
		 */
		err = rvu_update_lmtaddr(rvu, req->hdr.pcifunc, val);
		if (err)
			return err;
	}

	return 0;
}

/* Resetting the lmtst map table to original base addresses */
void rvu_reset_lmt_map_tbl(struct rvu *rvu, u16 pcifunc)
{
	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
	u32 tbl_idx;
	int err;

	if (is_rvu_otx2(rvu))
		return;

	if (pfvf->lmt_base_addr) {
		/* This corresponds to lmt map table index */
		tbl_idx = rvu_get_lmtst_tbl_index(rvu, pcifunc);
		/* Reverting back original lmt base addr for respective
		 * pcifunc.
		 */
		err = lmtst_map_table_ops(rvu, tbl_idx, &pfvf->lmt_base_addr,
					  LMT_TBL_OP_WRITE);
		if (err)
			dev_err(rvu->dev,
				"Failed to update LMT map table: index 0x%x err %d\n",
				tbl_idx, err);
		pfvf->lmt_base_addr = 0;
	}
}

int rvu_set_channels_base(struct rvu *rvu)
{
	struct rvu_hwinfo *hw = rvu->hw;
	u16 cpt_chan_base;
	u64 nix_const;
	int blkaddr;

	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
	if (blkaddr < 0)
		return blkaddr;

	nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST);

	hw->cgx = (nix_const >> 12) & 0xFULL;
	hw->lmac_per_cgx = (nix_const >> 8) & 0xFULL;
	hw->cgx_links = hw->cgx * hw->lmac_per_cgx;
	hw->lbk_links = (nix_const >> 24) & 0xFULL;
	hw->cpt_links = (nix_const >> 44) & 0xFULL;
	hw->sdp_links = 1;

	hw->cgx_chan_base = NIX_CHAN_CGX_LMAC_CHX(0, 0, 0);
	hw->lbk_chan_base = NIX_CHAN_LBK_CHX(0, 0);
	hw->sdp_chan_base = NIX_CHAN_SDP_CH_START;

	/* No Programmable channels */
	if (!(nix_const & BIT_ULL(60)))
		return 0;

	hw->cap.programmable_chans = true;

	/* If programmable channels are present then configure
	 * channels such that all channel numbers are contiguous
	 * leaving no holes. This way the new CPT channels can be
	 * accomodated. The order of channel numbers assigned is
	 * LBK, SDP, CGX and CPT.
	 */
	hw->sdp_chan_base = hw->lbk_chan_base + hw->lbk_links *
				((nix_const >> 16) & 0xFFULL);
	hw->cgx_chan_base = hw->sdp_chan_base + hw->sdp_links * SDP_CHANNELS;

	cpt_chan_base = hw->cgx_chan_base + hw->cgx_links *
				(nix_const & 0xFFULL);

	/* Out of 4096 channels start CPT from 2048 so
	 * that MSB for CPT channels is always set
	 */
	if (cpt_chan_base <= 0x800) {
		hw->cpt_chan_base = 0x800;
	} else {
		dev_err(rvu->dev,
			"CPT channels could not fit in the range 2048-4095\n");
		return -EINVAL;
	}

	return 0;
}

#define LBK_CONNECT_NIXX(a)		(0x0 + (a))

static void __rvu_lbk_set_chans(struct rvu *rvu, void __iomem *base,
				u64 offset, int lbkid, u16 chans)
{
	struct rvu_hwinfo *hw = rvu->hw;
	u64 cfg;

	cfg = readq(base + offset);
	cfg &= ~(LBK_LINK_CFG_RANGE_MASK |
		 LBK_LINK_CFG_ID_MASK | LBK_LINK_CFG_BASE_MASK);
	cfg |=	FIELD_PREP(LBK_LINK_CFG_RANGE_MASK, ilog2(chans));
	cfg |=	FIELD_PREP(LBK_LINK_CFG_ID_MASK, lbkid);
	cfg |=	FIELD_PREP(LBK_LINK_CFG_BASE_MASK, hw->lbk_chan_base);

	writeq(cfg, base + offset);
}

static void rvu_lbk_set_channels(struct rvu *rvu)
{
	struct pci_dev *pdev = NULL;
	void __iomem *base;
	u64 lbk_const;
	u8 src, dst;
	u16 chans;

	/* To loopback packets between multiple NIX blocks
	 * mutliple LBK blocks are needed. With two NIX blocks,
	 * four LBK blocks are needed and each LBK block
	 * source and destination are as follows:
	 * LBK0 - source NIX0 and destination NIX1
	 * LBK1 - source NIX0 and destination NIX1
	 * LBK2 - source NIX1 and destination NIX0
	 * LBK3 - source NIX1 and destination NIX1
	 * As per the HRM channel numbers should be programmed as:
	 * P2X and X2P of LBK0 as same
	 * P2X and X2P of LBK3 as same
	 * P2X of LBK1 and X2P of LBK2 as same
	 * P2X of LBK2 and X2P of LBK1 as same
	 */
	while (true) {
		pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
				      PCI_DEVID_OCTEONTX2_LBK, pdev);
		if (!pdev)
			return;

		base = pci_ioremap_bar(pdev, 0);
		if (!base)
			goto err_put;

		lbk_const = readq(base + LBK_CONST);
		chans = FIELD_GET(LBK_CONST_CHANS, lbk_const);
		dst = FIELD_GET(LBK_CONST_DST, lbk_const);
		src = FIELD_GET(LBK_CONST_SRC, lbk_const);

		if (src == dst) {
			if (src == LBK_CONNECT_NIXX(0)) { /* LBK0 */
				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
						    0, chans);
				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
						    0, chans);
			} else if (src == LBK_CONNECT_NIXX(1)) { /* LBK3 */
				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
						    1, chans);
				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
						    1, chans);
			}
		} else {
			if (src == LBK_CONNECT_NIXX(0)) { /* LBK1 */
				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
						    0, chans);
				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
						    1, chans);
			} else if (src == LBK_CONNECT_NIXX(1)) { /* LBK2 */
				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
						    1, chans);
				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
						    0, chans);
			}
		}
		iounmap(base);
	}
err_put:
	pci_dev_put(pdev);
}

static void __rvu_nix_set_channels(struct rvu *rvu, int blkaddr)
{
	u64 nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST);
	u16 cgx_chans, lbk_chans, sdp_chans, cpt_chans;
	struct rvu_hwinfo *hw = rvu->hw;
	int link, nix_link = 0;
	u16 start;
	u64 cfg;

	cgx_chans = nix_const & 0xFFULL;
	lbk_chans = (nix_const >> 16) & 0xFFULL;
	sdp_chans = SDP_CHANNELS;
	cpt_chans = (nix_const >> 32) & 0xFFFULL;

	start = hw->cgx_chan_base;
	for (link = 0; link < hw->cgx_links; link++, nix_link++) {
		cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
		cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
		cfg |=	FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(cgx_chans));
		cfg |=	FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
		rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
		start += cgx_chans;
	}

	start = hw->lbk_chan_base;
	for (link = 0; link < hw->lbk_links; link++, nix_link++) {
		cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
		cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
		cfg |=	FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(lbk_chans));
		cfg |=	FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
		rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
		start += lbk_chans;
	}

	start = hw->sdp_chan_base;
	for (link = 0; link < hw->sdp_links; link++, nix_link++) {
		cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
		cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
		cfg |=	FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(sdp_chans));
		cfg |=	FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
		rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
		start += sdp_chans;
	}

	start = hw->cpt_chan_base;
	for (link = 0; link < hw->cpt_links; link++, nix_link++) {
		cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
		cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
		cfg |=	FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(cpt_chans));
		cfg |=	FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
		rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
		start += cpt_chans;
	}
}

static void rvu_nix_set_channels(struct rvu *rvu)
{
	int blkaddr = 0;

	blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
	while (blkaddr) {
		__rvu_nix_set_channels(rvu, blkaddr);
		blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
	}
}

static void __rvu_rpm_set_channels(int cgxid, int lmacid, u16 base)
{
	u64 cfg;

	cfg = cgx_lmac_read(cgxid, lmacid, RPMX_CMRX_LINK_CFG);
	cfg &= ~(RPMX_CMRX_LINK_BASE_MASK | RPMX_CMRX_LINK_RANGE_MASK);

	/* There is no read-only constant register to read
	 * the number of channels for LMAC and it is always 16.
	 */
	cfg |=	FIELD_PREP(RPMX_CMRX_LINK_RANGE_MASK, ilog2(16));
	cfg |=	FIELD_PREP(RPMX_CMRX_LINK_BASE_MASK, base);
	cgx_lmac_write(cgxid, lmacid, RPMX_CMRX_LINK_CFG, cfg);
}

static void rvu_rpm_set_channels(struct rvu *rvu)
{
	struct rvu_hwinfo *hw = rvu->hw;
	u16 base = hw->cgx_chan_base;
	int cgx, lmac;

	for (cgx = 0; cgx < rvu->cgx_cnt_max; cgx++) {
		for (lmac = 0; lmac < hw->lmac_per_cgx; lmac++) {
			__rvu_rpm_set_channels(cgx, lmac, base);
			base += 16;
		}
	}
}

void rvu_program_channels(struct rvu *rvu)
{
	struct rvu_hwinfo *hw = rvu->hw;

	if (!hw->cap.programmable_chans)
		return;

	rvu_nix_set_channels(rvu);
	rvu_lbk_set_channels(rvu);
	rvu_rpm_set_channels(rvu);
}
