// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>
 */
#include "sja1105.h"

#define SJA1105_TAS_CLKSRC_DISABLED	0
#define SJA1105_TAS_CLKSRC_STANDALONE	1
#define SJA1105_TAS_CLKSRC_AS6802	2
#define SJA1105_TAS_CLKSRC_PTP		3
#define SJA1105_GATE_MASK		GENMASK_ULL(SJA1105_NUM_TC - 1, 0)

#define work_to_sja1105_tas(d) \
	container_of((d), struct sja1105_tas_data, tas_work)
#define tas_to_sja1105(d) \
	container_of((d), struct sja1105_private, tas_data)

static int sja1105_tas_set_runtime_params(struct sja1105_private *priv)
{
	struct sja1105_tas_data *tas_data = &priv->tas_data;
	struct sja1105_gating_config *gating_cfg = &tas_data->gating_cfg;
	struct dsa_switch *ds = priv->ds;
	s64 earliest_base_time = S64_MAX;
	s64 latest_base_time = 0;
	s64 its_cycle_time = 0;
	s64 max_cycle_time = 0;
	int port;

	tas_data->enabled = false;

	for (port = 0; port < SJA1105_NUM_PORTS; port++) {
		const struct tc_taprio_qopt_offload *offload;

		offload = tas_data->offload[port];
		if (!offload)
			continue;

		tas_data->enabled = true;

		if (max_cycle_time < offload->cycle_time)
			max_cycle_time = offload->cycle_time;
		if (latest_base_time < offload->base_time)
			latest_base_time = offload->base_time;
		if (earliest_base_time > offload->base_time) {
			earliest_base_time = offload->base_time;
			its_cycle_time = offload->cycle_time;
		}
	}

	if (!list_empty(&gating_cfg->entries)) {
		tas_data->enabled = true;

		if (max_cycle_time < gating_cfg->cycle_time)
			max_cycle_time = gating_cfg->cycle_time;
		if (latest_base_time < gating_cfg->base_time)
			latest_base_time = gating_cfg->base_time;
		if (earliest_base_time > gating_cfg->base_time) {
			earliest_base_time = gating_cfg->base_time;
			its_cycle_time = gating_cfg->cycle_time;
		}
	}

	if (!tas_data->enabled)
		return 0;

	/* Roll the earliest base time over until it is in a comparable
	 * time base with the latest, then compare their deltas.
	 * We want to enforce that all ports' base times are within
	 * SJA1105_TAS_MAX_DELTA 200ns cycles of one another.
	 */
	earliest_base_time = future_base_time(earliest_base_time,
					      its_cycle_time,
					      latest_base_time);
	while (earliest_base_time > latest_base_time)
		earliest_base_time -= its_cycle_time;
	if (latest_base_time - earliest_base_time >
	    sja1105_delta_to_ns(SJA1105_TAS_MAX_DELTA)) {
		dev_err(ds->dev,
			"Base times too far apart: min %llu max %llu\n",
			earliest_base_time, latest_base_time);
		return -ERANGE;
	}

	tas_data->earliest_base_time = earliest_base_time;
	tas_data->max_cycle_time = max_cycle_time;

	dev_dbg(ds->dev, "earliest base time %lld ns\n", earliest_base_time);
	dev_dbg(ds->dev, "latest base time %lld ns\n", latest_base_time);
	dev_dbg(ds->dev, "longest cycle time %lld ns\n", max_cycle_time);

	return 0;
}

/* Lo and behold: the egress scheduler from hell.
 *
 * At the hardware level, the Time-Aware Shaper holds a global linear arrray of
 * all schedule entries for all ports. These are the Gate Control List (GCL)
 * entries, let's call them "timeslots" for short. This linear array of
 * timeslots is held in BLK_IDX_SCHEDULE.
 *
 * Then there are a maximum of 8 "execution threads" inside the switch, which
 * iterate cyclically through the "schedule". Each "cycle" has an entry point
 * and an exit point, both being timeslot indices in the schedule table. The
 * hardware calls each cycle a "subschedule".
 *
 * Subschedule (cycle) i starts when
 *   ptpclkval >= ptpschtm + BLK_IDX_SCHEDULE_ENTRY_POINTS[i].delta.
 *
 * The hardware scheduler iterates BLK_IDX_SCHEDULE with a k ranging from
 *   k = BLK_IDX_SCHEDULE_ENTRY_POINTS[i].address to
 *   k = BLK_IDX_SCHEDULE_PARAMS.subscheind[i]
 *
 * For each schedule entry (timeslot) k, the engine executes the gate control
 * list entry for the duration of BLK_IDX_SCHEDULE[k].delta.
 *
 *         +---------+
 *         |         | BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS
 *         +---------+
 *              |
 *              +-----------------+
 *                                | .actsubsch
 *  BLK_IDX_SCHEDULE_ENTRY_POINTS v
 *                 +-------+-------+
 *                 |cycle 0|cycle 1|
 *                 +-------+-------+
 *                   |  |      |  |
 *  +----------------+  |      |  +-------------------------------------+
 *  |   .subschindx     |      |             .subschindx                |
 *  |                   |      +---------------+                        |
 *  |          .address |        .address      |                        |
 *  |                   |                      |                        |
 *  |                   |                      |                        |
 *  |  BLK_IDX_SCHEDULE v                      v                        |
 *  |              +-------+-------+-------+-------+-------+------+     |
 *  |              |entry 0|entry 1|entry 2|entry 3|entry 4|entry5|     |
 *  |              +-------+-------+-------+-------+-------+------+     |
 *  |                                  ^                    ^  ^  ^     |
 *  |                                  |                    |  |  |     |
 *  |        +-------------------------+                    |  |  |     |
 *  |        |              +-------------------------------+  |  |     |
 *  |        |              |              +-------------------+  |     |
 *  |        |              |              |                      |     |
 *  | +---------------------------------------------------------------+ |
 *  | |subscheind[0]<=subscheind[1]<=subscheind[2]<=...<=subscheind[7]| |
 *  | +---------------------------------------------------------------+ |
 *  |        ^              ^                BLK_IDX_SCHEDULE_PARAMS    |
 *  |        |              |                                           |
 *  +--------+              +-------------------------------------------+
 *
 *  In the above picture there are two subschedules (cycles):
 *
 *  - cycle 0: iterates the schedule table from 0 to 2 (and back)
 *  - cycle 1: iterates the schedule table from 3 to 5 (and back)
 *
 *  All other possible execution threads must be marked as unused by making
 *  their "subschedule end index" (subscheind) equal to the last valid
 *  subschedule's end index (in this case 5).
 */
int sja1105_init_scheduling(struct sja1105_private *priv)
{
	struct sja1105_schedule_entry_points_entry *schedule_entry_points;
	struct sja1105_schedule_entry_points_params_entry
					*schedule_entry_points_params;
	struct sja1105_schedule_params_entry *schedule_params;
	struct sja1105_tas_data *tas_data = &priv->tas_data;
	struct sja1105_gating_config *gating_cfg = &tas_data->gating_cfg;
	struct sja1105_schedule_entry *schedule;
	struct sja1105_table *table;
	int schedule_start_idx;
	s64 entry_point_delta;
	int schedule_end_idx;
	int num_entries = 0;
	int num_cycles = 0;
	int cycle = 0;
	int i, k = 0;
	int port, rc;

	rc = sja1105_tas_set_runtime_params(priv);
	if (rc < 0)
		return rc;

	/* Discard previous Schedule Table */
	table = &priv->static_config.tables[BLK_IDX_SCHEDULE];
	if (table->entry_count) {
		kfree(table->entries);
		table->entry_count = 0;
	}

	/* Discard previous Schedule Entry Points Parameters Table */
	table = &priv->static_config.tables[BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS];
	if (table->entry_count) {
		kfree(table->entries);
		table->entry_count = 0;
	}

	/* Discard previous Schedule Parameters Table */
	table = &priv->static_config.tables[BLK_IDX_SCHEDULE_PARAMS];
	if (table->entry_count) {
		kfree(table->entries);
		table->entry_count = 0;
	}

	/* Discard previous Schedule Entry Points Table */
	table = &priv->static_config.tables[BLK_IDX_SCHEDULE_ENTRY_POINTS];
	if (table->entry_count) {
		kfree(table->entries);
		table->entry_count = 0;
	}

	/* Figure out the dimensioning of the problem */
	for (port = 0; port < SJA1105_NUM_PORTS; port++) {
		if (tas_data->offload[port]) {
			num_entries += tas_data->offload[port]->num_entries;
			num_cycles++;
		}
	}

	if (!list_empty(&gating_cfg->entries)) {
		num_entries += gating_cfg->num_entries;
		num_cycles++;
	}

	/* Nothing to do */
	if (!num_cycles)
		return 0;

	/* Pre-allocate space in the static config tables */

	/* Schedule Table */
	table = &priv->static_config.tables[BLK_IDX_SCHEDULE];
	table->entries = kcalloc(num_entries, table->ops->unpacked_entry_size,
				 GFP_KERNEL);
	if (!table->entries)
		return -ENOMEM;
	table->entry_count = num_entries;
	schedule = table->entries;

	/* Schedule Points Parameters Table */
	table = &priv->static_config.tables[BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS];
	table->entries = kcalloc(SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT,
				 table->ops->unpacked_entry_size, GFP_KERNEL);
	if (!table->entries)
		/* Previously allocated memory will be freed automatically in
		 * sja1105_static_config_free. This is true for all early
		 * returns below.
		 */
		return -ENOMEM;
	table->entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT;
	schedule_entry_points_params = table->entries;

	/* Schedule Parameters Table */
	table = &priv->static_config.tables[BLK_IDX_SCHEDULE_PARAMS];
	table->entries = kcalloc(SJA1105_MAX_SCHEDULE_PARAMS_COUNT,
				 table->ops->unpacked_entry_size, GFP_KERNEL);
	if (!table->entries)
		return -ENOMEM;
	table->entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT;
	schedule_params = table->entries;

	/* Schedule Entry Points Table */
	table = &priv->static_config.tables[BLK_IDX_SCHEDULE_ENTRY_POINTS];
	table->entries = kcalloc(num_cycles, table->ops->unpacked_entry_size,
				 GFP_KERNEL);
	if (!table->entries)
		return -ENOMEM;
	table->entry_count = num_cycles;
	schedule_entry_points = table->entries;

	/* Finally start populating the static config tables */
	schedule_entry_points_params->clksrc = SJA1105_TAS_CLKSRC_PTP;
	schedule_entry_points_params->actsubsch = num_cycles - 1;

	for (port = 0; port < SJA1105_NUM_PORTS; port++) {
		const struct tc_taprio_qopt_offload *offload;
		/* Relative base time */
		s64 rbt;

		offload = tas_data->offload[port];
		if (!offload)
			continue;

		schedule_start_idx = k;
		schedule_end_idx = k + offload->num_entries - 1;
		/* This is the base time expressed as a number of TAS ticks
		 * relative to PTPSCHTM, which we'll (perhaps improperly) call
		 * the operational base time.
		 */
		rbt = future_base_time(offload->base_time,
				       offload->cycle_time,
				       tas_data->earliest_base_time);
		rbt -= tas_data->earliest_base_time;
		/* UM10944.pdf 4.2.2. Schedule Entry Points table says that
		 * delta cannot be zero, which is shitty. Advance all relative
		 * base times by 1 TAS delta, so that even the earliest base
		 * time becomes 1 in relative terms. Then start the operational
		 * base time (PTPSCHTM) one TAS delta earlier than planned.
		 */
		entry_point_delta = ns_to_sja1105_delta(rbt) + 1;

		schedule_entry_points[cycle].subschindx = cycle;
		schedule_entry_points[cycle].delta = entry_point_delta;
		schedule_entry_points[cycle].address = schedule_start_idx;

		/* The subschedule end indices need to be
		 * monotonically increasing.
		 */
		for (i = cycle; i < 8; i++)
			schedule_params->subscheind[i] = schedule_end_idx;

		for (i = 0; i < offload->num_entries; i++, k++) {
			s64 delta_ns = offload->entries[i].interval;

			schedule[k].delta = ns_to_sja1105_delta(delta_ns);
			schedule[k].destports = BIT(port);
			schedule[k].resmedia_en = true;
			schedule[k].resmedia = SJA1105_GATE_MASK &
					~offload->entries[i].gate_mask;
		}
		cycle++;
	}

	if (!list_empty(&gating_cfg->entries)) {
		struct sja1105_gate_entry *e;

		/* Relative base time */
		s64 rbt;

		schedule_start_idx = k;
		schedule_end_idx = k + gating_cfg->num_entries - 1;
		rbt = future_base_time(gating_cfg->base_time,
				       gating_cfg->cycle_time,
				       tas_data->earliest_base_time);
		rbt -= tas_data->earliest_base_time;
		entry_point_delta = ns_to_sja1105_delta(rbt) + 1;

		schedule_entry_points[cycle].subschindx = cycle;
		schedule_entry_points[cycle].delta = entry_point_delta;
		schedule_entry_points[cycle].address = schedule_start_idx;

		for (i = cycle; i < 8; i++)
			schedule_params->subscheind[i] = schedule_end_idx;

		list_for_each_entry(e, &gating_cfg->entries, list) {
			schedule[k].delta = ns_to_sja1105_delta(e->interval);
			schedule[k].destports = e->rule->vl.destports;
			schedule[k].setvalid = true;
			schedule[k].txen = true;
			schedule[k].vlindex = e->rule->vl.sharindx;
			schedule[k].winstindex = e->rule->vl.sharindx;
			if (e->gate_state) /* Gate open */
				schedule[k].winst = true;
			else /* Gate closed */
				schedule[k].winend = true;
			k++;
		}
	}

	return 0;
}

/* Be there 2 port subschedules, each executing an arbitrary number of gate
 * open/close events cyclically.
 * None of those gate events must ever occur at the exact same time, otherwise
 * the switch is known to act in exotically strange ways.
 * However the hardware doesn't bother performing these integrity checks.
 * So here we are with the task of validating whether the new @admin offload
 * has any conflict with the already established TAS configuration in
 * tas_data->offload.  We already know the other ports are in harmony with one
 * another, otherwise we wouldn't have saved them.
 * Each gate event executes periodically, with a period of @cycle_time and a
 * phase given by its cycle's @base_time plus its offset within the cycle
 * (which in turn is given by the length of the events prior to it).
 * There are two aspects to possible collisions:
 * - Collisions within one cycle's (actually the longest cycle's) time frame.
 *   For that, we need to compare the cartesian product of each possible
 *   occurrence of each event within one cycle time.
 * - Collisions in the future. Events may not collide within one cycle time,
 *   but if two port schedules don't have the same periodicity (aka the cycle
 *   times aren't multiples of one another), they surely will some time in the
 *   future (actually they will collide an infinite amount of times).
 */
static bool
sja1105_tas_check_conflicts(struct sja1105_private *priv, int port,
			    const struct tc_taprio_qopt_offload *admin)
{
	struct sja1105_tas_data *tas_data = &priv->tas_data;
	const struct tc_taprio_qopt_offload *offload;
	s64 max_cycle_time, min_cycle_time;
	s64 delta1, delta2;
	s64 rbt1, rbt2;
	s64 stop_time;
	s64 t1, t2;
	int i, j;
	s32 rem;

	offload = tas_data->offload[port];
	if (!offload)
		return false;

	/* Check if the two cycle times are multiples of one another.
	 * If they aren't, then they will surely collide.
	 */
	max_cycle_time = max(offload->cycle_time, admin->cycle_time);
	min_cycle_time = min(offload->cycle_time, admin->cycle_time);
	div_s64_rem(max_cycle_time, min_cycle_time, &rem);
	if (rem)
		return true;

	/* Calculate the "reduced" base time of each of the two cycles
	 * (transposed back as close to 0 as possible) by dividing to
	 * the cycle time.
	 */
	div_s64_rem(offload->base_time, offload->cycle_time, &rem);
	rbt1 = rem;

	div_s64_rem(admin->base_time, admin->cycle_time, &rem);
	rbt2 = rem;

	stop_time = max_cycle_time + max(rbt1, rbt2);

	/* delta1 is the relative base time of each GCL entry within
	 * the established ports' TAS config.
	 */
	for (i = 0, delta1 = 0;
	     i < offload->num_entries;
	     delta1 += offload->entries[i].interval, i++) {
		/* delta2 is the relative base time of each GCL entry
		 * within the newly added TAS config.
		 */
		for (j = 0, delta2 = 0;
		     j < admin->num_entries;
		     delta2 += admin->entries[j].interval, j++) {
			/* t1 follows all possible occurrences of the
			 * established ports' GCL entry i within the
			 * first cycle time.
			 */
			for (t1 = rbt1 + delta1;
			     t1 <= stop_time;
			     t1 += offload->cycle_time) {
				/* t2 follows all possible occurrences
				 * of the newly added GCL entry j
				 * within the first cycle time.
				 */
				for (t2 = rbt2 + delta2;
				     t2 <= stop_time;
				     t2 += admin->cycle_time) {
					if (t1 == t2) {
						dev_warn(priv->ds->dev,
							 "GCL entry %d collides with entry %d of port %d\n",
							 j, i, port);
						return true;
					}
				}
			}
		}
	}

	return false;
}

/* Check the tc-taprio configuration on @port for conflicts with the tc-gate
 * global subschedule. If @port is -1, check it against all ports.
 * To reuse the sja1105_tas_check_conflicts logic without refactoring it,
 * convert the gating configuration to a dummy tc-taprio offload structure.
 */
bool sja1105_gating_check_conflicts(struct sja1105_private *priv, int port,
				    struct netlink_ext_ack *extack)
{
	struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg;
	size_t num_entries = gating_cfg->num_entries;
	struct tc_taprio_qopt_offload *dummy;
	struct sja1105_gate_entry *e;
	bool conflict;
	int i = 0;

	if (list_empty(&gating_cfg->entries))
		return false;

	dummy = kzalloc(sizeof(struct tc_taprio_sched_entry) * num_entries +
			sizeof(struct tc_taprio_qopt_offload), GFP_KERNEL);
	if (!dummy) {
		NL_SET_ERR_MSG_MOD(extack, "Failed to allocate memory");
		return true;
	}

	dummy->num_entries = num_entries;
	dummy->base_time = gating_cfg->base_time;
	dummy->cycle_time = gating_cfg->cycle_time;

	list_for_each_entry(e, &gating_cfg->entries, list)
		dummy->entries[i++].interval = e->interval;

	if (port != -1) {
		conflict = sja1105_tas_check_conflicts(priv, port, dummy);
	} else {
		for (port = 0; port < SJA1105_NUM_PORTS; port++) {
			conflict = sja1105_tas_check_conflicts(priv, port,
							       dummy);
			if (conflict)
				break;
		}
	}

	kfree(dummy);

	return conflict;
}

int sja1105_setup_tc_taprio(struct dsa_switch *ds, int port,
			    struct tc_taprio_qopt_offload *admin)
{
	struct sja1105_private *priv = ds->priv;
	struct sja1105_tas_data *tas_data = &priv->tas_data;
	int other_port, rc, i;

	/* Can't change an already configured port (must delete qdisc first).
	 * Can't delete the qdisc from an unconfigured port.
	 */
	if (!!tas_data->offload[port] == admin->enable)
		return -EINVAL;

	if (!admin->enable) {
		taprio_offload_free(tas_data->offload[port]);
		tas_data->offload[port] = NULL;

		rc = sja1105_init_scheduling(priv);
		if (rc < 0)
			return rc;

		return sja1105_static_config_reload(priv, SJA1105_SCHEDULING);
	}

	/* The cycle time extension is the amount of time the last cycle from
	 * the old OPER needs to be extended in order to phase-align with the
	 * base time of the ADMIN when that becomes the new OPER.
	 * But of course our switch needs to be reset to switch-over between
	 * the ADMIN and the OPER configs - so much for a seamless transition.
	 * So don't add insult over injury and just say we don't support cycle
	 * time extension.
	 */
	if (admin->cycle_time_extension)
		return -ENOTSUPP;

	for (i = 0; i < admin->num_entries; i++) {
		s64 delta_ns = admin->entries[i].interval;
		s64 delta_cycles = ns_to_sja1105_delta(delta_ns);
		bool too_long, too_short;

		too_long = (delta_cycles >= SJA1105_TAS_MAX_DELTA);
		too_short = (delta_cycles == 0);
		if (too_long || too_short) {
			dev_err(priv->ds->dev,
				"Interval %llu too %s for GCL entry %d\n",
				delta_ns, too_long ? "long" : "short", i);
			return -ERANGE;
		}
	}

	for (other_port = 0; other_port < SJA1105_NUM_PORTS; other_port++) {
		if (other_port == port)
			continue;

		if (sja1105_tas_check_conflicts(priv, other_port, admin))
			return -ERANGE;
	}

	if (sja1105_gating_check_conflicts(priv, port, NULL)) {
		dev_err(ds->dev, "Conflict with tc-gate schedule\n");
		return -ERANGE;
	}

	tas_data->offload[port] = taprio_offload_get(admin);

	rc = sja1105_init_scheduling(priv);
	if (rc < 0)
		return rc;

	return sja1105_static_config_reload(priv, SJA1105_SCHEDULING);
}

static int sja1105_tas_check_running(struct sja1105_private *priv)
{
	struct sja1105_tas_data *tas_data = &priv->tas_data;
	struct dsa_switch *ds = priv->ds;
	struct sja1105_ptp_cmd cmd = {0};
	int rc;

	rc = sja1105_ptp_commit(ds, &cmd, SPI_READ);
	if (rc < 0)
		return rc;

	if (cmd.ptpstrtsch == 1)
		/* Schedule successfully started */
		tas_data->state = SJA1105_TAS_STATE_RUNNING;
	else if (cmd.ptpstopsch == 1)
		/* Schedule is stopped */
		tas_data->state = SJA1105_TAS_STATE_DISABLED;
	else
		/* Schedule is probably not configured with PTP clock source */
		rc = -EINVAL;

	return rc;
}

/* Write to PTPCLKCORP */
static int sja1105_tas_adjust_drift(struct sja1105_private *priv,
				    u64 correction)
{
	const struct sja1105_regs *regs = priv->info->regs;
	u32 ptpclkcorp = ns_to_sja1105_ticks(correction);

	return sja1105_xfer_u32(priv, SPI_WRITE, regs->ptpclkcorp,
				&ptpclkcorp, NULL);
}

/* Write to PTPSCHTM */
static int sja1105_tas_set_base_time(struct sja1105_private *priv,
				     u64 base_time)
{
	const struct sja1105_regs *regs = priv->info->regs;
	u64 ptpschtm = ns_to_sja1105_ticks(base_time);

	return sja1105_xfer_u64(priv, SPI_WRITE, regs->ptpschtm,
				&ptpschtm, NULL);
}

static int sja1105_tas_start(struct sja1105_private *priv)
{
	struct sja1105_tas_data *tas_data = &priv->tas_data;
	struct sja1105_ptp_cmd *cmd = &priv->ptp_data.cmd;
	struct dsa_switch *ds = priv->ds;
	int rc;

	dev_dbg(ds->dev, "Starting the TAS\n");

	if (tas_data->state == SJA1105_TAS_STATE_ENABLED_NOT_RUNNING ||
	    tas_data->state == SJA1105_TAS_STATE_RUNNING) {
		dev_err(ds->dev, "TAS already started\n");
		return -EINVAL;
	}

	cmd->ptpstrtsch = 1;
	cmd->ptpstopsch = 0;

	rc = sja1105_ptp_commit(ds, cmd, SPI_WRITE);
	if (rc < 0)
		return rc;

	tas_data->state = SJA1105_TAS_STATE_ENABLED_NOT_RUNNING;

	return 0;
}

static int sja1105_tas_stop(struct sja1105_private *priv)
{
	struct sja1105_tas_data *tas_data = &priv->tas_data;
	struct sja1105_ptp_cmd *cmd = &priv->ptp_data.cmd;
	struct dsa_switch *ds = priv->ds;
	int rc;

	dev_dbg(ds->dev, "Stopping the TAS\n");

	if (tas_data->state == SJA1105_TAS_STATE_DISABLED) {
		dev_err(ds->dev, "TAS already disabled\n");
		return -EINVAL;
	}

	cmd->ptpstopsch = 1;
	cmd->ptpstrtsch = 0;

	rc = sja1105_ptp_commit(ds, cmd, SPI_WRITE);
	if (rc < 0)
		return rc;

	tas_data->state = SJA1105_TAS_STATE_DISABLED;

	return 0;
}

/* The schedule engine and the PTP clock are driven by the same oscillator, and
 * they run in parallel. But whilst the PTP clock can keep an absolute
 * time-of-day, the schedule engine is only running in 'ticks' (25 ticks make
 * up a delta, which is 200ns), and wrapping around at the end of each cycle.
 * The schedule engine is started when the PTP clock reaches the PTPSCHTM time
 * (in PTP domain).
 * Because the PTP clock can be rate-corrected (accelerated or slowed down) by
 * a software servo, and the schedule engine clock runs in parallel to the PTP
 * clock, there is logic internal to the switch that periodically keeps the
 * schedule engine from drifting away. The frequency with which this internal
 * syntonization happens is the PTP clock correction period (PTPCLKCORP). It is
 * a value also in the PTP clock domain, and is also rate-corrected.
 * To be precise, during a correction period, there is logic to determine by
 * how many scheduler clock ticks has the PTP clock drifted. At the end of each
 * correction period/beginning of new one, the length of a delta is shrunk or
 * expanded with an integer number of ticks, compared with the typical 25.
 * So a delta lasts for 200ns (or 25 ticks) only on average.
 * Sometimes it is longer, sometimes it is shorter. The internal syntonization
 * logic can adjust for at most 5 ticks each 20 ticks.
 *
 * The first implication is that you should choose your schedule correction
 * period to be an integer multiple of the schedule length. Preferably one.
 * In case there are schedules of multiple ports active, then the correction
 * period needs to be a multiple of them all. Given the restriction that the
 * cycle times have to be multiples of one another anyway, this means the
 * correction period can simply be the largest cycle time, hence the current
 * choice. This way, the updates are always synchronous to the transmission
 * cycle, and therefore predictable.
 *
 * The second implication is that at the beginning of a correction period, the
 * first few deltas will be modulated in time, until the schedule engine is
 * properly phase-aligned with the PTP clock. For this reason, you should place
 * your best-effort traffic at the beginning of a cycle, and your
 * time-triggered traffic afterwards.
 *
 * The third implication is that once the schedule engine is started, it can
 * only adjust for so much drift within a correction period. In the servo you
 * can only change the PTPCLKRATE, but not step the clock (PTPCLKADD). If you
 * want to do the latter, you need to stop and restart the schedule engine,
 * which is what the state machine handles.
 */
static void sja1105_tas_state_machine(struct work_struct *work)
{
	struct sja1105_tas_data *tas_data = work_to_sja1105_tas(work);
	struct sja1105_private *priv = tas_to_sja1105(tas_data);
	struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
	struct timespec64 base_time_ts, now_ts;
	struct dsa_switch *ds = priv->ds;
	struct timespec64 diff;
	s64 base_time, now;
	int rc = 0;

	mutex_lock(&ptp_data->lock);

	switch (tas_data->state) {
	case SJA1105_TAS_STATE_DISABLED:
		/* Can't do anything at all if clock is still being stepped */
		if (tas_data->last_op != SJA1105_PTP_ADJUSTFREQ)
			break;

		rc = sja1105_tas_adjust_drift(priv, tas_data->max_cycle_time);
		if (rc < 0)
			break;

		rc = __sja1105_ptp_gettimex(ds, &now, NULL);
		if (rc < 0)
			break;

		/* Plan to start the earliest schedule first. The others
		 * will be started in hardware, by way of their respective
		 * entry points delta.
		 * Try our best to avoid fringe cases (race condition between
		 * ptpschtm and ptpstrtsch) by pushing the oper_base_time at
		 * least one second in the future from now. This is not ideal,
		 * but this only needs to buy us time until the
		 * sja1105_tas_start command below gets executed.
		 */
		base_time = future_base_time(tas_data->earliest_base_time,
					     tas_data->max_cycle_time,
					     now + 1ull * NSEC_PER_SEC);
		base_time -= sja1105_delta_to_ns(1);

		rc = sja1105_tas_set_base_time(priv, base_time);
		if (rc < 0)
			break;

		tas_data->oper_base_time = base_time;

		rc = sja1105_tas_start(priv);
		if (rc < 0)
			break;

		base_time_ts = ns_to_timespec64(base_time);
		now_ts = ns_to_timespec64(now);

		dev_dbg(ds->dev, "OPER base time %lld.%09ld (now %lld.%09ld)\n",
			base_time_ts.tv_sec, base_time_ts.tv_nsec,
			now_ts.tv_sec, now_ts.tv_nsec);

		break;

	case SJA1105_TAS_STATE_ENABLED_NOT_RUNNING:
		if (tas_data->last_op != SJA1105_PTP_ADJUSTFREQ) {
			/* Clock was stepped.. bad news for TAS */
			sja1105_tas_stop(priv);
			break;
		}

		/* Check if TAS has actually started, by comparing the
		 * scheduled start time with the SJA1105 PTP clock
		 */
		rc = __sja1105_ptp_gettimex(ds, &now, NULL);
		if (rc < 0)
			break;

		if (now < tas_data->oper_base_time) {
			/* TAS has not started yet */
			diff = ns_to_timespec64(tas_data->oper_base_time - now);
			dev_dbg(ds->dev, "time to start: [%lld.%09ld]",
				diff.tv_sec, diff.tv_nsec);
			break;
		}

		/* Time elapsed, what happened? */
		rc = sja1105_tas_check_running(priv);
		if (rc < 0)
			break;

		if (tas_data->state != SJA1105_TAS_STATE_RUNNING)
			/* TAS has started */
			dev_err(ds->dev,
				"TAS not started despite time elapsed\n");

		break;

	case SJA1105_TAS_STATE_RUNNING:
		/* Clock was stepped.. bad news for TAS */
		if (tas_data->last_op != SJA1105_PTP_ADJUSTFREQ) {
			sja1105_tas_stop(priv);
			break;
		}

		rc = sja1105_tas_check_running(priv);
		if (rc < 0)
			break;

		if (tas_data->state != SJA1105_TAS_STATE_RUNNING)
			dev_err(ds->dev, "TAS surprisingly stopped\n");

		break;

	default:
		if (net_ratelimit())
			dev_err(ds->dev, "TAS in an invalid state (incorrect use of API)!\n");
	}

	if (rc && net_ratelimit())
		dev_err(ds->dev, "An operation returned %d\n", rc);

	mutex_unlock(&ptp_data->lock);
}

void sja1105_tas_clockstep(struct dsa_switch *ds)
{
	struct sja1105_private *priv = ds->priv;
	struct sja1105_tas_data *tas_data = &priv->tas_data;

	if (!tas_data->enabled)
		return;

	tas_data->last_op = SJA1105_PTP_CLOCKSTEP;
	schedule_work(&tas_data->tas_work);
}

void sja1105_tas_adjfreq(struct dsa_switch *ds)
{
	struct sja1105_private *priv = ds->priv;
	struct sja1105_tas_data *tas_data = &priv->tas_data;

	if (!tas_data->enabled)
		return;

	/* No reason to schedule the workqueue, nothing changed */
	if (tas_data->state == SJA1105_TAS_STATE_RUNNING)
		return;

	tas_data->last_op = SJA1105_PTP_ADJUSTFREQ;
	schedule_work(&tas_data->tas_work);
}

void sja1105_tas_setup(struct dsa_switch *ds)
{
	struct sja1105_private *priv = ds->priv;
	struct sja1105_tas_data *tas_data = &priv->tas_data;

	INIT_WORK(&tas_data->tas_work, sja1105_tas_state_machine);
	tas_data->state = SJA1105_TAS_STATE_DISABLED;
	tas_data->last_op = SJA1105_PTP_NONE;

	INIT_LIST_HEAD(&tas_data->gating_cfg.entries);
}

void sja1105_tas_teardown(struct dsa_switch *ds)
{
	struct sja1105_private *priv = ds->priv;
	struct tc_taprio_qopt_offload *offload;
	int port;

	cancel_work_sync(&priv->tas_data.tas_work);

	for (port = 0; port < SJA1105_NUM_PORTS; port++) {
		offload = priv->tas_data.offload[port];
		if (!offload)
			continue;

		taprio_offload_free(offload);
	}
}
