162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause
262306a36Sopenharmony_ci/* Copyright 2016-2018 NXP
362306a36Sopenharmony_ci * Copyright (c) 2018, Sensor-Technik Wiedemann GmbH
462306a36Sopenharmony_ci * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#include <linux/spi/spi.h>
762306a36Sopenharmony_ci#include <linux/packing.h>
862306a36Sopenharmony_ci#include "sja1105.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cistruct sja1105_chunk {
1162306a36Sopenharmony_ci	u8	*buf;
1262306a36Sopenharmony_ci	size_t	len;
1362306a36Sopenharmony_ci	u64	reg_addr;
1462306a36Sopenharmony_ci};
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistatic void
1762306a36Sopenharmony_cisja1105_spi_message_pack(void *buf, const struct sja1105_spi_message *msg)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	const int size = SJA1105_SIZE_SPI_MSG_HEADER;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	memset(buf, 0, size);
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	sja1105_pack(buf, &msg->access,     31, 31, size);
2462306a36Sopenharmony_ci	sja1105_pack(buf, &msg->read_count, 30, 25, size);
2562306a36Sopenharmony_ci	sja1105_pack(buf, &msg->address,    24,  4, size);
2662306a36Sopenharmony_ci}
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* If @rw is:
2962306a36Sopenharmony_ci * - SPI_WRITE: creates and sends an SPI write message at absolute
3062306a36Sopenharmony_ci *		address reg_addr, taking @len bytes from *buf
3162306a36Sopenharmony_ci * - SPI_READ:  creates and sends an SPI read message from absolute
3262306a36Sopenharmony_ci *		address reg_addr, writing @len bytes into *buf
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_cistatic int sja1105_xfer(const struct sja1105_private *priv,
3562306a36Sopenharmony_ci			sja1105_spi_rw_mode_t rw, u64 reg_addr, u8 *buf,
3662306a36Sopenharmony_ci			size_t len, struct ptp_system_timestamp *ptp_sts)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	u8 hdr_buf[SJA1105_SIZE_SPI_MSG_HEADER] = {0};
3962306a36Sopenharmony_ci	struct spi_device *spi = priv->spidev;
4062306a36Sopenharmony_ci	struct spi_transfer xfers[2] = {0};
4162306a36Sopenharmony_ci	struct spi_transfer *chunk_xfer;
4262306a36Sopenharmony_ci	struct spi_transfer *hdr_xfer;
4362306a36Sopenharmony_ci	struct sja1105_chunk chunk;
4462306a36Sopenharmony_ci	int num_chunks;
4562306a36Sopenharmony_ci	int rc, i = 0;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	num_chunks = DIV_ROUND_UP(len, priv->max_xfer_len);
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	chunk.reg_addr = reg_addr;
5062306a36Sopenharmony_ci	chunk.buf = buf;
5162306a36Sopenharmony_ci	chunk.len = min_t(size_t, len, priv->max_xfer_len);
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	hdr_xfer = &xfers[0];
5462306a36Sopenharmony_ci	chunk_xfer = &xfers[1];
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	for (i = 0; i < num_chunks; i++) {
5762306a36Sopenharmony_ci		struct spi_transfer *ptp_sts_xfer;
5862306a36Sopenharmony_ci		struct sja1105_spi_message msg;
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci		/* Populate the transfer's header buffer */
6162306a36Sopenharmony_ci		msg.address = chunk.reg_addr;
6262306a36Sopenharmony_ci		msg.access = rw;
6362306a36Sopenharmony_ci		if (rw == SPI_READ)
6462306a36Sopenharmony_ci			msg.read_count = chunk.len / 4;
6562306a36Sopenharmony_ci		else
6662306a36Sopenharmony_ci			/* Ignored */
6762306a36Sopenharmony_ci			msg.read_count = 0;
6862306a36Sopenharmony_ci		sja1105_spi_message_pack(hdr_buf, &msg);
6962306a36Sopenharmony_ci		hdr_xfer->tx_buf = hdr_buf;
7062306a36Sopenharmony_ci		hdr_xfer->len = SJA1105_SIZE_SPI_MSG_HEADER;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci		/* Populate the transfer's data buffer */
7362306a36Sopenharmony_ci		if (rw == SPI_READ)
7462306a36Sopenharmony_ci			chunk_xfer->rx_buf = chunk.buf;
7562306a36Sopenharmony_ci		else
7662306a36Sopenharmony_ci			chunk_xfer->tx_buf = chunk.buf;
7762306a36Sopenharmony_ci		chunk_xfer->len = chunk.len;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci		/* Request timestamping for the transfer. Instead of letting
8062306a36Sopenharmony_ci		 * callers specify which byte they want to timestamp, we can
8162306a36Sopenharmony_ci		 * make certain assumptions:
8262306a36Sopenharmony_ci		 * - A read operation will request a software timestamp when
8362306a36Sopenharmony_ci		 *   what's being read is the PTP time. That is snapshotted by
8462306a36Sopenharmony_ci		 *   the switch hardware at the end of the command portion
8562306a36Sopenharmony_ci		 *   (hdr_xfer).
8662306a36Sopenharmony_ci		 * - A write operation will request a software timestamp on
8762306a36Sopenharmony_ci		 *   actions that modify the PTP time. Taking clock stepping as
8862306a36Sopenharmony_ci		 *   an example, the switch writes the PTP time at the end of
8962306a36Sopenharmony_ci		 *   the data portion (chunk_xfer).
9062306a36Sopenharmony_ci		 */
9162306a36Sopenharmony_ci		if (rw == SPI_READ)
9262306a36Sopenharmony_ci			ptp_sts_xfer = hdr_xfer;
9362306a36Sopenharmony_ci		else
9462306a36Sopenharmony_ci			ptp_sts_xfer = chunk_xfer;
9562306a36Sopenharmony_ci		ptp_sts_xfer->ptp_sts_word_pre = ptp_sts_xfer->len - 1;
9662306a36Sopenharmony_ci		ptp_sts_xfer->ptp_sts_word_post = ptp_sts_xfer->len - 1;
9762306a36Sopenharmony_ci		ptp_sts_xfer->ptp_sts = ptp_sts;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci		/* Calculate next chunk */
10062306a36Sopenharmony_ci		chunk.buf += chunk.len;
10162306a36Sopenharmony_ci		chunk.reg_addr += chunk.len / 4;
10262306a36Sopenharmony_ci		chunk.len = min_t(size_t, (ptrdiff_t)(buf + len - chunk.buf),
10362306a36Sopenharmony_ci				  priv->max_xfer_len);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci		rc = spi_sync_transfer(spi, xfers, 2);
10662306a36Sopenharmony_ci		if (rc < 0) {
10762306a36Sopenharmony_ci			dev_err(&spi->dev, "SPI transfer failed: %d\n", rc);
10862306a36Sopenharmony_ci			return rc;
10962306a36Sopenharmony_ci		}
11062306a36Sopenharmony_ci	}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	return 0;
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciint sja1105_xfer_buf(const struct sja1105_private *priv,
11662306a36Sopenharmony_ci		     sja1105_spi_rw_mode_t rw, u64 reg_addr,
11762306a36Sopenharmony_ci		     u8 *buf, size_t len)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	return sja1105_xfer(priv, rw, reg_addr, buf, len, NULL);
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci/* If @rw is:
12362306a36Sopenharmony_ci * - SPI_WRITE: creates and sends an SPI write message at absolute
12462306a36Sopenharmony_ci *		address reg_addr
12562306a36Sopenharmony_ci * - SPI_READ:  creates and sends an SPI read message from absolute
12662306a36Sopenharmony_ci *		address reg_addr
12762306a36Sopenharmony_ci *
12862306a36Sopenharmony_ci * The u64 *value is unpacked, meaning that it's stored in the native
12962306a36Sopenharmony_ci * CPU endianness and directly usable by software running on the core.
13062306a36Sopenharmony_ci */
13162306a36Sopenharmony_ciint sja1105_xfer_u64(const struct sja1105_private *priv,
13262306a36Sopenharmony_ci		     sja1105_spi_rw_mode_t rw, u64 reg_addr, u64 *value,
13362306a36Sopenharmony_ci		     struct ptp_system_timestamp *ptp_sts)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	u8 packed_buf[8];
13662306a36Sopenharmony_ci	int rc;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	if (rw == SPI_WRITE)
13962306a36Sopenharmony_ci		sja1105_pack(packed_buf, value, 63, 0, 8);
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	rc = sja1105_xfer(priv, rw, reg_addr, packed_buf, 8, ptp_sts);
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	if (rw == SPI_READ)
14462306a36Sopenharmony_ci		sja1105_unpack(packed_buf, value, 63, 0, 8);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	return rc;
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci/* Same as above, but transfers only a 4 byte word */
15062306a36Sopenharmony_ciint sja1105_xfer_u32(const struct sja1105_private *priv,
15162306a36Sopenharmony_ci		     sja1105_spi_rw_mode_t rw, u64 reg_addr, u32 *value,
15262306a36Sopenharmony_ci		     struct ptp_system_timestamp *ptp_sts)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	u8 packed_buf[4];
15562306a36Sopenharmony_ci	u64 tmp;
15662306a36Sopenharmony_ci	int rc;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	if (rw == SPI_WRITE) {
15962306a36Sopenharmony_ci		/* The packing API only supports u64 as CPU word size,
16062306a36Sopenharmony_ci		 * so we need to convert.
16162306a36Sopenharmony_ci		 */
16262306a36Sopenharmony_ci		tmp = *value;
16362306a36Sopenharmony_ci		sja1105_pack(packed_buf, &tmp, 31, 0, 4);
16462306a36Sopenharmony_ci	}
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	rc = sja1105_xfer(priv, rw, reg_addr, packed_buf, 4, ptp_sts);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	if (rw == SPI_READ) {
16962306a36Sopenharmony_ci		sja1105_unpack(packed_buf, &tmp, 31, 0, 4);
17062306a36Sopenharmony_ci		*value = tmp;
17162306a36Sopenharmony_ci	}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	return rc;
17462306a36Sopenharmony_ci}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_cistatic int sja1105et_reset_cmd(struct dsa_switch *ds)
17762306a36Sopenharmony_ci{
17862306a36Sopenharmony_ci	struct sja1105_private *priv = ds->priv;
17962306a36Sopenharmony_ci	const struct sja1105_regs *regs = priv->info->regs;
18062306a36Sopenharmony_ci	u32 cold_reset = BIT(3);
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	/* Cold reset */
18362306a36Sopenharmony_ci	return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_cistatic int sja1105pqrs_reset_cmd(struct dsa_switch *ds)
18762306a36Sopenharmony_ci{
18862306a36Sopenharmony_ci	struct sja1105_private *priv = ds->priv;
18962306a36Sopenharmony_ci	const struct sja1105_regs *regs = priv->info->regs;
19062306a36Sopenharmony_ci	u32 cold_reset = BIT(2);
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	/* Cold reset */
19362306a36Sopenharmony_ci	return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cistatic int sja1110_reset_cmd(struct dsa_switch *ds)
19762306a36Sopenharmony_ci{
19862306a36Sopenharmony_ci	struct sja1105_private *priv = ds->priv;
19962306a36Sopenharmony_ci	const struct sja1105_regs *regs = priv->info->regs;
20062306a36Sopenharmony_ci	u32 switch_reset = BIT(20);
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	/* Only reset the switch core.
20362306a36Sopenharmony_ci	 * A full cold reset would re-enable the BASE_MCSS_CLOCK PLL which
20462306a36Sopenharmony_ci	 * would turn on the microcontroller, potentially letting it execute
20562306a36Sopenharmony_ci	 * code which could interfere with our configuration.
20662306a36Sopenharmony_ci	 */
20762306a36Sopenharmony_ci	return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &switch_reset, NULL);
20862306a36Sopenharmony_ci}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ciint sja1105_inhibit_tx(const struct sja1105_private *priv,
21162306a36Sopenharmony_ci		       unsigned long port_bitmap, bool tx_inhibited)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	const struct sja1105_regs *regs = priv->info->regs;
21462306a36Sopenharmony_ci	u32 inhibit_cmd;
21562306a36Sopenharmony_ci	int rc;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	rc = sja1105_xfer_u32(priv, SPI_READ, regs->port_control,
21862306a36Sopenharmony_ci			      &inhibit_cmd, NULL);
21962306a36Sopenharmony_ci	if (rc < 0)
22062306a36Sopenharmony_ci		return rc;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	if (tx_inhibited)
22362306a36Sopenharmony_ci		inhibit_cmd |= port_bitmap;
22462306a36Sopenharmony_ci	else
22562306a36Sopenharmony_ci		inhibit_cmd &= ~port_bitmap;
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	return sja1105_xfer_u32(priv, SPI_WRITE, regs->port_control,
22862306a36Sopenharmony_ci				&inhibit_cmd, NULL);
22962306a36Sopenharmony_ci}
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_cistruct sja1105_status {
23262306a36Sopenharmony_ci	u64 configs;
23362306a36Sopenharmony_ci	u64 crcchkl;
23462306a36Sopenharmony_ci	u64 ids;
23562306a36Sopenharmony_ci	u64 crcchkg;
23662306a36Sopenharmony_ci};
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci/* This is not reading the entire General Status area, which is also
23962306a36Sopenharmony_ci * divergent between E/T and P/Q/R/S, but only the relevant bits for
24062306a36Sopenharmony_ci * ensuring that the static config upload procedure was successful.
24162306a36Sopenharmony_ci */
24262306a36Sopenharmony_cistatic void sja1105_status_unpack(void *buf, struct sja1105_status *status)
24362306a36Sopenharmony_ci{
24462306a36Sopenharmony_ci	/* So that addition translates to 4 bytes */
24562306a36Sopenharmony_ci	u32 *p = buf;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	/* device_id is missing from the buffer, but we don't
24862306a36Sopenharmony_ci	 * want to diverge from the manual definition of the
24962306a36Sopenharmony_ci	 * register addresses, so we'll back off one step with
25062306a36Sopenharmony_ci	 * the register pointer, and never access p[0].
25162306a36Sopenharmony_ci	 */
25262306a36Sopenharmony_ci	p--;
25362306a36Sopenharmony_ci	sja1105_unpack(p + 0x1, &status->configs,   31, 31, 4);
25462306a36Sopenharmony_ci	sja1105_unpack(p + 0x1, &status->crcchkl,   30, 30, 4);
25562306a36Sopenharmony_ci	sja1105_unpack(p + 0x1, &status->ids,       29, 29, 4);
25662306a36Sopenharmony_ci	sja1105_unpack(p + 0x1, &status->crcchkg,   28, 28, 4);
25762306a36Sopenharmony_ci}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_cistatic int sja1105_status_get(struct sja1105_private *priv,
26062306a36Sopenharmony_ci			      struct sja1105_status *status)
26162306a36Sopenharmony_ci{
26262306a36Sopenharmony_ci	const struct sja1105_regs *regs = priv->info->regs;
26362306a36Sopenharmony_ci	u8 packed_buf[4];
26462306a36Sopenharmony_ci	int rc;
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	rc = sja1105_xfer_buf(priv, SPI_READ, regs->status, packed_buf, 4);
26762306a36Sopenharmony_ci	if (rc < 0)
26862306a36Sopenharmony_ci		return rc;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	sja1105_status_unpack(packed_buf, status);
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	return 0;
27362306a36Sopenharmony_ci}
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci/* Not const because unpacking priv->static_config into buffers and preparing
27662306a36Sopenharmony_ci * for upload requires the recalculation of table CRCs and updating the
27762306a36Sopenharmony_ci * structures with these.
27862306a36Sopenharmony_ci */
27962306a36Sopenharmony_ciint static_config_buf_prepare_for_upload(struct sja1105_private *priv,
28062306a36Sopenharmony_ci					 void *config_buf, int buf_len)
28162306a36Sopenharmony_ci{
28262306a36Sopenharmony_ci	struct sja1105_static_config *config = &priv->static_config;
28362306a36Sopenharmony_ci	struct sja1105_table_header final_header;
28462306a36Sopenharmony_ci	sja1105_config_valid_t valid;
28562306a36Sopenharmony_ci	char *final_header_ptr;
28662306a36Sopenharmony_ci	int crc_len;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	valid = sja1105_static_config_check_valid(config,
28962306a36Sopenharmony_ci						  priv->info->max_frame_mem);
29062306a36Sopenharmony_ci	if (valid != SJA1105_CONFIG_OK) {
29162306a36Sopenharmony_ci		dev_err(&priv->spidev->dev,
29262306a36Sopenharmony_ci			sja1105_static_config_error_msg[valid]);
29362306a36Sopenharmony_ci		return -EINVAL;
29462306a36Sopenharmony_ci	}
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	/* Write Device ID and config tables to config_buf */
29762306a36Sopenharmony_ci	sja1105_static_config_pack(config_buf, config);
29862306a36Sopenharmony_ci	/* Recalculate CRC of the last header (right now 0xDEADBEEF).
29962306a36Sopenharmony_ci	 * Don't include the CRC field itself.
30062306a36Sopenharmony_ci	 */
30162306a36Sopenharmony_ci	crc_len = buf_len - 4;
30262306a36Sopenharmony_ci	/* Read the whole table header */
30362306a36Sopenharmony_ci	final_header_ptr = config_buf + buf_len - SJA1105_SIZE_TABLE_HEADER;
30462306a36Sopenharmony_ci	sja1105_table_header_packing(final_header_ptr, &final_header, UNPACK);
30562306a36Sopenharmony_ci	/* Modify */
30662306a36Sopenharmony_ci	final_header.crc = sja1105_crc32(config_buf, crc_len);
30762306a36Sopenharmony_ci	/* Rewrite */
30862306a36Sopenharmony_ci	sja1105_table_header_packing(final_header_ptr, &final_header, PACK);
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	return 0;
31162306a36Sopenharmony_ci}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci#define RETRIES 10
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ciint sja1105_static_config_upload(struct sja1105_private *priv)
31662306a36Sopenharmony_ci{
31762306a36Sopenharmony_ci	struct sja1105_static_config *config = &priv->static_config;
31862306a36Sopenharmony_ci	const struct sja1105_regs *regs = priv->info->regs;
31962306a36Sopenharmony_ci	struct device *dev = &priv->spidev->dev;
32062306a36Sopenharmony_ci	struct dsa_switch *ds = priv->ds;
32162306a36Sopenharmony_ci	struct sja1105_status status;
32262306a36Sopenharmony_ci	int rc, retries = RETRIES;
32362306a36Sopenharmony_ci	u8 *config_buf;
32462306a36Sopenharmony_ci	int buf_len;
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci	buf_len = sja1105_static_config_get_length(config);
32762306a36Sopenharmony_ci	config_buf = kcalloc(buf_len, sizeof(char), GFP_KERNEL);
32862306a36Sopenharmony_ci	if (!config_buf)
32962306a36Sopenharmony_ci		return -ENOMEM;
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	rc = static_config_buf_prepare_for_upload(priv, config_buf, buf_len);
33262306a36Sopenharmony_ci	if (rc < 0) {
33362306a36Sopenharmony_ci		dev_err(dev, "Invalid config, cannot upload\n");
33462306a36Sopenharmony_ci		rc = -EINVAL;
33562306a36Sopenharmony_ci		goto out;
33662306a36Sopenharmony_ci	}
33762306a36Sopenharmony_ci	/* Prevent PHY jabbering during switch reset by inhibiting
33862306a36Sopenharmony_ci	 * Tx on all ports and waiting for current packet to drain.
33962306a36Sopenharmony_ci	 * Otherwise, the PHY will see an unterminated Ethernet packet.
34062306a36Sopenharmony_ci	 */
34162306a36Sopenharmony_ci	rc = sja1105_inhibit_tx(priv, GENMASK_ULL(ds->num_ports - 1, 0), true);
34262306a36Sopenharmony_ci	if (rc < 0) {
34362306a36Sopenharmony_ci		dev_err(dev, "Failed to inhibit Tx on ports\n");
34462306a36Sopenharmony_ci		rc = -ENXIO;
34562306a36Sopenharmony_ci		goto out;
34662306a36Sopenharmony_ci	}
34762306a36Sopenharmony_ci	/* Wait for an eventual egress packet to finish transmission
34862306a36Sopenharmony_ci	 * (reach IFG). It is guaranteed that a second one will not
34962306a36Sopenharmony_ci	 * follow, and that switch cold reset is thus safe
35062306a36Sopenharmony_ci	 */
35162306a36Sopenharmony_ci	usleep_range(500, 1000);
35262306a36Sopenharmony_ci	do {
35362306a36Sopenharmony_ci		/* Put the SJA1105 in programming mode */
35462306a36Sopenharmony_ci		rc = priv->info->reset_cmd(priv->ds);
35562306a36Sopenharmony_ci		if (rc < 0) {
35662306a36Sopenharmony_ci			dev_err(dev, "Failed to reset switch, retrying...\n");
35762306a36Sopenharmony_ci			continue;
35862306a36Sopenharmony_ci		}
35962306a36Sopenharmony_ci		/* Wait for the switch to come out of reset */
36062306a36Sopenharmony_ci		usleep_range(1000, 5000);
36162306a36Sopenharmony_ci		/* Upload the static config to the device */
36262306a36Sopenharmony_ci		rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->config,
36362306a36Sopenharmony_ci				      config_buf, buf_len);
36462306a36Sopenharmony_ci		if (rc < 0) {
36562306a36Sopenharmony_ci			dev_err(dev, "Failed to upload config, retrying...\n");
36662306a36Sopenharmony_ci			continue;
36762306a36Sopenharmony_ci		}
36862306a36Sopenharmony_ci		/* Check that SJA1105 responded well to the config upload */
36962306a36Sopenharmony_ci		rc = sja1105_status_get(priv, &status);
37062306a36Sopenharmony_ci		if (rc < 0)
37162306a36Sopenharmony_ci			continue;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci		if (status.ids == 1) {
37462306a36Sopenharmony_ci			dev_err(dev, "Mismatch between hardware and static config "
37562306a36Sopenharmony_ci				"device id. Wrote 0x%llx, wants 0x%llx\n",
37662306a36Sopenharmony_ci				config->device_id, priv->info->device_id);
37762306a36Sopenharmony_ci			continue;
37862306a36Sopenharmony_ci		}
37962306a36Sopenharmony_ci		if (status.crcchkl == 1) {
38062306a36Sopenharmony_ci			dev_err(dev, "Switch reported invalid local CRC on "
38162306a36Sopenharmony_ci				"the uploaded config, retrying...\n");
38262306a36Sopenharmony_ci			continue;
38362306a36Sopenharmony_ci		}
38462306a36Sopenharmony_ci		if (status.crcchkg == 1) {
38562306a36Sopenharmony_ci			dev_err(dev, "Switch reported invalid global CRC on "
38662306a36Sopenharmony_ci				"the uploaded config, retrying...\n");
38762306a36Sopenharmony_ci			continue;
38862306a36Sopenharmony_ci		}
38962306a36Sopenharmony_ci		if (status.configs == 0) {
39062306a36Sopenharmony_ci			dev_err(dev, "Switch reported that configuration is "
39162306a36Sopenharmony_ci				"invalid, retrying...\n");
39262306a36Sopenharmony_ci			continue;
39362306a36Sopenharmony_ci		}
39462306a36Sopenharmony_ci		/* Success! */
39562306a36Sopenharmony_ci		break;
39662306a36Sopenharmony_ci	} while (--retries);
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	if (!retries) {
39962306a36Sopenharmony_ci		rc = -EIO;
40062306a36Sopenharmony_ci		dev_err(dev, "Failed to upload config to device, giving up\n");
40162306a36Sopenharmony_ci		goto out;
40262306a36Sopenharmony_ci	} else if (retries != RETRIES) {
40362306a36Sopenharmony_ci		dev_info(dev, "Succeeded after %d tried\n", RETRIES - retries);
40462306a36Sopenharmony_ci	}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ciout:
40762306a36Sopenharmony_ci	kfree(config_buf);
40862306a36Sopenharmony_ci	return rc;
40962306a36Sopenharmony_ci}
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_cistatic const struct sja1105_regs sja1105et_regs = {
41262306a36Sopenharmony_ci	.device_id = 0x0,
41362306a36Sopenharmony_ci	.prod_id = 0x100BC3,
41462306a36Sopenharmony_ci	.status = 0x1,
41562306a36Sopenharmony_ci	.port_control = 0x11,
41662306a36Sopenharmony_ci	.vl_status = 0x10000,
41762306a36Sopenharmony_ci	.config = 0x020000,
41862306a36Sopenharmony_ci	.rgu = 0x100440,
41962306a36Sopenharmony_ci	/* UM10944.pdf, Table 86, ACU Register overview */
42062306a36Sopenharmony_ci	.pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
42162306a36Sopenharmony_ci	.pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
42262306a36Sopenharmony_ci	.rmii_pll1 = 0x10000A,
42362306a36Sopenharmony_ci	.cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
42462306a36Sopenharmony_ci	.stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208},
42562306a36Sopenharmony_ci	.stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440},
42662306a36Sopenharmony_ci	.stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640},
42762306a36Sopenharmony_ci	/* UM10944.pdf, Table 78, CGU Register overview */
42862306a36Sopenharmony_ci	.mii_tx_clk = {0x100013, 0x10001A, 0x100021, 0x100028, 0x10002F},
42962306a36Sopenharmony_ci	.mii_rx_clk = {0x100014, 0x10001B, 0x100022, 0x100029, 0x100030},
43062306a36Sopenharmony_ci	.mii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
43162306a36Sopenharmony_ci	.mii_ext_rx_clk = {0x100019, 0x100020, 0x100027, 0x10002E, 0x100035},
43262306a36Sopenharmony_ci	.rgmii_tx_clk = {0x100016, 0x10001D, 0x100024, 0x10002B, 0x100032},
43362306a36Sopenharmony_ci	.rmii_ref_clk = {0x100015, 0x10001C, 0x100023, 0x10002A, 0x100031},
43462306a36Sopenharmony_ci	.rmii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
43562306a36Sopenharmony_ci	.ptpegr_ts = {0xC0, 0xC2, 0xC4, 0xC6, 0xC8},
43662306a36Sopenharmony_ci	.ptpschtm = 0x12, /* Spans 0x12 to 0x13 */
43762306a36Sopenharmony_ci	.ptppinst = 0x14,
43862306a36Sopenharmony_ci	.ptppindur = 0x16,
43962306a36Sopenharmony_ci	.ptp_control = 0x17,
44062306a36Sopenharmony_ci	.ptpclkval = 0x18, /* Spans 0x18 to 0x19 */
44162306a36Sopenharmony_ci	.ptpclkrate = 0x1A,
44262306a36Sopenharmony_ci	.ptpclkcorp = 0x1D,
44362306a36Sopenharmony_ci	.mdio_100base_tx = SJA1105_RSV_ADDR,
44462306a36Sopenharmony_ci	.mdio_100base_t1 = SJA1105_RSV_ADDR,
44562306a36Sopenharmony_ci};
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_cistatic const struct sja1105_regs sja1105pqrs_regs = {
44862306a36Sopenharmony_ci	.device_id = 0x0,
44962306a36Sopenharmony_ci	.prod_id = 0x100BC3,
45062306a36Sopenharmony_ci	.status = 0x1,
45162306a36Sopenharmony_ci	.port_control = 0x12,
45262306a36Sopenharmony_ci	.vl_status = 0x10000,
45362306a36Sopenharmony_ci	.config = 0x020000,
45462306a36Sopenharmony_ci	.rgu = 0x100440,
45562306a36Sopenharmony_ci	/* UM10944.pdf, Table 86, ACU Register overview */
45662306a36Sopenharmony_ci	.pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
45762306a36Sopenharmony_ci	.pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
45862306a36Sopenharmony_ci	.pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814},
45962306a36Sopenharmony_ci	.rmii_pll1 = 0x10000A,
46062306a36Sopenharmony_ci	.cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
46162306a36Sopenharmony_ci	.stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208},
46262306a36Sopenharmony_ci	.stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440},
46362306a36Sopenharmony_ci	.stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640},
46462306a36Sopenharmony_ci	.stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460},
46562306a36Sopenharmony_ci	/* UM11040.pdf, Table 114 */
46662306a36Sopenharmony_ci	.mii_tx_clk = {0x100013, 0x100019, 0x10001F, 0x100025, 0x10002B},
46762306a36Sopenharmony_ci	.mii_rx_clk = {0x100014, 0x10001A, 0x100020, 0x100026, 0x10002C},
46862306a36Sopenharmony_ci	.mii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
46962306a36Sopenharmony_ci	.mii_ext_rx_clk = {0x100018, 0x10001E, 0x100024, 0x10002A, 0x100030},
47062306a36Sopenharmony_ci	.rgmii_tx_clk = {0x100016, 0x10001C, 0x100022, 0x100028, 0x10002E},
47162306a36Sopenharmony_ci	.rmii_ref_clk = {0x100015, 0x10001B, 0x100021, 0x100027, 0x10002D},
47262306a36Sopenharmony_ci	.rmii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
47362306a36Sopenharmony_ci	.ptpegr_ts = {0xC0, 0xC4, 0xC8, 0xCC, 0xD0},
47462306a36Sopenharmony_ci	.ptpschtm = 0x13, /* Spans 0x13 to 0x14 */
47562306a36Sopenharmony_ci	.ptppinst = 0x15,
47662306a36Sopenharmony_ci	.ptppindur = 0x17,
47762306a36Sopenharmony_ci	.ptp_control = 0x18,
47862306a36Sopenharmony_ci	.ptpclkval = 0x19,
47962306a36Sopenharmony_ci	.ptpclkrate = 0x1B,
48062306a36Sopenharmony_ci	.ptpclkcorp = 0x1E,
48162306a36Sopenharmony_ci	.ptpsyncts = 0x1F,
48262306a36Sopenharmony_ci	.mdio_100base_tx = SJA1105_RSV_ADDR,
48362306a36Sopenharmony_ci	.mdio_100base_t1 = SJA1105_RSV_ADDR,
48462306a36Sopenharmony_ci};
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_cistatic const struct sja1105_regs sja1110_regs = {
48762306a36Sopenharmony_ci	.device_id = SJA1110_SPI_ADDR(0x0),
48862306a36Sopenharmony_ci	.prod_id = SJA1110_ACU_ADDR(0xf00),
48962306a36Sopenharmony_ci	.status = SJA1110_SPI_ADDR(0x4),
49062306a36Sopenharmony_ci	.port_control = SJA1110_SPI_ADDR(0x50), /* actually INHIB_TX */
49162306a36Sopenharmony_ci	.vl_status = 0x10000,
49262306a36Sopenharmony_ci	.config = 0x020000,
49362306a36Sopenharmony_ci	.rgu = SJA1110_RGU_ADDR(0x100), /* Reset Control Register 0 */
49462306a36Sopenharmony_ci	/* Ports 2 and 3 are capable of xMII, but there isn't anything to
49562306a36Sopenharmony_ci	 * configure in the CGU/ACU for them.
49662306a36Sopenharmony_ci	 */
49762306a36Sopenharmony_ci	.pad_mii_tx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
49862306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
49962306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
50062306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
50162306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
50262306a36Sopenharmony_ci		       SJA1105_RSV_ADDR},
50362306a36Sopenharmony_ci	.pad_mii_rx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
50462306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
50562306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
50662306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
50762306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
50862306a36Sopenharmony_ci		       SJA1105_RSV_ADDR},
50962306a36Sopenharmony_ci	.pad_mii_id = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
51062306a36Sopenharmony_ci		       SJA1110_ACU_ADDR(0x18), SJA1110_ACU_ADDR(0x28),
51162306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
51262306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
51362306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
51462306a36Sopenharmony_ci		       SJA1105_RSV_ADDR},
51562306a36Sopenharmony_ci	.rmii_pll1 = SJA1105_RSV_ADDR,
51662306a36Sopenharmony_ci	.cgu_idiv = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
51762306a36Sopenharmony_ci		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
51862306a36Sopenharmony_ci		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
51962306a36Sopenharmony_ci		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
52062306a36Sopenharmony_ci	.stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208, 0x20a,
52162306a36Sopenharmony_ci		       0x20c, 0x20e, 0x210, 0x212, 0x214},
52262306a36Sopenharmony_ci	.stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440, 0x450,
52362306a36Sopenharmony_ci		       0x460, 0x470, 0x480, 0x490, 0x4a0},
52462306a36Sopenharmony_ci	.stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640, 0x650,
52562306a36Sopenharmony_ci		       0x660, 0x670, 0x680, 0x690, 0x6a0},
52662306a36Sopenharmony_ci	.stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460, 0x1478,
52762306a36Sopenharmony_ci			 0x1490, 0x14a8, 0x14c0, 0x14d8, 0x14f0},
52862306a36Sopenharmony_ci	.mii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
52962306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
53062306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
53162306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
53262306a36Sopenharmony_ci	.mii_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
53362306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
53462306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
53562306a36Sopenharmony_ci		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
53662306a36Sopenharmony_ci	.mii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
53762306a36Sopenharmony_ci			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
53862306a36Sopenharmony_ci			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
53962306a36Sopenharmony_ci			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
54062306a36Sopenharmony_ci	.mii_ext_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
54162306a36Sopenharmony_ci			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
54262306a36Sopenharmony_ci			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
54362306a36Sopenharmony_ci			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
54462306a36Sopenharmony_ci	.rgmii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
54562306a36Sopenharmony_ci			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
54662306a36Sopenharmony_ci			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
54762306a36Sopenharmony_ci			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
54862306a36Sopenharmony_ci	.rmii_ref_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
54962306a36Sopenharmony_ci			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
55062306a36Sopenharmony_ci			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
55162306a36Sopenharmony_ci			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
55262306a36Sopenharmony_ci	.rmii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
55362306a36Sopenharmony_ci			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
55462306a36Sopenharmony_ci			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
55562306a36Sopenharmony_ci			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
55662306a36Sopenharmony_ci			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
55762306a36Sopenharmony_ci			    SJA1105_RSV_ADDR},
55862306a36Sopenharmony_ci	.ptpschtm = SJA1110_SPI_ADDR(0x54),
55962306a36Sopenharmony_ci	.ptppinst = SJA1110_SPI_ADDR(0x5c),
56062306a36Sopenharmony_ci	.ptppindur = SJA1110_SPI_ADDR(0x64),
56162306a36Sopenharmony_ci	.ptp_control = SJA1110_SPI_ADDR(0x68),
56262306a36Sopenharmony_ci	.ptpclkval = SJA1110_SPI_ADDR(0x6c),
56362306a36Sopenharmony_ci	.ptpclkrate = SJA1110_SPI_ADDR(0x74),
56462306a36Sopenharmony_ci	.ptpclkcorp = SJA1110_SPI_ADDR(0x80),
56562306a36Sopenharmony_ci	.ptpsyncts = SJA1110_SPI_ADDR(0x84),
56662306a36Sopenharmony_ci	.mdio_100base_tx = 0x1c2400,
56762306a36Sopenharmony_ci	.mdio_100base_t1 = 0x1c1000,
56862306a36Sopenharmony_ci	.pcs_base = {SJA1105_RSV_ADDR, 0x1c1400, 0x1c1800, 0x1c1c00, 0x1c2000,
56962306a36Sopenharmony_ci		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
57062306a36Sopenharmony_ci		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
57162306a36Sopenharmony_ci};
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ciconst struct sja1105_info sja1105e_info = {
57462306a36Sopenharmony_ci	.device_id		= SJA1105E_DEVICE_ID,
57562306a36Sopenharmony_ci	.part_no		= SJA1105ET_PART_NO,
57662306a36Sopenharmony_ci	.static_ops		= sja1105e_table_ops,
57762306a36Sopenharmony_ci	.dyn_ops		= sja1105et_dyn_ops,
57862306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1105,
57962306a36Sopenharmony_ci	.can_limit_mcast_flood	= false,
58062306a36Sopenharmony_ci	.ptp_ts_bits		= 24,
58162306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 4,
58262306a36Sopenharmony_ci	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
58362306a36Sopenharmony_ci	.num_ports		= SJA1105_NUM_PORTS,
58462306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1105ET_MAX_CBS_COUNT,
58562306a36Sopenharmony_ci	.reset_cmd		= sja1105et_reset_cmd,
58662306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105et_fdb_add,
58762306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105et_fdb_del,
58862306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105et_ptp_cmd_packing,
58962306a36Sopenharmony_ci	.rxtstamp		= sja1105_rxtstamp,
59062306a36Sopenharmony_ci	.clocking_setup		= sja1105_clocking_setup,
59162306a36Sopenharmony_ci	.regs			= &sja1105et_regs,
59262306a36Sopenharmony_ci	.port_speed		= {
59362306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
59462306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 3,
59562306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 2,
59662306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 1,
59762306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
59862306a36Sopenharmony_ci	},
59962306a36Sopenharmony_ci	.supports_mii		= {true, true, true, true, true},
60062306a36Sopenharmony_ci	.supports_rmii		= {true, true, true, true, true},
60162306a36Sopenharmony_ci	.supports_rgmii		= {true, true, true, true, true},
60262306a36Sopenharmony_ci	.name			= "SJA1105E",
60362306a36Sopenharmony_ci};
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ciconst struct sja1105_info sja1105t_info = {
60662306a36Sopenharmony_ci	.device_id		= SJA1105T_DEVICE_ID,
60762306a36Sopenharmony_ci	.part_no		= SJA1105ET_PART_NO,
60862306a36Sopenharmony_ci	.static_ops		= sja1105t_table_ops,
60962306a36Sopenharmony_ci	.dyn_ops		= sja1105et_dyn_ops,
61062306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1105,
61162306a36Sopenharmony_ci	.can_limit_mcast_flood	= false,
61262306a36Sopenharmony_ci	.ptp_ts_bits		= 24,
61362306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 4,
61462306a36Sopenharmony_ci	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
61562306a36Sopenharmony_ci	.num_ports		= SJA1105_NUM_PORTS,
61662306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1105ET_MAX_CBS_COUNT,
61762306a36Sopenharmony_ci	.reset_cmd		= sja1105et_reset_cmd,
61862306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105et_fdb_add,
61962306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105et_fdb_del,
62062306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105et_ptp_cmd_packing,
62162306a36Sopenharmony_ci	.rxtstamp		= sja1105_rxtstamp,
62262306a36Sopenharmony_ci	.clocking_setup		= sja1105_clocking_setup,
62362306a36Sopenharmony_ci	.regs			= &sja1105et_regs,
62462306a36Sopenharmony_ci	.port_speed		= {
62562306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
62662306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 3,
62762306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 2,
62862306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 1,
62962306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
63062306a36Sopenharmony_ci	},
63162306a36Sopenharmony_ci	.supports_mii		= {true, true, true, true, true},
63262306a36Sopenharmony_ci	.supports_rmii		= {true, true, true, true, true},
63362306a36Sopenharmony_ci	.supports_rgmii		= {true, true, true, true, true},
63462306a36Sopenharmony_ci	.name			= "SJA1105T",
63562306a36Sopenharmony_ci};
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ciconst struct sja1105_info sja1105p_info = {
63862306a36Sopenharmony_ci	.device_id		= SJA1105PR_DEVICE_ID,
63962306a36Sopenharmony_ci	.part_no		= SJA1105P_PART_NO,
64062306a36Sopenharmony_ci	.static_ops		= sja1105p_table_ops,
64162306a36Sopenharmony_ci	.dyn_ops		= sja1105pqrs_dyn_ops,
64262306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1105,
64362306a36Sopenharmony_ci	.can_limit_mcast_flood	= true,
64462306a36Sopenharmony_ci	.ptp_ts_bits		= 32,
64562306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 8,
64662306a36Sopenharmony_ci	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
64762306a36Sopenharmony_ci	.num_ports		= SJA1105_NUM_PORTS,
64862306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,
64962306a36Sopenharmony_ci	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,
65062306a36Sopenharmony_ci	.reset_cmd		= sja1105pqrs_reset_cmd,
65162306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105pqrs_fdb_add,
65262306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105pqrs_fdb_del,
65362306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
65462306a36Sopenharmony_ci	.rxtstamp		= sja1105_rxtstamp,
65562306a36Sopenharmony_ci	.clocking_setup		= sja1105_clocking_setup,
65662306a36Sopenharmony_ci	.regs			= &sja1105pqrs_regs,
65762306a36Sopenharmony_ci	.port_speed		= {
65862306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
65962306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 3,
66062306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 2,
66162306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 1,
66262306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
66362306a36Sopenharmony_ci	},
66462306a36Sopenharmony_ci	.supports_mii		= {true, true, true, true, true},
66562306a36Sopenharmony_ci	.supports_rmii		= {true, true, true, true, true},
66662306a36Sopenharmony_ci	.supports_rgmii		= {true, true, true, true, true},
66762306a36Sopenharmony_ci	.name			= "SJA1105P",
66862306a36Sopenharmony_ci};
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ciconst struct sja1105_info sja1105q_info = {
67162306a36Sopenharmony_ci	.device_id		= SJA1105QS_DEVICE_ID,
67262306a36Sopenharmony_ci	.part_no		= SJA1105Q_PART_NO,
67362306a36Sopenharmony_ci	.static_ops		= sja1105q_table_ops,
67462306a36Sopenharmony_ci	.dyn_ops		= sja1105pqrs_dyn_ops,
67562306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1105,
67662306a36Sopenharmony_ci	.can_limit_mcast_flood	= true,
67762306a36Sopenharmony_ci	.ptp_ts_bits		= 32,
67862306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 8,
67962306a36Sopenharmony_ci	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
68062306a36Sopenharmony_ci	.num_ports		= SJA1105_NUM_PORTS,
68162306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,
68262306a36Sopenharmony_ci	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,
68362306a36Sopenharmony_ci	.reset_cmd		= sja1105pqrs_reset_cmd,
68462306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105pqrs_fdb_add,
68562306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105pqrs_fdb_del,
68662306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
68762306a36Sopenharmony_ci	.rxtstamp		= sja1105_rxtstamp,
68862306a36Sopenharmony_ci	.clocking_setup		= sja1105_clocking_setup,
68962306a36Sopenharmony_ci	.regs			= &sja1105pqrs_regs,
69062306a36Sopenharmony_ci	.port_speed		= {
69162306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
69262306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 3,
69362306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 2,
69462306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 1,
69562306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
69662306a36Sopenharmony_ci	},
69762306a36Sopenharmony_ci	.supports_mii		= {true, true, true, true, true},
69862306a36Sopenharmony_ci	.supports_rmii		= {true, true, true, true, true},
69962306a36Sopenharmony_ci	.supports_rgmii		= {true, true, true, true, true},
70062306a36Sopenharmony_ci	.name			= "SJA1105Q",
70162306a36Sopenharmony_ci};
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ciconst struct sja1105_info sja1105r_info = {
70462306a36Sopenharmony_ci	.device_id		= SJA1105PR_DEVICE_ID,
70562306a36Sopenharmony_ci	.part_no		= SJA1105R_PART_NO,
70662306a36Sopenharmony_ci	.static_ops		= sja1105r_table_ops,
70762306a36Sopenharmony_ci	.dyn_ops		= sja1105pqrs_dyn_ops,
70862306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1105,
70962306a36Sopenharmony_ci	.can_limit_mcast_flood	= true,
71062306a36Sopenharmony_ci	.ptp_ts_bits		= 32,
71162306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 8,
71262306a36Sopenharmony_ci	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
71362306a36Sopenharmony_ci	.num_ports		= SJA1105_NUM_PORTS,
71462306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,
71562306a36Sopenharmony_ci	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,
71662306a36Sopenharmony_ci	.reset_cmd		= sja1105pqrs_reset_cmd,
71762306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105pqrs_fdb_add,
71862306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105pqrs_fdb_del,
71962306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
72062306a36Sopenharmony_ci	.rxtstamp		= sja1105_rxtstamp,
72162306a36Sopenharmony_ci	.clocking_setup		= sja1105_clocking_setup,
72262306a36Sopenharmony_ci	.pcs_mdio_read_c45	= sja1105_pcs_mdio_read_c45,
72362306a36Sopenharmony_ci	.pcs_mdio_write_c45	= sja1105_pcs_mdio_write_c45,
72462306a36Sopenharmony_ci	.regs			= &sja1105pqrs_regs,
72562306a36Sopenharmony_ci	.port_speed		= {
72662306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
72762306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 3,
72862306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 2,
72962306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 1,
73062306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
73162306a36Sopenharmony_ci	},
73262306a36Sopenharmony_ci	.supports_mii		= {true, true, true, true, true},
73362306a36Sopenharmony_ci	.supports_rmii		= {true, true, true, true, true},
73462306a36Sopenharmony_ci	.supports_rgmii		= {true, true, true, true, true},
73562306a36Sopenharmony_ci	.supports_sgmii		= {false, false, false, false, true},
73662306a36Sopenharmony_ci	.name			= "SJA1105R",
73762306a36Sopenharmony_ci};
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ciconst struct sja1105_info sja1105s_info = {
74062306a36Sopenharmony_ci	.device_id		= SJA1105QS_DEVICE_ID,
74162306a36Sopenharmony_ci	.part_no		= SJA1105S_PART_NO,
74262306a36Sopenharmony_ci	.static_ops		= sja1105s_table_ops,
74362306a36Sopenharmony_ci	.dyn_ops		= sja1105pqrs_dyn_ops,
74462306a36Sopenharmony_ci	.regs			= &sja1105pqrs_regs,
74562306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1105,
74662306a36Sopenharmony_ci	.can_limit_mcast_flood	= true,
74762306a36Sopenharmony_ci	.ptp_ts_bits		= 32,
74862306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 8,
74962306a36Sopenharmony_ci	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
75062306a36Sopenharmony_ci	.num_ports		= SJA1105_NUM_PORTS,
75162306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,
75262306a36Sopenharmony_ci	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,
75362306a36Sopenharmony_ci	.reset_cmd		= sja1105pqrs_reset_cmd,
75462306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105pqrs_fdb_add,
75562306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105pqrs_fdb_del,
75662306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
75762306a36Sopenharmony_ci	.rxtstamp		= sja1105_rxtstamp,
75862306a36Sopenharmony_ci	.clocking_setup		= sja1105_clocking_setup,
75962306a36Sopenharmony_ci	.pcs_mdio_read_c45	= sja1105_pcs_mdio_read_c45,
76062306a36Sopenharmony_ci	.pcs_mdio_write_c45	= sja1105_pcs_mdio_write_c45,
76162306a36Sopenharmony_ci	.port_speed		= {
76262306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
76362306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 3,
76462306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 2,
76562306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 1,
76662306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
76762306a36Sopenharmony_ci	},
76862306a36Sopenharmony_ci	.supports_mii		= {true, true, true, true, true},
76962306a36Sopenharmony_ci	.supports_rmii		= {true, true, true, true, true},
77062306a36Sopenharmony_ci	.supports_rgmii		= {true, true, true, true, true},
77162306a36Sopenharmony_ci	.supports_sgmii		= {false, false, false, false, true},
77262306a36Sopenharmony_ci	.name			= "SJA1105S",
77362306a36Sopenharmony_ci};
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ciconst struct sja1105_info sja1110a_info = {
77662306a36Sopenharmony_ci	.device_id		= SJA1110_DEVICE_ID,
77762306a36Sopenharmony_ci	.part_no		= SJA1110A_PART_NO,
77862306a36Sopenharmony_ci	.static_ops		= sja1110_table_ops,
77962306a36Sopenharmony_ci	.dyn_ops		= sja1110_dyn_ops,
78062306a36Sopenharmony_ci	.regs			= &sja1110_regs,
78162306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1110,
78262306a36Sopenharmony_ci	.can_limit_mcast_flood	= true,
78362306a36Sopenharmony_ci	.multiple_cascade_ports	= true,
78462306a36Sopenharmony_ci	.fixed_cbs_mapping	= true,
78562306a36Sopenharmony_ci	.ptp_ts_bits		= 32,
78662306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 8,
78762306a36Sopenharmony_ci	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY,
78862306a36Sopenharmony_ci	.num_ports		= SJA1110_NUM_PORTS,
78962306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT,
79062306a36Sopenharmony_ci	.setup_rgmii_delay	= sja1110_setup_rgmii_delay,
79162306a36Sopenharmony_ci	.reset_cmd		= sja1110_reset_cmd,
79262306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105pqrs_fdb_add,
79362306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105pqrs_fdb_del,
79462306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
79562306a36Sopenharmony_ci	.rxtstamp		= sja1110_rxtstamp,
79662306a36Sopenharmony_ci	.txtstamp		= sja1110_txtstamp,
79762306a36Sopenharmony_ci	.disable_microcontroller = sja1110_disable_microcontroller,
79862306a36Sopenharmony_ci	.pcs_mdio_read_c45	= sja1110_pcs_mdio_read_c45,
79962306a36Sopenharmony_ci	.pcs_mdio_write_c45	= sja1110_pcs_mdio_write_c45,
80062306a36Sopenharmony_ci	.port_speed		= {
80162306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
80262306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 4,
80362306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 3,
80462306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 2,
80562306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 1,
80662306a36Sopenharmony_ci	},
80762306a36Sopenharmony_ci	.supports_mii		= {true, true, true, true, false,
80862306a36Sopenharmony_ci				   true, true, true, true, true, true},
80962306a36Sopenharmony_ci	.supports_rmii		= {false, false, true, true, false,
81062306a36Sopenharmony_ci				   false, false, false, false, false, false},
81162306a36Sopenharmony_ci	.supports_rgmii		= {false, false, true, true, false,
81262306a36Sopenharmony_ci				   false, false, false, false, false, false},
81362306a36Sopenharmony_ci	.supports_sgmii		= {false, true, true, true, true,
81462306a36Sopenharmony_ci				   false, false, false, false, false, false},
81562306a36Sopenharmony_ci	.supports_2500basex	= {false, false, false, true, true,
81662306a36Sopenharmony_ci				   false, false, false, false, false, false},
81762306a36Sopenharmony_ci	.internal_phy		= {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
81862306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_NO_PHY,
81962306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
82062306a36Sopenharmony_ci				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
82162306a36Sopenharmony_ci				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
82262306a36Sopenharmony_ci				   SJA1105_PHY_BASE_T1},
82362306a36Sopenharmony_ci	.name			= "SJA1110A",
82462306a36Sopenharmony_ci};
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ciconst struct sja1105_info sja1110b_info = {
82762306a36Sopenharmony_ci	.device_id		= SJA1110_DEVICE_ID,
82862306a36Sopenharmony_ci	.part_no		= SJA1110B_PART_NO,
82962306a36Sopenharmony_ci	.static_ops		= sja1110_table_ops,
83062306a36Sopenharmony_ci	.dyn_ops		= sja1110_dyn_ops,
83162306a36Sopenharmony_ci	.regs			= &sja1110_regs,
83262306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1110,
83362306a36Sopenharmony_ci	.can_limit_mcast_flood	= true,
83462306a36Sopenharmony_ci	.multiple_cascade_ports	= true,
83562306a36Sopenharmony_ci	.fixed_cbs_mapping	= true,
83662306a36Sopenharmony_ci	.ptp_ts_bits		= 32,
83762306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 8,
83862306a36Sopenharmony_ci	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY,
83962306a36Sopenharmony_ci	.num_ports		= SJA1110_NUM_PORTS,
84062306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT,
84162306a36Sopenharmony_ci	.setup_rgmii_delay	= sja1110_setup_rgmii_delay,
84262306a36Sopenharmony_ci	.reset_cmd		= sja1110_reset_cmd,
84362306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105pqrs_fdb_add,
84462306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105pqrs_fdb_del,
84562306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
84662306a36Sopenharmony_ci	.rxtstamp		= sja1110_rxtstamp,
84762306a36Sopenharmony_ci	.txtstamp		= sja1110_txtstamp,
84862306a36Sopenharmony_ci	.disable_microcontroller = sja1110_disable_microcontroller,
84962306a36Sopenharmony_ci	.pcs_mdio_read_c45	= sja1110_pcs_mdio_read_c45,
85062306a36Sopenharmony_ci	.pcs_mdio_write_c45	= sja1110_pcs_mdio_write_c45,
85162306a36Sopenharmony_ci	.port_speed		= {
85262306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
85362306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 4,
85462306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 3,
85562306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 2,
85662306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 1,
85762306a36Sopenharmony_ci	},
85862306a36Sopenharmony_ci	.supports_mii		= {true, true, true, true, false,
85962306a36Sopenharmony_ci				   true, true, true, true, true, false},
86062306a36Sopenharmony_ci	.supports_rmii		= {false, false, true, true, false,
86162306a36Sopenharmony_ci				   false, false, false, false, false, false},
86262306a36Sopenharmony_ci	.supports_rgmii		= {false, false, true, true, false,
86362306a36Sopenharmony_ci				   false, false, false, false, false, false},
86462306a36Sopenharmony_ci	.supports_sgmii		= {false, false, false, true, true,
86562306a36Sopenharmony_ci				   false, false, false, false, false, false},
86662306a36Sopenharmony_ci	.supports_2500basex	= {false, false, false, true, true,
86762306a36Sopenharmony_ci				   false, false, false, false, false, false},
86862306a36Sopenharmony_ci	.internal_phy		= {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
86962306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_NO_PHY,
87062306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
87162306a36Sopenharmony_ci				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
87262306a36Sopenharmony_ci				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
87362306a36Sopenharmony_ci				   SJA1105_NO_PHY},
87462306a36Sopenharmony_ci	.name			= "SJA1110B",
87562306a36Sopenharmony_ci};
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ciconst struct sja1105_info sja1110c_info = {
87862306a36Sopenharmony_ci	.device_id		= SJA1110_DEVICE_ID,
87962306a36Sopenharmony_ci	.part_no		= SJA1110C_PART_NO,
88062306a36Sopenharmony_ci	.static_ops		= sja1110_table_ops,
88162306a36Sopenharmony_ci	.dyn_ops		= sja1110_dyn_ops,
88262306a36Sopenharmony_ci	.regs			= &sja1110_regs,
88362306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1110,
88462306a36Sopenharmony_ci	.can_limit_mcast_flood	= true,
88562306a36Sopenharmony_ci	.multiple_cascade_ports	= true,
88662306a36Sopenharmony_ci	.fixed_cbs_mapping	= true,
88762306a36Sopenharmony_ci	.ptp_ts_bits		= 32,
88862306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 8,
88962306a36Sopenharmony_ci	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY,
89062306a36Sopenharmony_ci	.num_ports		= SJA1110_NUM_PORTS,
89162306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT,
89262306a36Sopenharmony_ci	.setup_rgmii_delay	= sja1110_setup_rgmii_delay,
89362306a36Sopenharmony_ci	.reset_cmd		= sja1110_reset_cmd,
89462306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105pqrs_fdb_add,
89562306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105pqrs_fdb_del,
89662306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
89762306a36Sopenharmony_ci	.rxtstamp		= sja1110_rxtstamp,
89862306a36Sopenharmony_ci	.txtstamp		= sja1110_txtstamp,
89962306a36Sopenharmony_ci	.disable_microcontroller = sja1110_disable_microcontroller,
90062306a36Sopenharmony_ci	.pcs_mdio_read_c45	= sja1110_pcs_mdio_read_c45,
90162306a36Sopenharmony_ci	.pcs_mdio_write_c45	= sja1110_pcs_mdio_write_c45,
90262306a36Sopenharmony_ci	.port_speed		= {
90362306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
90462306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 4,
90562306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 3,
90662306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 2,
90762306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 1,
90862306a36Sopenharmony_ci	},
90962306a36Sopenharmony_ci	.supports_mii		= {true, true, true, true, false,
91062306a36Sopenharmony_ci				   true, true, true, false, false, false},
91162306a36Sopenharmony_ci	.supports_rmii		= {false, false, true, true, false,
91262306a36Sopenharmony_ci				   false, false, false, false, false, false},
91362306a36Sopenharmony_ci	.supports_rgmii		= {false, false, true, true, false,
91462306a36Sopenharmony_ci				   false, false, false, false, false, false},
91562306a36Sopenharmony_ci	.supports_sgmii		= {false, false, false, false, true,
91662306a36Sopenharmony_ci				   false, false, false, false, false, false},
91762306a36Sopenharmony_ci	.supports_2500basex	= {false, false, false, false, true,
91862306a36Sopenharmony_ci				   false, false, false, false, false, false},
91962306a36Sopenharmony_ci	.internal_phy		= {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
92062306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_NO_PHY,
92162306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
92262306a36Sopenharmony_ci				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
92362306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_NO_PHY,
92462306a36Sopenharmony_ci				   SJA1105_NO_PHY},
92562306a36Sopenharmony_ci	.name			= "SJA1110C",
92662306a36Sopenharmony_ci};
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ciconst struct sja1105_info sja1110d_info = {
92962306a36Sopenharmony_ci	.device_id		= SJA1110_DEVICE_ID,
93062306a36Sopenharmony_ci	.part_no		= SJA1110D_PART_NO,
93162306a36Sopenharmony_ci	.static_ops		= sja1110_table_ops,
93262306a36Sopenharmony_ci	.dyn_ops		= sja1110_dyn_ops,
93362306a36Sopenharmony_ci	.regs			= &sja1110_regs,
93462306a36Sopenharmony_ci	.tag_proto		= DSA_TAG_PROTO_SJA1110,
93562306a36Sopenharmony_ci	.can_limit_mcast_flood	= true,
93662306a36Sopenharmony_ci	.multiple_cascade_ports	= true,
93762306a36Sopenharmony_ci	.fixed_cbs_mapping	= true,
93862306a36Sopenharmony_ci	.ptp_ts_bits		= 32,
93962306a36Sopenharmony_ci	.ptpegr_ts_bytes	= 8,
94062306a36Sopenharmony_ci	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY,
94162306a36Sopenharmony_ci	.num_ports		= SJA1110_NUM_PORTS,
94262306a36Sopenharmony_ci	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT,
94362306a36Sopenharmony_ci	.setup_rgmii_delay	= sja1110_setup_rgmii_delay,
94462306a36Sopenharmony_ci	.reset_cmd		= sja1110_reset_cmd,
94562306a36Sopenharmony_ci	.fdb_add_cmd		= sja1105pqrs_fdb_add,
94662306a36Sopenharmony_ci	.fdb_del_cmd		= sja1105pqrs_fdb_del,
94762306a36Sopenharmony_ci	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
94862306a36Sopenharmony_ci	.rxtstamp		= sja1110_rxtstamp,
94962306a36Sopenharmony_ci	.txtstamp		= sja1110_txtstamp,
95062306a36Sopenharmony_ci	.disable_microcontroller = sja1110_disable_microcontroller,
95162306a36Sopenharmony_ci	.pcs_mdio_read_c45	= sja1110_pcs_mdio_read_c45,
95262306a36Sopenharmony_ci	.pcs_mdio_write_c45	= sja1110_pcs_mdio_write_c45,
95362306a36Sopenharmony_ci	.port_speed		= {
95462306a36Sopenharmony_ci		[SJA1105_SPEED_AUTO] = 0,
95562306a36Sopenharmony_ci		[SJA1105_SPEED_10MBPS] = 4,
95662306a36Sopenharmony_ci		[SJA1105_SPEED_100MBPS] = 3,
95762306a36Sopenharmony_ci		[SJA1105_SPEED_1000MBPS] = 2,
95862306a36Sopenharmony_ci		[SJA1105_SPEED_2500MBPS] = 1,
95962306a36Sopenharmony_ci	},
96062306a36Sopenharmony_ci	.supports_mii		= {true, false, true, false, false,
96162306a36Sopenharmony_ci				   true, true, true, false, false, false},
96262306a36Sopenharmony_ci	.supports_rmii		= {false, false, true, false, false,
96362306a36Sopenharmony_ci				   false, false, false, false, false, false},
96462306a36Sopenharmony_ci	.supports_rgmii		= {false, false, true, false, false,
96562306a36Sopenharmony_ci				   false, false, false, false, false, false},
96662306a36Sopenharmony_ci	.supports_sgmii		= {false, true, true, true, true,
96762306a36Sopenharmony_ci				   false, false, false, false, false, false},
96862306a36Sopenharmony_ci	.supports_2500basex     = {false, false, false, true, true,
96962306a36Sopenharmony_ci				   false, false, false, false, false, false},
97062306a36Sopenharmony_ci	.internal_phy		= {SJA1105_NO_PHY, SJA1105_NO_PHY,
97162306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_NO_PHY,
97262306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
97362306a36Sopenharmony_ci				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
97462306a36Sopenharmony_ci				   SJA1105_NO_PHY, SJA1105_NO_PHY,
97562306a36Sopenharmony_ci				   SJA1105_NO_PHY},
97662306a36Sopenharmony_ci	.name			= "SJA1110D",
97762306a36Sopenharmony_ci};
978