// SPDX-License-Identifier: GPL-2.0+
/* Microchip Sparx5 Switch driver
 *
 * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
 */

#include <net/pkt_cls.h>

#include "sparx5_tc.h"
#include "sparx5_main.h"
#include "sparx5_qos.h"

static void sparx5_tc_get_layer_and_idx(u32 parent, u32 portno, u32 *layer,
					u32 *idx)
{
	if (parent == TC_H_ROOT) {
		*layer = 2;
		*idx = portno;
	} else {
		u32 queue = TC_H_MIN(parent) - 1;
		*layer = 0;
		*idx = SPX5_HSCH_L0_GET_IDX(portno, queue);
	}
}

static int sparx5_tc_setup_qdisc_mqprio(struct net_device *ndev,
					struct tc_mqprio_qopt_offload *m)
{
	m->qopt.hw = TC_MQPRIO_HW_OFFLOAD_TCS;

	if (m->qopt.num_tc == 0)
		return sparx5_tc_mqprio_del(ndev);
	else
		return sparx5_tc_mqprio_add(ndev, m->qopt.num_tc);
}

static int sparx5_tc_setup_qdisc_tbf(struct net_device *ndev,
				     struct tc_tbf_qopt_offload *qopt)
{
	struct sparx5_port *port = netdev_priv(ndev);
	u32 layer, se_idx;

	sparx5_tc_get_layer_and_idx(qopt->parent, port->portno, &layer,
				    &se_idx);

	switch (qopt->command) {
	case TC_TBF_REPLACE:
		return sparx5_tc_tbf_add(port, &qopt->replace_params, layer,
					 se_idx);
	case TC_TBF_DESTROY:
		return sparx5_tc_tbf_del(port, layer, se_idx);
	case TC_TBF_STATS:
		return -EOPNOTSUPP;
	default:
		return -EOPNOTSUPP;
	}

	return -EOPNOTSUPP;
}

static int sparx5_tc_setup_qdisc_ets(struct net_device *ndev,
				     struct tc_ets_qopt_offload *qopt)
{
	struct tc_ets_qopt_offload_replace_params *params =
		&qopt->replace_params;
	struct sparx5_port *port = netdev_priv(ndev);
	int i;

	/* Only allow ets on ports  */
	if (qopt->parent != TC_H_ROOT)
		return -EOPNOTSUPP;

	switch (qopt->command) {
	case TC_ETS_REPLACE:

		/* We support eight priorities */
		if (params->bands != SPX5_PRIOS)
			return -EOPNOTSUPP;

		/* Sanity checks */
		for (i = 0; i < SPX5_PRIOS; ++i) {
			/* Priority map is *always* reverse e.g: 7 6 5 .. 0 */
			if (params->priomap[i] != (7 - i))
				return -EOPNOTSUPP;
			/* Throw an error if we receive zero weights by tc */
			if (params->quanta[i] && params->weights[i] == 0) {
				pr_err("Invalid ets configuration; band %d has weight zero",
				       i);
				return -EINVAL;
			}
		}

		sparx5_tc_ets_add(port, params);
		break;
	case TC_ETS_DESTROY:

		sparx5_tc_ets_del(port);

		break;
	case TC_ETS_GRAFT:
		return -EOPNOTSUPP;

	default:
		return -EOPNOTSUPP;
	}

	return -EOPNOTSUPP;
}

int sparx5_port_setup_tc(struct net_device *ndev, enum tc_setup_type type,
			 void *type_data)
{
	switch (type) {
	case TC_SETUP_QDISC_MQPRIO:
		return sparx5_tc_setup_qdisc_mqprio(ndev, type_data);
	case TC_SETUP_QDISC_TBF:
		return sparx5_tc_setup_qdisc_tbf(ndev, type_data);
	case TC_SETUP_QDISC_ETS:
		return sparx5_tc_setup_qdisc_ets(ndev, type_data);
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}
