// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/* Microsemi Ocelot Switch driver
 *
 * Copyright (c) 2019 Microsemi Corporation
 */

#include <soc/mscc/ocelot.h>
#include "ocelot_police.h"

/* Types for ANA:POL[0-192]:POL_MODE_CFG.FRM_MODE */
#define POL_MODE_LINERATE   0 /* Incl IPG. Unit: 33 1/3 kbps, 4096 bytes */
#define POL_MODE_DATARATE   1 /* Excl IPG. Unit: 33 1/3 kbps, 4096 bytes  */
#define POL_MODE_FRMRATE_HI 2 /* Unit: 33 1/3 fps, 32.8 frames */
#define POL_MODE_FRMRATE_LO 3 /* Unit: 1/3 fps, 0.3 frames */

/* Policer indexes */
#define POL_IX_PORT    0    /* 0-11    : Port policers */
#define POL_IX_QUEUE   32   /* 32-127  : Queue policers  */

/* Default policer order */
#define POL_ORDER 0x1d3 /* Ocelot policer order: Serial (QoS -> Port -> VCAP) */

int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix,
			 struct qos_policer_conf *conf)
{
	u32 cf = 0, cir_ena = 0, frm_mode = POL_MODE_LINERATE;
	u32 cir = 0, cbs = 0, pir = 0, pbs = 0;
	bool cir_discard = 0, pir_discard = 0;
	u32 pbs_max = 0, cbs_max = 0;
	u8 ipg = 20;
	u32 value;

	pir = conf->pir;
	pbs = conf->pbs;

	switch (conf->mode) {
	case MSCC_QOS_RATE_MODE_LINE:
	case MSCC_QOS_RATE_MODE_DATA:
		if (conf->mode == MSCC_QOS_RATE_MODE_LINE) {
			frm_mode = POL_MODE_LINERATE;
			ipg = min_t(u8, GENMASK(4, 0), conf->ipg);
		} else {
			frm_mode = POL_MODE_DATARATE;
		}
		if (conf->dlb) {
			cir_ena = 1;
			cir = conf->cir;
			cbs = conf->cbs;
			if (cir == 0 && cbs == 0) {
				/* Discard cir frames */
				cir_discard = 1;
			} else {
				cir = DIV_ROUND_UP(cir, 100);
				cir *= 3; /* 33 1/3 kbps */
				cbs = DIV_ROUND_UP(cbs, 4096);
				cbs = (cbs ? cbs : 1); /* No zero burst size */
				cbs_max = 60; /* Limit burst size */
				cf = conf->cf;
				if (cf)
					pir += conf->cir;
			}
		}
		if (pir == 0 && pbs == 0) {
			/* Discard PIR frames */
			pir_discard = 1;
		} else {
			pir = DIV_ROUND_UP(pir, 100);
			pir *= 3;  /* 33 1/3 kbps */
			pbs = DIV_ROUND_UP(pbs, 4096);
			pbs = (pbs ? pbs : 1); /* No zero burst size */
			pbs_max = 60; /* Limit burst size */
		}
		break;
	case MSCC_QOS_RATE_MODE_FRAME:
		if (pir >= 100) {
			frm_mode = POL_MODE_FRMRATE_HI;
			pir = DIV_ROUND_UP(pir, 100);
			pir *= 3;  /* 33 1/3 fps */
			pbs = (pbs * 10) / 328; /* 32.8 frames */
			pbs = (pbs ? pbs : 1); /* No zero burst size */
			pbs_max = GENMASK(6, 0); /* Limit burst size */
		} else {
			frm_mode = POL_MODE_FRMRATE_LO;
			if (pir == 0 && pbs == 0) {
				/* Discard all frames */
				pir_discard = 1;
				cir_discard = 1;
			} else {
				pir *= 3; /* 1/3 fps */
				pbs = (pbs * 10) / 3; /* 0.3 frames */
				pbs = (pbs ? pbs : 1); /* No zero burst size */
				pbs_max = 61; /* Limit burst size */
			}
		}
		break;
	default: /* MSCC_QOS_RATE_MODE_DISABLED */
		/* Disable policer using maximum rate and zero burst */
		pir = GENMASK(15, 0);
		pbs = 0;
		break;
	}

	/* Check limits */
	if (pir > GENMASK(15, 0)) {
		dev_err(ocelot->dev, "Invalid pir for port %d: %u (max %lu)\n",
			port, pir, GENMASK(15, 0));
		return -EINVAL;
	}

	if (cir > GENMASK(15, 0)) {
		dev_err(ocelot->dev, "Invalid cir for port %d: %u (max %lu)\n",
			port, cir, GENMASK(15, 0));
		return -EINVAL;
	}

	if (pbs > pbs_max) {
		dev_err(ocelot->dev, "Invalid pbs for port %d: %u (max %u)\n",
			port, pbs, pbs_max);
		return -EINVAL;
	}

	if (cbs > cbs_max) {
		dev_err(ocelot->dev, "Invalid cbs for port %d: %u (max %u)\n",
			port, cbs, cbs_max);
		return -EINVAL;
	}

	value = (ANA_POL_MODE_CFG_IPG_SIZE(ipg) |
		 ANA_POL_MODE_CFG_FRM_MODE(frm_mode) |
		 (cf ? ANA_POL_MODE_CFG_DLB_COUPLED : 0) |
		 (cir_ena ? ANA_POL_MODE_CFG_CIR_ENA : 0) |
		 ANA_POL_MODE_CFG_OVERSHOOT_ENA);

	ocelot_write_gix(ocelot, value, ANA_POL_MODE_CFG, pol_ix);

	ocelot_write_gix(ocelot,
			 ANA_POL_PIR_CFG_PIR_RATE(pir) |
			 ANA_POL_PIR_CFG_PIR_BURST(pbs),
			 ANA_POL_PIR_CFG, pol_ix);

	ocelot_write_gix(ocelot,
			 (pir_discard ? GENMASK(22, 0) : 0),
			 ANA_POL_PIR_STATE, pol_ix);

	ocelot_write_gix(ocelot,
			 ANA_POL_CIR_CFG_CIR_RATE(cir) |
			 ANA_POL_CIR_CFG_CIR_BURST(cbs),
			 ANA_POL_CIR_CFG, pol_ix);

	ocelot_write_gix(ocelot,
			 (cir_discard ? GENMASK(22, 0) : 0),
			 ANA_POL_CIR_STATE, pol_ix);

	return 0;
}

int ocelot_port_policer_add(struct ocelot *ocelot, int port,
			    struct ocelot_policer *pol)
{
	struct qos_policer_conf pp = { 0 };
	int err;

	if (!pol)
		return -EINVAL;

	pp.mode = MSCC_QOS_RATE_MODE_DATA;
	pp.pir = pol->rate;
	pp.pbs = pol->burst;

	dev_dbg(ocelot->dev, "%s: port %u pir %u kbps, pbs %u bytes\n",
		__func__, port, pp.pir, pp.pbs);

	err = qos_policer_conf_set(ocelot, port, POL_IX_PORT + port, &pp);
	if (err)
		return err;

	ocelot_rmw_gix(ocelot,
		       ANA_PORT_POL_CFG_PORT_POL_ENA |
		       ANA_PORT_POL_CFG_POL_ORDER(POL_ORDER),
		       ANA_PORT_POL_CFG_PORT_POL_ENA |
		       ANA_PORT_POL_CFG_POL_ORDER_M,
		       ANA_PORT_POL_CFG, port);

	return 0;
}
EXPORT_SYMBOL(ocelot_port_policer_add);

int ocelot_port_policer_del(struct ocelot *ocelot, int port)
{
	struct qos_policer_conf pp = { 0 };
	int err;

	dev_dbg(ocelot->dev, "%s: port %u\n", __func__, port);

	pp.mode = MSCC_QOS_RATE_MODE_DISABLED;

	err = qos_policer_conf_set(ocelot, port, POL_IX_PORT + port, &pp);
	if (err)
		return err;

	ocelot_rmw_gix(ocelot,
		       ANA_PORT_POL_CFG_POL_ORDER(POL_ORDER),
		       ANA_PORT_POL_CFG_PORT_POL_ENA |
		       ANA_PORT_POL_CFG_POL_ORDER_M,
		       ANA_PORT_POL_CFG, port);

	return 0;
}
EXPORT_SYMBOL(ocelot_port_policer_del);
