// SPDX-License-Identifier: GPL-2.0
/* Marvell MCS driver
 *
 * Copyright (C) 2022 Marvell.
 */

#include "mcs.h"
#include "mcs_reg.h"

static struct mcs_ops cnf10kb_mcs_ops   = {
	.mcs_set_hw_capabilities	= cnf10kb_mcs_set_hw_capabilities,
	.mcs_parser_cfg			= cnf10kb_mcs_parser_cfg,
	.mcs_tx_sa_mem_map_write	= cnf10kb_mcs_tx_sa_mem_map_write,
	.mcs_rx_sa_mem_map_write	= cnf10kb_mcs_rx_sa_mem_map_write,
	.mcs_flowid_secy_map		= cnf10kb_mcs_flowid_secy_map,
};

struct mcs_ops *cnf10kb_get_mac_ops(void)
{
	return &cnf10kb_mcs_ops;
}

void cnf10kb_mcs_set_hw_capabilities(struct mcs *mcs)
{
	struct hwinfo *hw = mcs->hw;

	hw->tcam_entries = 64;		/* TCAM entries */
	hw->secy_entries  = 64;		/* SecY entries */
	hw->sc_entries = 64;		/* SC CAM entries */
	hw->sa_entries = 128;		/* SA entries */
	hw->lmac_cnt = 4;		/* lmacs/ports per mcs block */
	hw->mcs_x2p_intf = 1;		/* x2p clabration intf */
	hw->mcs_blks = 7;		/* MCS blocks */
}

void cnf10kb_mcs_parser_cfg(struct mcs *mcs)
{
	u64 reg, val;

	/* VLAN Ctag */
	val = (0x8100ull & 0xFFFF) | BIT_ULL(20) | BIT_ULL(22);

	reg = MCSX_PEX_RX_SLAVE_CUSTOM_TAGX(0);
	mcs_reg_write(mcs, reg, val);

	reg = MCSX_PEX_TX_SLAVE_CUSTOM_TAGX(0);
	mcs_reg_write(mcs, reg, val);

	/* VLAN STag */
	val = (0x88a8ull & 0xFFFF) | BIT_ULL(20) | BIT_ULL(23);

	/* RX */
	reg = MCSX_PEX_RX_SLAVE_CUSTOM_TAGX(1);
	mcs_reg_write(mcs, reg, val);

	/* TX */
	reg = MCSX_PEX_TX_SLAVE_CUSTOM_TAGX(1);
	mcs_reg_write(mcs, reg, val);

	/* Enable custom tage 0 and 1 and sectag */
	val = BIT_ULL(0) | BIT_ULL(1) | BIT_ULL(12);

	reg = MCSX_PEX_RX_SLAVE_ETYPE_ENABLE;
	mcs_reg_write(mcs, reg, val);

	reg = MCSX_PEX_TX_SLAVE_ETYPE_ENABLE;
	mcs_reg_write(mcs, reg, val);
}

void cnf10kb_mcs_flowid_secy_map(struct mcs *mcs, struct secy_mem_map *map, int dir)
{
	u64 reg, val;

	val = (map->secy & 0x3F) | (map->ctrl_pkt & 0x1) << 6;
	if (dir == MCS_RX) {
		reg = MCSX_CPM_RX_SLAVE_SECY_MAP_MEMX(map->flow_id);
	} else {
		reg = MCSX_CPM_TX_SLAVE_SECY_MAP_MEM_0X(map->flow_id);
		mcs_reg_write(mcs, reg, map->sci);
		val |= (map->sc & 0x3F) << 7;
		reg = MCSX_CPM_TX_SLAVE_SECY_MAP_MEM_1X(map->flow_id);
	}

	mcs_reg_write(mcs, reg, val);
}

void cnf10kb_mcs_tx_sa_mem_map_write(struct mcs *mcs, struct mcs_tx_sc_sa_map *map)
{
	u64 reg, val;

	val = (map->sa_index0 & 0x7F) | (map->sa_index1 & 0x7F) << 7;

	reg = MCSX_CPM_TX_SLAVE_SA_MAP_MEM_0X(map->sc_id);
	mcs_reg_write(mcs, reg, val);

	reg = MCSX_CPM_TX_SLAVE_AUTO_REKEY_ENABLE_0;
	val = mcs_reg_read(mcs, reg);

	if (map->rekey_ena)
		val |= BIT_ULL(map->sc_id);
	else
		val &= ~BIT_ULL(map->sc_id);

	mcs_reg_write(mcs, reg, val);

	mcs_reg_write(mcs, MCSX_CPM_TX_SLAVE_SA_INDEX0_VLDX(map->sc_id), map->sa_index0_vld);
	mcs_reg_write(mcs, MCSX_CPM_TX_SLAVE_SA_INDEX1_VLDX(map->sc_id), map->sa_index1_vld);

	mcs_reg_write(mcs, MCSX_CPM_TX_SLAVE_TX_SA_ACTIVEX(map->sc_id), map->tx_sa_active);
}

void cnf10kb_mcs_rx_sa_mem_map_write(struct mcs *mcs, struct mcs_rx_sc_sa_map *map)
{
	u64 val, reg;

	val = (map->sa_index & 0x7F) | (map->sa_in_use << 7);

	reg = MCSX_CPM_RX_SLAVE_SA_MAP_MEMX((4 * map->sc_id) + map->an);
	mcs_reg_write(mcs, reg, val);
}

int mcs_set_force_clk_en(struct mcs *mcs, bool set)
{
	unsigned long timeout = jiffies + usecs_to_jiffies(2000);
	u64 val;

	val = mcs_reg_read(mcs, MCSX_MIL_GLOBAL);

	if (set) {
		val |= BIT_ULL(4);
		mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val);

		/* Poll till mcsx_mil_ip_gbl_status.mcs_ip_stats_ready value is 1 */
		while (!(mcs_reg_read(mcs, MCSX_MIL_IP_GBL_STATUS) & BIT_ULL(0))) {
			if (time_after(jiffies, timeout)) {
				dev_err(mcs->dev, "MCS set force clk enable failed\n");
				break;
			}
		}
	} else {
		val &= ~BIT_ULL(4);
		mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val);
	}

	return 0;
}

/* TX SA interrupt is raised only if autorekey is enabled.
 * MCS_CPM_TX_SLAVE_SA_MAP_MEM_0X[sc].tx_sa_active bit gets toggled if
 * one of two SAs mapped to SC gets expired. If tx_sa_active=0 implies
 * SA in SA_index1 got expired else SA in SA_index0 got expired.
 */
void cnf10kb_mcs_tx_pn_thresh_reached_handler(struct mcs *mcs)
{
	struct mcs_intr_event event;
	struct rsrc_bmap *sc_bmap;
	unsigned long rekey_ena;
	u64 val, sa_status;
	int sc;

	sc_bmap = &mcs->tx.sc;

	event.mcs_id = mcs->mcs_id;
	event.intr_mask = MCS_CPM_TX_PN_THRESH_REACHED_INT;

	rekey_ena = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_AUTO_REKEY_ENABLE_0);

	for_each_set_bit(sc, sc_bmap->bmap, mcs->hw->sc_entries) {
		/* Auto rekey is enable */
		if (!test_bit(sc, &rekey_ena))
			continue;
		sa_status = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_TX_SA_ACTIVEX(sc));
		/* Check if tx_sa_active status had changed */
		if (sa_status == mcs->tx_sa_active[sc])
			continue;

		/* SA_index0 is expired */
		val = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_SA_MAP_MEM_0X(sc));
		if (sa_status)
			event.sa_id = val & 0x7F;
		else
			event.sa_id = (val >> 7) & 0x7F;

		event.pcifunc = mcs->tx.sa2pf_map[event.sa_id];
		mcs_add_intr_wq_entry(mcs, &event);
	}
}

void cnf10kb_mcs_tx_pn_wrapped_handler(struct mcs *mcs)
{
	struct mcs_intr_event event = { 0 };
	struct rsrc_bmap *sc_bmap;
	u64 val;
	int sc;

	sc_bmap = &mcs->tx.sc;

	event.mcs_id = mcs->mcs_id;
	event.intr_mask = MCS_CPM_TX_PACKET_XPN_EQ0_INT;

	for_each_set_bit(sc, sc_bmap->bmap, mcs->hw->sc_entries) {
		val = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_SA_MAP_MEM_0X(sc));

		if (mcs->tx_sa_active[sc])
			/* SA_index1 was used and got expired */
			event.sa_id = (val >> 7) & 0x7F;
		else
			/* SA_index0 was used and got expired */
			event.sa_id = val & 0x7F;

		event.pcifunc = mcs->tx.sa2pf_map[event.sa_id];
		mcs_add_intr_wq_entry(mcs, &event);
	}
}
