// SPDX-License-Identifier: GPL-2.0+

#include "lan966x_main.h"

/* 0-8 : 9 port policers */
#define POL_IDX_PORT	0

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

struct lan966x_tc_policer {
	/* kilobit per second */
	u32 rate;
	/* bytes */
	u32 burst;
};

static int lan966x_police_add(struct lan966x_port *port,
			      struct lan966x_tc_policer *pol,
			      u16 pol_idx)
{
	struct lan966x *lan966x = port->lan966x;

	/* Rate unit is 33 1/3 kpps */
	pol->rate = DIV_ROUND_UP(pol->rate * 3, 100);
	/* Avoid zero burst size */
	pol->burst = pol->burst ?: 1;
	/* Unit is 4kB */
	pol->burst = DIV_ROUND_UP(pol->burst, 4096);

	if (pol->rate > GENMASK(15, 0) ||
	    pol->burst > GENMASK(6, 0))
		return -EINVAL;

	lan_wr(ANA_POL_MODE_DROP_ON_YELLOW_ENA_SET(0) |
	       ANA_POL_MODE_MARK_ALL_FRMS_RED_ENA_SET(0) |
	       ANA_POL_MODE_IPG_SIZE_SET(20) |
	       ANA_POL_MODE_FRM_MODE_SET(1) |
	       ANA_POL_MODE_OVERSHOOT_ENA_SET(1),
	       lan966x, ANA_POL_MODE(pol_idx));

	lan_wr(ANA_POL_PIR_STATE_PIR_LVL_SET(0),
	       lan966x, ANA_POL_PIR_STATE(pol_idx));

	lan_wr(ANA_POL_PIR_CFG_PIR_RATE_SET(pol->rate) |
	       ANA_POL_PIR_CFG_PIR_BURST_SET(pol->burst),
	       lan966x, ANA_POL_PIR_CFG(pol_idx));

	return 0;
}

static void lan966x_police_del(struct lan966x_port *port, u16 pol_idx)
{
	struct lan966x *lan966x = port->lan966x;

	lan_wr(ANA_POL_MODE_DROP_ON_YELLOW_ENA_SET(0) |
	       ANA_POL_MODE_MARK_ALL_FRMS_RED_ENA_SET(0) |
	       ANA_POL_MODE_IPG_SIZE_SET(20) |
	       ANA_POL_MODE_FRM_MODE_SET(2) |
	       ANA_POL_MODE_OVERSHOOT_ENA_SET(1),
	       lan966x, ANA_POL_MODE(pol_idx));

	lan_wr(ANA_POL_PIR_STATE_PIR_LVL_SET(0),
	       lan966x, ANA_POL_PIR_STATE(pol_idx));

	lan_wr(ANA_POL_PIR_CFG_PIR_RATE_SET(GENMASK(14, 0)) |
	       ANA_POL_PIR_CFG_PIR_BURST_SET(0),
	       lan966x, ANA_POL_PIR_CFG(pol_idx));
}

static int lan966x_police_validate(struct lan966x_port *port,
				   const struct flow_action *action,
				   const struct flow_action_entry *act,
				   unsigned long police_id,
				   bool ingress,
				   struct netlink_ext_ack *extack)
{
	if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Offload not supported when exceed action is not drop");
		return -EOPNOTSUPP;
	}

	if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
	    act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Offload not supported when conform action is not pipe or ok");
		return -EOPNOTSUPP;
	}

	if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
	    !flow_action_is_last_entry(action, act)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Offload not supported when conform action is ok, but action is not last");
		return -EOPNOTSUPP;
	}

	if (act->police.peakrate_bytes_ps ||
	    act->police.avrate || act->police.overhead) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Offload not supported when peakrate/avrate/overhead is configured");
		return -EOPNOTSUPP;
	}

	if (act->police.rate_pkt_ps) {
		NL_SET_ERR_MSG_MOD(extack,
				   "QoS offload not support packets per second");
		return -EOPNOTSUPP;
	}

	if (!ingress) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Policer is not supported on egress");
		return -EOPNOTSUPP;
	}

	if (port->tc.ingress_shared_block) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Policer is not supported on shared ingress blocks");
		return -EOPNOTSUPP;
	}

	if (port->tc.police_id && port->tc.police_id != police_id) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Only one policer per port is supported");
		return -EEXIST;
	}

	return 0;
}

int lan966x_police_port_add(struct lan966x_port *port,
			    struct flow_action *action,
			    struct flow_action_entry *act,
			    unsigned long police_id,
			    bool ingress,
			    struct netlink_ext_ack *extack)
{
	struct lan966x *lan966x = port->lan966x;
	struct rtnl_link_stats64 new_stats;
	struct lan966x_tc_policer pol;
	struct flow_stats *old_stats;
	int err;

	err = lan966x_police_validate(port, action, act, police_id, ingress,
				      extack);
	if (err)
		return err;

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

	pol.rate = div_u64(act->police.rate_bytes_ps, 1000) * 8;
	pol.burst = act->police.burst;

	err = lan966x_police_add(port, &pol, POL_IDX_PORT + port->chip_port);
	if (err) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Failed to add policer to port");
		return err;
	}

	lan_rmw(ANA_POL_CFG_PORT_POL_ENA_SET(1) |
		ANA_POL_CFG_POL_ORDER_SET(POL_ORDER),
		ANA_POL_CFG_PORT_POL_ENA |
		ANA_POL_CFG_POL_ORDER,
		lan966x, ANA_POL_CFG(port->chip_port));

	port->tc.police_id = police_id;

	/* Setup initial stats */
	old_stats = &port->tc.police_stat;
	lan966x_stats_get(port->dev, &new_stats);
	old_stats->bytes = new_stats.rx_bytes;
	old_stats->pkts = new_stats.rx_packets;
	old_stats->drops = new_stats.rx_dropped;
	old_stats->lastused = jiffies;

	return 0;
}

int lan966x_police_port_del(struct lan966x_port *port,
			    unsigned long police_id,
			    struct netlink_ext_ack *extack)
{
	struct lan966x *lan966x = port->lan966x;

	if (port->tc.police_id != police_id) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Invalid policer id");
		return -EINVAL;
	}

	lan966x_police_del(port, POL_IDX_PORT + port->chip_port);

	lan_rmw(ANA_POL_CFG_PORT_POL_ENA_SET(0) |
		ANA_POL_CFG_POL_ORDER_SET(POL_ORDER),
		ANA_POL_CFG_PORT_POL_ENA |
		ANA_POL_CFG_POL_ORDER,
		lan966x, ANA_POL_CFG(port->chip_port));

	port->tc.police_id = 0;

	return 0;
}

void lan966x_police_port_stats(struct lan966x_port *port,
			       struct flow_stats *stats)
{
	struct rtnl_link_stats64 new_stats;
	struct flow_stats *old_stats;

	old_stats = &port->tc.police_stat;
	lan966x_stats_get(port->dev, &new_stats);

	flow_stats_update(stats,
			  new_stats.rx_bytes - old_stats->bytes,
			  new_stats.rx_packets - old_stats->pkts,
			  new_stats.rx_dropped - old_stats->drops,
			  old_stats->lastused,
			  FLOW_ACTION_HW_STATS_IMMEDIATE);

	old_stats->bytes = new_stats.rx_bytes;
	old_stats->pkts = new_stats.rx_packets;
	old_stats->drops = new_stats.rx_dropped;
	old_stats->lastused = jiffies;
}
