cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sja1105_spi.c (33182B)


      1// SPDX-License-Identifier: BSD-3-Clause
      2/* Copyright 2016-2018 NXP
      3 * Copyright (c) 2018, Sensor-Technik Wiedemann GmbH
      4 * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
      5 */
      6#include <linux/spi/spi.h>
      7#include <linux/packing.h>
      8#include "sja1105.h"
      9
     10struct sja1105_chunk {
     11	u8	*buf;
     12	size_t	len;
     13	u64	reg_addr;
     14};
     15
     16static void
     17sja1105_spi_message_pack(void *buf, const struct sja1105_spi_message *msg)
     18{
     19	const int size = SJA1105_SIZE_SPI_MSG_HEADER;
     20
     21	memset(buf, 0, size);
     22
     23	sja1105_pack(buf, &msg->access,     31, 31, size);
     24	sja1105_pack(buf, &msg->read_count, 30, 25, size);
     25	sja1105_pack(buf, &msg->address,    24,  4, size);
     26}
     27
     28/* If @rw is:
     29 * - SPI_WRITE: creates and sends an SPI write message at absolute
     30 *		address reg_addr, taking @len bytes from *buf
     31 * - SPI_READ:  creates and sends an SPI read message from absolute
     32 *		address reg_addr, writing @len bytes into *buf
     33 */
     34static int sja1105_xfer(const struct sja1105_private *priv,
     35			sja1105_spi_rw_mode_t rw, u64 reg_addr, u8 *buf,
     36			size_t len, struct ptp_system_timestamp *ptp_sts)
     37{
     38	u8 hdr_buf[SJA1105_SIZE_SPI_MSG_HEADER] = {0};
     39	struct spi_device *spi = priv->spidev;
     40	struct spi_transfer xfers[2] = {0};
     41	struct spi_transfer *chunk_xfer;
     42	struct spi_transfer *hdr_xfer;
     43	struct sja1105_chunk chunk;
     44	int num_chunks;
     45	int rc, i = 0;
     46
     47	num_chunks = DIV_ROUND_UP(len, priv->max_xfer_len);
     48
     49	chunk.reg_addr = reg_addr;
     50	chunk.buf = buf;
     51	chunk.len = min_t(size_t, len, priv->max_xfer_len);
     52
     53	hdr_xfer = &xfers[0];
     54	chunk_xfer = &xfers[1];
     55
     56	for (i = 0; i < num_chunks; i++) {
     57		struct spi_transfer *ptp_sts_xfer;
     58		struct sja1105_spi_message msg;
     59
     60		/* Populate the transfer's header buffer */
     61		msg.address = chunk.reg_addr;
     62		msg.access = rw;
     63		if (rw == SPI_READ)
     64			msg.read_count = chunk.len / 4;
     65		else
     66			/* Ignored */
     67			msg.read_count = 0;
     68		sja1105_spi_message_pack(hdr_buf, &msg);
     69		hdr_xfer->tx_buf = hdr_buf;
     70		hdr_xfer->len = SJA1105_SIZE_SPI_MSG_HEADER;
     71
     72		/* Populate the transfer's data buffer */
     73		if (rw == SPI_READ)
     74			chunk_xfer->rx_buf = chunk.buf;
     75		else
     76			chunk_xfer->tx_buf = chunk.buf;
     77		chunk_xfer->len = chunk.len;
     78
     79		/* Request timestamping for the transfer. Instead of letting
     80		 * callers specify which byte they want to timestamp, we can
     81		 * make certain assumptions:
     82		 * - A read operation will request a software timestamp when
     83		 *   what's being read is the PTP time. That is snapshotted by
     84		 *   the switch hardware at the end of the command portion
     85		 *   (hdr_xfer).
     86		 * - A write operation will request a software timestamp on
     87		 *   actions that modify the PTP time. Taking clock stepping as
     88		 *   an example, the switch writes the PTP time at the end of
     89		 *   the data portion (chunk_xfer).
     90		 */
     91		if (rw == SPI_READ)
     92			ptp_sts_xfer = hdr_xfer;
     93		else
     94			ptp_sts_xfer = chunk_xfer;
     95		ptp_sts_xfer->ptp_sts_word_pre = ptp_sts_xfer->len - 1;
     96		ptp_sts_xfer->ptp_sts_word_post = ptp_sts_xfer->len - 1;
     97		ptp_sts_xfer->ptp_sts = ptp_sts;
     98
     99		/* Calculate next chunk */
    100		chunk.buf += chunk.len;
    101		chunk.reg_addr += chunk.len / 4;
    102		chunk.len = min_t(size_t, (ptrdiff_t)(buf + len - chunk.buf),
    103				  priv->max_xfer_len);
    104
    105		rc = spi_sync_transfer(spi, xfers, 2);
    106		if (rc < 0) {
    107			dev_err(&spi->dev, "SPI transfer failed: %d\n", rc);
    108			return rc;
    109		}
    110	}
    111
    112	return 0;
    113}
    114
    115int sja1105_xfer_buf(const struct sja1105_private *priv,
    116		     sja1105_spi_rw_mode_t rw, u64 reg_addr,
    117		     u8 *buf, size_t len)
    118{
    119	return sja1105_xfer(priv, rw, reg_addr, buf, len, NULL);
    120}
    121
    122/* If @rw is:
    123 * - SPI_WRITE: creates and sends an SPI write message at absolute
    124 *		address reg_addr
    125 * - SPI_READ:  creates and sends an SPI read message from absolute
    126 *		address reg_addr
    127 *
    128 * The u64 *value is unpacked, meaning that it's stored in the native
    129 * CPU endianness and directly usable by software running on the core.
    130 */
    131int sja1105_xfer_u64(const struct sja1105_private *priv,
    132		     sja1105_spi_rw_mode_t rw, u64 reg_addr, u64 *value,
    133		     struct ptp_system_timestamp *ptp_sts)
    134{
    135	u8 packed_buf[8];
    136	int rc;
    137
    138	if (rw == SPI_WRITE)
    139		sja1105_pack(packed_buf, value, 63, 0, 8);
    140
    141	rc = sja1105_xfer(priv, rw, reg_addr, packed_buf, 8, ptp_sts);
    142
    143	if (rw == SPI_READ)
    144		sja1105_unpack(packed_buf, value, 63, 0, 8);
    145
    146	return rc;
    147}
    148
    149/* Same as above, but transfers only a 4 byte word */
    150int sja1105_xfer_u32(const struct sja1105_private *priv,
    151		     sja1105_spi_rw_mode_t rw, u64 reg_addr, u32 *value,
    152		     struct ptp_system_timestamp *ptp_sts)
    153{
    154	u8 packed_buf[4];
    155	u64 tmp;
    156	int rc;
    157
    158	if (rw == SPI_WRITE) {
    159		/* The packing API only supports u64 as CPU word size,
    160		 * so we need to convert.
    161		 */
    162		tmp = *value;
    163		sja1105_pack(packed_buf, &tmp, 31, 0, 4);
    164	}
    165
    166	rc = sja1105_xfer(priv, rw, reg_addr, packed_buf, 4, ptp_sts);
    167
    168	if (rw == SPI_READ) {
    169		sja1105_unpack(packed_buf, &tmp, 31, 0, 4);
    170		*value = tmp;
    171	}
    172
    173	return rc;
    174}
    175
    176static int sja1105et_reset_cmd(struct dsa_switch *ds)
    177{
    178	struct sja1105_private *priv = ds->priv;
    179	const struct sja1105_regs *regs = priv->info->regs;
    180	u32 cold_reset = BIT(3);
    181
    182	/* Cold reset */
    183	return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
    184}
    185
    186static int sja1105pqrs_reset_cmd(struct dsa_switch *ds)
    187{
    188	struct sja1105_private *priv = ds->priv;
    189	const struct sja1105_regs *regs = priv->info->regs;
    190	u32 cold_reset = BIT(2);
    191
    192	/* Cold reset */
    193	return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
    194}
    195
    196static int sja1110_reset_cmd(struct dsa_switch *ds)
    197{
    198	struct sja1105_private *priv = ds->priv;
    199	const struct sja1105_regs *regs = priv->info->regs;
    200	u32 switch_reset = BIT(20);
    201
    202	/* Only reset the switch core.
    203	 * A full cold reset would re-enable the BASE_MCSS_CLOCK PLL which
    204	 * would turn on the microcontroller, potentially letting it execute
    205	 * code which could interfere with our configuration.
    206	 */
    207	return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &switch_reset, NULL);
    208}
    209
    210int sja1105_inhibit_tx(const struct sja1105_private *priv,
    211		       unsigned long port_bitmap, bool tx_inhibited)
    212{
    213	const struct sja1105_regs *regs = priv->info->regs;
    214	u32 inhibit_cmd;
    215	int rc;
    216
    217	rc = sja1105_xfer_u32(priv, SPI_READ, regs->port_control,
    218			      &inhibit_cmd, NULL);
    219	if (rc < 0)
    220		return rc;
    221
    222	if (tx_inhibited)
    223		inhibit_cmd |= port_bitmap;
    224	else
    225		inhibit_cmd &= ~port_bitmap;
    226
    227	return sja1105_xfer_u32(priv, SPI_WRITE, regs->port_control,
    228				&inhibit_cmd, NULL);
    229}
    230
    231struct sja1105_status {
    232	u64 configs;
    233	u64 crcchkl;
    234	u64 ids;
    235	u64 crcchkg;
    236};
    237
    238/* This is not reading the entire General Status area, which is also
    239 * divergent between E/T and P/Q/R/S, but only the relevant bits for
    240 * ensuring that the static config upload procedure was successful.
    241 */
    242static void sja1105_status_unpack(void *buf, struct sja1105_status *status)
    243{
    244	/* So that addition translates to 4 bytes */
    245	u32 *p = buf;
    246
    247	/* device_id is missing from the buffer, but we don't
    248	 * want to diverge from the manual definition of the
    249	 * register addresses, so we'll back off one step with
    250	 * the register pointer, and never access p[0].
    251	 */
    252	p--;
    253	sja1105_unpack(p + 0x1, &status->configs,   31, 31, 4);
    254	sja1105_unpack(p + 0x1, &status->crcchkl,   30, 30, 4);
    255	sja1105_unpack(p + 0x1, &status->ids,       29, 29, 4);
    256	sja1105_unpack(p + 0x1, &status->crcchkg,   28, 28, 4);
    257}
    258
    259static int sja1105_status_get(struct sja1105_private *priv,
    260			      struct sja1105_status *status)
    261{
    262	const struct sja1105_regs *regs = priv->info->regs;
    263	u8 packed_buf[4];
    264	int rc;
    265
    266	rc = sja1105_xfer_buf(priv, SPI_READ, regs->status, packed_buf, 4);
    267	if (rc < 0)
    268		return rc;
    269
    270	sja1105_status_unpack(packed_buf, status);
    271
    272	return 0;
    273}
    274
    275/* Not const because unpacking priv->static_config into buffers and preparing
    276 * for upload requires the recalculation of table CRCs and updating the
    277 * structures with these.
    278 */
    279int static_config_buf_prepare_for_upload(struct sja1105_private *priv,
    280					 void *config_buf, int buf_len)
    281{
    282	struct sja1105_static_config *config = &priv->static_config;
    283	struct sja1105_table_header final_header;
    284	sja1105_config_valid_t valid;
    285	char *final_header_ptr;
    286	int crc_len;
    287
    288	valid = sja1105_static_config_check_valid(config,
    289						  priv->info->max_frame_mem);
    290	if (valid != SJA1105_CONFIG_OK) {
    291		dev_err(&priv->spidev->dev,
    292			sja1105_static_config_error_msg[valid]);
    293		return -EINVAL;
    294	}
    295
    296	/* Write Device ID and config tables to config_buf */
    297	sja1105_static_config_pack(config_buf, config);
    298	/* Recalculate CRC of the last header (right now 0xDEADBEEF).
    299	 * Don't include the CRC field itself.
    300	 */
    301	crc_len = buf_len - 4;
    302	/* Read the whole table header */
    303	final_header_ptr = config_buf + buf_len - SJA1105_SIZE_TABLE_HEADER;
    304	sja1105_table_header_packing(final_header_ptr, &final_header, UNPACK);
    305	/* Modify */
    306	final_header.crc = sja1105_crc32(config_buf, crc_len);
    307	/* Rewrite */
    308	sja1105_table_header_packing(final_header_ptr, &final_header, PACK);
    309
    310	return 0;
    311}
    312
    313#define RETRIES 10
    314
    315int sja1105_static_config_upload(struct sja1105_private *priv)
    316{
    317	struct sja1105_static_config *config = &priv->static_config;
    318	const struct sja1105_regs *regs = priv->info->regs;
    319	struct device *dev = &priv->spidev->dev;
    320	struct dsa_switch *ds = priv->ds;
    321	struct sja1105_status status;
    322	int rc, retries = RETRIES;
    323	u8 *config_buf;
    324	int buf_len;
    325
    326	buf_len = sja1105_static_config_get_length(config);
    327	config_buf = kcalloc(buf_len, sizeof(char), GFP_KERNEL);
    328	if (!config_buf)
    329		return -ENOMEM;
    330
    331	rc = static_config_buf_prepare_for_upload(priv, config_buf, buf_len);
    332	if (rc < 0) {
    333		dev_err(dev, "Invalid config, cannot upload\n");
    334		rc = -EINVAL;
    335		goto out;
    336	}
    337	/* Prevent PHY jabbering during switch reset by inhibiting
    338	 * Tx on all ports and waiting for current packet to drain.
    339	 * Otherwise, the PHY will see an unterminated Ethernet packet.
    340	 */
    341	rc = sja1105_inhibit_tx(priv, GENMASK_ULL(ds->num_ports - 1, 0), true);
    342	if (rc < 0) {
    343		dev_err(dev, "Failed to inhibit Tx on ports\n");
    344		rc = -ENXIO;
    345		goto out;
    346	}
    347	/* Wait for an eventual egress packet to finish transmission
    348	 * (reach IFG). It is guaranteed that a second one will not
    349	 * follow, and that switch cold reset is thus safe
    350	 */
    351	usleep_range(500, 1000);
    352	do {
    353		/* Put the SJA1105 in programming mode */
    354		rc = priv->info->reset_cmd(priv->ds);
    355		if (rc < 0) {
    356			dev_err(dev, "Failed to reset switch, retrying...\n");
    357			continue;
    358		}
    359		/* Wait for the switch to come out of reset */
    360		usleep_range(1000, 5000);
    361		/* Upload the static config to the device */
    362		rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->config,
    363				      config_buf, buf_len);
    364		if (rc < 0) {
    365			dev_err(dev, "Failed to upload config, retrying...\n");
    366			continue;
    367		}
    368		/* Check that SJA1105 responded well to the config upload */
    369		rc = sja1105_status_get(priv, &status);
    370		if (rc < 0)
    371			continue;
    372
    373		if (status.ids == 1) {
    374			dev_err(dev, "Mismatch between hardware and static config "
    375				"device id. Wrote 0x%llx, wants 0x%llx\n",
    376				config->device_id, priv->info->device_id);
    377			continue;
    378		}
    379		if (status.crcchkl == 1) {
    380			dev_err(dev, "Switch reported invalid local CRC on "
    381				"the uploaded config, retrying...\n");
    382			continue;
    383		}
    384		if (status.crcchkg == 1) {
    385			dev_err(dev, "Switch reported invalid global CRC on "
    386				"the uploaded config, retrying...\n");
    387			continue;
    388		}
    389		if (status.configs == 0) {
    390			dev_err(dev, "Switch reported that configuration is "
    391				"invalid, retrying...\n");
    392			continue;
    393		}
    394		/* Success! */
    395		break;
    396	} while (--retries);
    397
    398	if (!retries) {
    399		rc = -EIO;
    400		dev_err(dev, "Failed to upload config to device, giving up\n");
    401		goto out;
    402	} else if (retries != RETRIES) {
    403		dev_info(dev, "Succeeded after %d tried\n", RETRIES - retries);
    404	}
    405
    406out:
    407	kfree(config_buf);
    408	return rc;
    409}
    410
    411static const struct sja1105_regs sja1105et_regs = {
    412	.device_id = 0x0,
    413	.prod_id = 0x100BC3,
    414	.status = 0x1,
    415	.port_control = 0x11,
    416	.vl_status = 0x10000,
    417	.config = 0x020000,
    418	.rgu = 0x100440,
    419	/* UM10944.pdf, Table 86, ACU Register overview */
    420	.pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
    421	.pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
    422	.rmii_pll1 = 0x10000A,
    423	.cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
    424	.stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208},
    425	.stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440},
    426	.stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640},
    427	/* UM10944.pdf, Table 78, CGU Register overview */
    428	.mii_tx_clk = {0x100013, 0x10001A, 0x100021, 0x100028, 0x10002F},
    429	.mii_rx_clk = {0x100014, 0x10001B, 0x100022, 0x100029, 0x100030},
    430	.mii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
    431	.mii_ext_rx_clk = {0x100019, 0x100020, 0x100027, 0x10002E, 0x100035},
    432	.rgmii_tx_clk = {0x100016, 0x10001D, 0x100024, 0x10002B, 0x100032},
    433	.rmii_ref_clk = {0x100015, 0x10001C, 0x100023, 0x10002A, 0x100031},
    434	.rmii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
    435	.ptpegr_ts = {0xC0, 0xC2, 0xC4, 0xC6, 0xC8},
    436	.ptpschtm = 0x12, /* Spans 0x12 to 0x13 */
    437	.ptppinst = 0x14,
    438	.ptppindur = 0x16,
    439	.ptp_control = 0x17,
    440	.ptpclkval = 0x18, /* Spans 0x18 to 0x19 */
    441	.ptpclkrate = 0x1A,
    442	.ptpclkcorp = 0x1D,
    443	.mdio_100base_tx = SJA1105_RSV_ADDR,
    444	.mdio_100base_t1 = SJA1105_RSV_ADDR,
    445};
    446
    447static const struct sja1105_regs sja1105pqrs_regs = {
    448	.device_id = 0x0,
    449	.prod_id = 0x100BC3,
    450	.status = 0x1,
    451	.port_control = 0x12,
    452	.vl_status = 0x10000,
    453	.config = 0x020000,
    454	.rgu = 0x100440,
    455	/* UM10944.pdf, Table 86, ACU Register overview */
    456	.pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
    457	.pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
    458	.pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814},
    459	.rmii_pll1 = 0x10000A,
    460	.cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
    461	.stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208},
    462	.stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440},
    463	.stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640},
    464	.stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460},
    465	/* UM11040.pdf, Table 114 */
    466	.mii_tx_clk = {0x100013, 0x100019, 0x10001F, 0x100025, 0x10002B},
    467	.mii_rx_clk = {0x100014, 0x10001A, 0x100020, 0x100026, 0x10002C},
    468	.mii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
    469	.mii_ext_rx_clk = {0x100018, 0x10001E, 0x100024, 0x10002A, 0x100030},
    470	.rgmii_tx_clk = {0x100016, 0x10001C, 0x100022, 0x100028, 0x10002E},
    471	.rmii_ref_clk = {0x100015, 0x10001B, 0x100021, 0x100027, 0x10002D},
    472	.rmii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
    473	.ptpegr_ts = {0xC0, 0xC4, 0xC8, 0xCC, 0xD0},
    474	.ptpschtm = 0x13, /* Spans 0x13 to 0x14 */
    475	.ptppinst = 0x15,
    476	.ptppindur = 0x17,
    477	.ptp_control = 0x18,
    478	.ptpclkval = 0x19,
    479	.ptpclkrate = 0x1B,
    480	.ptpclkcorp = 0x1E,
    481	.ptpsyncts = 0x1F,
    482	.mdio_100base_tx = SJA1105_RSV_ADDR,
    483	.mdio_100base_t1 = SJA1105_RSV_ADDR,
    484};
    485
    486static const struct sja1105_regs sja1110_regs = {
    487	.device_id = SJA1110_SPI_ADDR(0x0),
    488	.prod_id = SJA1110_ACU_ADDR(0xf00),
    489	.status = SJA1110_SPI_ADDR(0x4),
    490	.port_control = SJA1110_SPI_ADDR(0x50), /* actually INHIB_TX */
    491	.vl_status = 0x10000,
    492	.config = 0x020000,
    493	.rgu = SJA1110_RGU_ADDR(0x100), /* Reset Control Register 0 */
    494	/* Ports 2 and 3 are capable of xMII, but there isn't anything to
    495	 * configure in the CGU/ACU for them.
    496	 */
    497	.pad_mii_tx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    498		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    499		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    500		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    501		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    502		       SJA1105_RSV_ADDR},
    503	.pad_mii_rx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    504		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    505		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    506		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    507		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    508		       SJA1105_RSV_ADDR},
    509	.pad_mii_id = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    510		       SJA1110_ACU_ADDR(0x18), SJA1110_ACU_ADDR(0x28),
    511		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    512		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    513		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    514		       SJA1105_RSV_ADDR},
    515	.rmii_pll1 = SJA1105_RSV_ADDR,
    516	.cgu_idiv = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    517		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    518		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    519		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
    520	.stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208, 0x20a,
    521		       0x20c, 0x20e, 0x210, 0x212, 0x214},
    522	.stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440, 0x450,
    523		       0x460, 0x470, 0x480, 0x490, 0x4a0},
    524	.stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640, 0x650,
    525		       0x660, 0x670, 0x680, 0x690, 0x6a0},
    526	.stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460, 0x1478,
    527			 0x1490, 0x14a8, 0x14c0, 0x14d8, 0x14f0},
    528	.mii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    529		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    530		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    531		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
    532	.mii_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    533		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    534		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    535		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
    536	.mii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    537			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    538			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    539			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
    540	.mii_ext_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    541			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    542			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    543			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
    544	.rgmii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    545			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    546			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    547			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
    548	.rmii_ref_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    549			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    550			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    551			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
    552	.rmii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    553			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    554			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    555			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    556			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    557			    SJA1105_RSV_ADDR},
    558	.ptpschtm = SJA1110_SPI_ADDR(0x54),
    559	.ptppinst = SJA1110_SPI_ADDR(0x5c),
    560	.ptppindur = SJA1110_SPI_ADDR(0x64),
    561	.ptp_control = SJA1110_SPI_ADDR(0x68),
    562	.ptpclkval = SJA1110_SPI_ADDR(0x6c),
    563	.ptpclkrate = SJA1110_SPI_ADDR(0x74),
    564	.ptpclkcorp = SJA1110_SPI_ADDR(0x80),
    565	.ptpsyncts = SJA1110_SPI_ADDR(0x84),
    566	.mdio_100base_tx = 0x1c2400,
    567	.mdio_100base_t1 = 0x1c1000,
    568	.pcs_base = {SJA1105_RSV_ADDR, 0x1c1400, 0x1c1800, 0x1c1c00, 0x1c2000,
    569		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
    570		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
    571};
    572
    573const struct sja1105_info sja1105e_info = {
    574	.device_id		= SJA1105E_DEVICE_ID,
    575	.part_no		= SJA1105ET_PART_NO,
    576	.static_ops		= sja1105e_table_ops,
    577	.dyn_ops		= sja1105et_dyn_ops,
    578	.tag_proto		= DSA_TAG_PROTO_SJA1105,
    579	.can_limit_mcast_flood	= false,
    580	.ptp_ts_bits		= 24,
    581	.ptpegr_ts_bytes	= 4,
    582	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
    583	.num_ports		= SJA1105_NUM_PORTS,
    584	.num_cbs_shapers	= SJA1105ET_MAX_CBS_COUNT,
    585	.reset_cmd		= sja1105et_reset_cmd,
    586	.fdb_add_cmd		= sja1105et_fdb_add,
    587	.fdb_del_cmd		= sja1105et_fdb_del,
    588	.ptp_cmd_packing	= sja1105et_ptp_cmd_packing,
    589	.rxtstamp		= sja1105_rxtstamp,
    590	.clocking_setup		= sja1105_clocking_setup,
    591	.regs			= &sja1105et_regs,
    592	.port_speed		= {
    593		[SJA1105_SPEED_AUTO] = 0,
    594		[SJA1105_SPEED_10MBPS] = 3,
    595		[SJA1105_SPEED_100MBPS] = 2,
    596		[SJA1105_SPEED_1000MBPS] = 1,
    597		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
    598	},
    599	.supports_mii		= {true, true, true, true, true},
    600	.supports_rmii		= {true, true, true, true, true},
    601	.supports_rgmii		= {true, true, true, true, true},
    602	.name			= "SJA1105E",
    603};
    604
    605const struct sja1105_info sja1105t_info = {
    606	.device_id		= SJA1105T_DEVICE_ID,
    607	.part_no		= SJA1105ET_PART_NO,
    608	.static_ops		= sja1105t_table_ops,
    609	.dyn_ops		= sja1105et_dyn_ops,
    610	.tag_proto		= DSA_TAG_PROTO_SJA1105,
    611	.can_limit_mcast_flood	= false,
    612	.ptp_ts_bits		= 24,
    613	.ptpegr_ts_bytes	= 4,
    614	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
    615	.num_ports		= SJA1105_NUM_PORTS,
    616	.num_cbs_shapers	= SJA1105ET_MAX_CBS_COUNT,
    617	.reset_cmd		= sja1105et_reset_cmd,
    618	.fdb_add_cmd		= sja1105et_fdb_add,
    619	.fdb_del_cmd		= sja1105et_fdb_del,
    620	.ptp_cmd_packing	= sja1105et_ptp_cmd_packing,
    621	.rxtstamp		= sja1105_rxtstamp,
    622	.clocking_setup		= sja1105_clocking_setup,
    623	.regs			= &sja1105et_regs,
    624	.port_speed		= {
    625		[SJA1105_SPEED_AUTO] = 0,
    626		[SJA1105_SPEED_10MBPS] = 3,
    627		[SJA1105_SPEED_100MBPS] = 2,
    628		[SJA1105_SPEED_1000MBPS] = 1,
    629		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
    630	},
    631	.supports_mii		= {true, true, true, true, true},
    632	.supports_rmii		= {true, true, true, true, true},
    633	.supports_rgmii		= {true, true, true, true, true},
    634	.name			= "SJA1105T",
    635};
    636
    637const struct sja1105_info sja1105p_info = {
    638	.device_id		= SJA1105PR_DEVICE_ID,
    639	.part_no		= SJA1105P_PART_NO,
    640	.static_ops		= sja1105p_table_ops,
    641	.dyn_ops		= sja1105pqrs_dyn_ops,
    642	.tag_proto		= DSA_TAG_PROTO_SJA1105,
    643	.can_limit_mcast_flood	= true,
    644	.ptp_ts_bits		= 32,
    645	.ptpegr_ts_bytes	= 8,
    646	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
    647	.num_ports		= SJA1105_NUM_PORTS,
    648	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,
    649	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,
    650	.reset_cmd		= sja1105pqrs_reset_cmd,
    651	.fdb_add_cmd		= sja1105pqrs_fdb_add,
    652	.fdb_del_cmd		= sja1105pqrs_fdb_del,
    653	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
    654	.rxtstamp		= sja1105_rxtstamp,
    655	.clocking_setup		= sja1105_clocking_setup,
    656	.regs			= &sja1105pqrs_regs,
    657	.port_speed		= {
    658		[SJA1105_SPEED_AUTO] = 0,
    659		[SJA1105_SPEED_10MBPS] = 3,
    660		[SJA1105_SPEED_100MBPS] = 2,
    661		[SJA1105_SPEED_1000MBPS] = 1,
    662		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
    663	},
    664	.supports_mii		= {true, true, true, true, true},
    665	.supports_rmii		= {true, true, true, true, true},
    666	.supports_rgmii		= {true, true, true, true, true},
    667	.name			= "SJA1105P",
    668};
    669
    670const struct sja1105_info sja1105q_info = {
    671	.device_id		= SJA1105QS_DEVICE_ID,
    672	.part_no		= SJA1105Q_PART_NO,
    673	.static_ops		= sja1105q_table_ops,
    674	.dyn_ops		= sja1105pqrs_dyn_ops,
    675	.tag_proto		= DSA_TAG_PROTO_SJA1105,
    676	.can_limit_mcast_flood	= true,
    677	.ptp_ts_bits		= 32,
    678	.ptpegr_ts_bytes	= 8,
    679	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
    680	.num_ports		= SJA1105_NUM_PORTS,
    681	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,
    682	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,
    683	.reset_cmd		= sja1105pqrs_reset_cmd,
    684	.fdb_add_cmd		= sja1105pqrs_fdb_add,
    685	.fdb_del_cmd		= sja1105pqrs_fdb_del,
    686	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
    687	.rxtstamp		= sja1105_rxtstamp,
    688	.clocking_setup		= sja1105_clocking_setup,
    689	.regs			= &sja1105pqrs_regs,
    690	.port_speed		= {
    691		[SJA1105_SPEED_AUTO] = 0,
    692		[SJA1105_SPEED_10MBPS] = 3,
    693		[SJA1105_SPEED_100MBPS] = 2,
    694		[SJA1105_SPEED_1000MBPS] = 1,
    695		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
    696	},
    697	.supports_mii		= {true, true, true, true, true},
    698	.supports_rmii		= {true, true, true, true, true},
    699	.supports_rgmii		= {true, true, true, true, true},
    700	.name			= "SJA1105Q",
    701};
    702
    703const struct sja1105_info sja1105r_info = {
    704	.device_id		= SJA1105PR_DEVICE_ID,
    705	.part_no		= SJA1105R_PART_NO,
    706	.static_ops		= sja1105r_table_ops,
    707	.dyn_ops		= sja1105pqrs_dyn_ops,
    708	.tag_proto		= DSA_TAG_PROTO_SJA1105,
    709	.can_limit_mcast_flood	= true,
    710	.ptp_ts_bits		= 32,
    711	.ptpegr_ts_bytes	= 8,
    712	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
    713	.num_ports		= SJA1105_NUM_PORTS,
    714	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,
    715	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,
    716	.reset_cmd		= sja1105pqrs_reset_cmd,
    717	.fdb_add_cmd		= sja1105pqrs_fdb_add,
    718	.fdb_del_cmd		= sja1105pqrs_fdb_del,
    719	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
    720	.rxtstamp		= sja1105_rxtstamp,
    721	.clocking_setup		= sja1105_clocking_setup,
    722	.pcs_mdio_read		= sja1105_pcs_mdio_read,
    723	.pcs_mdio_write		= sja1105_pcs_mdio_write,
    724	.regs			= &sja1105pqrs_regs,
    725	.port_speed		= {
    726		[SJA1105_SPEED_AUTO] = 0,
    727		[SJA1105_SPEED_10MBPS] = 3,
    728		[SJA1105_SPEED_100MBPS] = 2,
    729		[SJA1105_SPEED_1000MBPS] = 1,
    730		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
    731	},
    732	.supports_mii		= {true, true, true, true, true},
    733	.supports_rmii		= {true, true, true, true, true},
    734	.supports_rgmii		= {true, true, true, true, true},
    735	.supports_sgmii		= {false, false, false, false, true},
    736	.name			= "SJA1105R",
    737};
    738
    739const struct sja1105_info sja1105s_info = {
    740	.device_id		= SJA1105QS_DEVICE_ID,
    741	.part_no		= SJA1105S_PART_NO,
    742	.static_ops		= sja1105s_table_ops,
    743	.dyn_ops		= sja1105pqrs_dyn_ops,
    744	.regs			= &sja1105pqrs_regs,
    745	.tag_proto		= DSA_TAG_PROTO_SJA1105,
    746	.can_limit_mcast_flood	= true,
    747	.ptp_ts_bits		= 32,
    748	.ptpegr_ts_bytes	= 8,
    749	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY,
    750	.num_ports		= SJA1105_NUM_PORTS,
    751	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,
    752	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,
    753	.reset_cmd		= sja1105pqrs_reset_cmd,
    754	.fdb_add_cmd		= sja1105pqrs_fdb_add,
    755	.fdb_del_cmd		= sja1105pqrs_fdb_del,
    756	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
    757	.rxtstamp		= sja1105_rxtstamp,
    758	.clocking_setup		= sja1105_clocking_setup,
    759	.pcs_mdio_read		= sja1105_pcs_mdio_read,
    760	.pcs_mdio_write		= sja1105_pcs_mdio_write,
    761	.port_speed		= {
    762		[SJA1105_SPEED_AUTO] = 0,
    763		[SJA1105_SPEED_10MBPS] = 3,
    764		[SJA1105_SPEED_100MBPS] = 2,
    765		[SJA1105_SPEED_1000MBPS] = 1,
    766		[SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
    767	},
    768	.supports_mii		= {true, true, true, true, true},
    769	.supports_rmii		= {true, true, true, true, true},
    770	.supports_rgmii		= {true, true, true, true, true},
    771	.supports_sgmii		= {false, false, false, false, true},
    772	.name			= "SJA1105S",
    773};
    774
    775const struct sja1105_info sja1110a_info = {
    776	.device_id		= SJA1110_DEVICE_ID,
    777	.part_no		= SJA1110A_PART_NO,
    778	.static_ops		= sja1110_table_ops,
    779	.dyn_ops		= sja1110_dyn_ops,
    780	.regs			= &sja1110_regs,
    781	.tag_proto		= DSA_TAG_PROTO_SJA1110,
    782	.can_limit_mcast_flood	= true,
    783	.multiple_cascade_ports	= true,
    784	.ptp_ts_bits		= 32,
    785	.ptpegr_ts_bytes	= 8,
    786	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY,
    787	.num_ports		= SJA1110_NUM_PORTS,
    788	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT,
    789	.setup_rgmii_delay	= sja1110_setup_rgmii_delay,
    790	.reset_cmd		= sja1110_reset_cmd,
    791	.fdb_add_cmd		= sja1105pqrs_fdb_add,
    792	.fdb_del_cmd		= sja1105pqrs_fdb_del,
    793	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
    794	.rxtstamp		= sja1110_rxtstamp,
    795	.txtstamp		= sja1110_txtstamp,
    796	.disable_microcontroller = sja1110_disable_microcontroller,
    797	.pcs_mdio_read		= sja1110_pcs_mdio_read,
    798	.pcs_mdio_write		= sja1110_pcs_mdio_write,
    799	.port_speed		= {
    800		[SJA1105_SPEED_AUTO] = 0,
    801		[SJA1105_SPEED_10MBPS] = 4,
    802		[SJA1105_SPEED_100MBPS] = 3,
    803		[SJA1105_SPEED_1000MBPS] = 2,
    804		[SJA1105_SPEED_2500MBPS] = 1,
    805	},
    806	.supports_mii		= {true, true, true, true, false,
    807				   true, true, true, true, true, true},
    808	.supports_rmii		= {false, false, true, true, false,
    809				   false, false, false, false, false, false},
    810	.supports_rgmii		= {false, false, true, true, false,
    811				   false, false, false, false, false, false},
    812	.supports_sgmii		= {false, true, true, true, true,
    813				   false, false, false, false, false, false},
    814	.supports_2500basex	= {false, false, false, true, true,
    815				   false, false, false, false, false, false},
    816	.internal_phy		= {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
    817				   SJA1105_NO_PHY, SJA1105_NO_PHY,
    818				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
    819				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
    820				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
    821				   SJA1105_PHY_BASE_T1},
    822	.name			= "SJA1110A",
    823};
    824
    825const struct sja1105_info sja1110b_info = {
    826	.device_id		= SJA1110_DEVICE_ID,
    827	.part_no		= SJA1110B_PART_NO,
    828	.static_ops		= sja1110_table_ops,
    829	.dyn_ops		= sja1110_dyn_ops,
    830	.regs			= &sja1110_regs,
    831	.tag_proto		= DSA_TAG_PROTO_SJA1110,
    832	.can_limit_mcast_flood	= true,
    833	.multiple_cascade_ports	= true,
    834	.ptp_ts_bits		= 32,
    835	.ptpegr_ts_bytes	= 8,
    836	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY,
    837	.num_ports		= SJA1110_NUM_PORTS,
    838	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT,
    839	.setup_rgmii_delay	= sja1110_setup_rgmii_delay,
    840	.reset_cmd		= sja1110_reset_cmd,
    841	.fdb_add_cmd		= sja1105pqrs_fdb_add,
    842	.fdb_del_cmd		= sja1105pqrs_fdb_del,
    843	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
    844	.rxtstamp		= sja1110_rxtstamp,
    845	.txtstamp		= sja1110_txtstamp,
    846	.disable_microcontroller = sja1110_disable_microcontroller,
    847	.pcs_mdio_read		= sja1110_pcs_mdio_read,
    848	.pcs_mdio_write		= sja1110_pcs_mdio_write,
    849	.port_speed		= {
    850		[SJA1105_SPEED_AUTO] = 0,
    851		[SJA1105_SPEED_10MBPS] = 4,
    852		[SJA1105_SPEED_100MBPS] = 3,
    853		[SJA1105_SPEED_1000MBPS] = 2,
    854		[SJA1105_SPEED_2500MBPS] = 1,
    855	},
    856	.supports_mii		= {true, true, true, true, false,
    857				   true, true, true, true, true, false},
    858	.supports_rmii		= {false, false, true, true, false,
    859				   false, false, false, false, false, false},
    860	.supports_rgmii		= {false, false, true, true, false,
    861				   false, false, false, false, false, false},
    862	.supports_sgmii		= {false, false, false, true, true,
    863				   false, false, false, false, false, false},
    864	.supports_2500basex	= {false, false, false, true, true,
    865				   false, false, false, false, false, false},
    866	.internal_phy		= {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
    867				   SJA1105_NO_PHY, SJA1105_NO_PHY,
    868				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
    869				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
    870				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
    871				   SJA1105_NO_PHY},
    872	.name			= "SJA1110B",
    873};
    874
    875const struct sja1105_info sja1110c_info = {
    876	.device_id		= SJA1110_DEVICE_ID,
    877	.part_no		= SJA1110C_PART_NO,
    878	.static_ops		= sja1110_table_ops,
    879	.dyn_ops		= sja1110_dyn_ops,
    880	.regs			= &sja1110_regs,
    881	.tag_proto		= DSA_TAG_PROTO_SJA1110,
    882	.can_limit_mcast_flood	= true,
    883	.multiple_cascade_ports	= true,
    884	.ptp_ts_bits		= 32,
    885	.ptpegr_ts_bytes	= 8,
    886	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY,
    887	.num_ports		= SJA1110_NUM_PORTS,
    888	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT,
    889	.setup_rgmii_delay	= sja1110_setup_rgmii_delay,
    890	.reset_cmd		= sja1110_reset_cmd,
    891	.fdb_add_cmd		= sja1105pqrs_fdb_add,
    892	.fdb_del_cmd		= sja1105pqrs_fdb_del,
    893	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
    894	.rxtstamp		= sja1110_rxtstamp,
    895	.txtstamp		= sja1110_txtstamp,
    896	.disable_microcontroller = sja1110_disable_microcontroller,
    897	.pcs_mdio_read		= sja1110_pcs_mdio_read,
    898	.pcs_mdio_write		= sja1110_pcs_mdio_write,
    899	.port_speed		= {
    900		[SJA1105_SPEED_AUTO] = 0,
    901		[SJA1105_SPEED_10MBPS] = 4,
    902		[SJA1105_SPEED_100MBPS] = 3,
    903		[SJA1105_SPEED_1000MBPS] = 2,
    904		[SJA1105_SPEED_2500MBPS] = 1,
    905	},
    906	.supports_mii		= {true, true, true, true, false,
    907				   true, true, true, false, false, false},
    908	.supports_rmii		= {false, false, true, true, false,
    909				   false, false, false, false, false, false},
    910	.supports_rgmii		= {false, false, true, true, false,
    911				   false, false, false, false, false, false},
    912	.supports_sgmii		= {false, false, false, false, true,
    913				   false, false, false, false, false, false},
    914	.supports_2500basex	= {false, false, false, false, true,
    915				   false, false, false, false, false, false},
    916	.internal_phy		= {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
    917				   SJA1105_NO_PHY, SJA1105_NO_PHY,
    918				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
    919				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
    920				   SJA1105_NO_PHY, SJA1105_NO_PHY,
    921				   SJA1105_NO_PHY},
    922	.name			= "SJA1110C",
    923};
    924
    925const struct sja1105_info sja1110d_info = {
    926	.device_id		= SJA1110_DEVICE_ID,
    927	.part_no		= SJA1110D_PART_NO,
    928	.static_ops		= sja1110_table_ops,
    929	.dyn_ops		= sja1110_dyn_ops,
    930	.regs			= &sja1110_regs,
    931	.tag_proto		= DSA_TAG_PROTO_SJA1110,
    932	.can_limit_mcast_flood	= true,
    933	.multiple_cascade_ports	= true,
    934	.ptp_ts_bits		= 32,
    935	.ptpegr_ts_bytes	= 8,
    936	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY,
    937	.num_ports		= SJA1110_NUM_PORTS,
    938	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT,
    939	.setup_rgmii_delay	= sja1110_setup_rgmii_delay,
    940	.reset_cmd		= sja1110_reset_cmd,
    941	.fdb_add_cmd		= sja1105pqrs_fdb_add,
    942	.fdb_del_cmd		= sja1105pqrs_fdb_del,
    943	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing,
    944	.rxtstamp		= sja1110_rxtstamp,
    945	.txtstamp		= sja1110_txtstamp,
    946	.disable_microcontroller = sja1110_disable_microcontroller,
    947	.pcs_mdio_read		= sja1110_pcs_mdio_read,
    948	.pcs_mdio_write		= sja1110_pcs_mdio_write,
    949	.port_speed		= {
    950		[SJA1105_SPEED_AUTO] = 0,
    951		[SJA1105_SPEED_10MBPS] = 4,
    952		[SJA1105_SPEED_100MBPS] = 3,
    953		[SJA1105_SPEED_1000MBPS] = 2,
    954		[SJA1105_SPEED_2500MBPS] = 1,
    955	},
    956	.supports_mii		= {true, false, true, false, false,
    957				   true, true, true, false, false, false},
    958	.supports_rmii		= {false, false, true, false, false,
    959				   false, false, false, false, false, false},
    960	.supports_rgmii		= {false, false, true, false, false,
    961				   false, false, false, false, false, false},
    962	.supports_sgmii		= {false, true, true, true, true,
    963				   false, false, false, false, false, false},
    964	.supports_2500basex     = {false, false, false, true, true,
    965				   false, false, false, false, false, false},
    966	.internal_phy		= {SJA1105_NO_PHY, SJA1105_NO_PHY,
    967				   SJA1105_NO_PHY, SJA1105_NO_PHY,
    968				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
    969				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
    970				   SJA1105_NO_PHY, SJA1105_NO_PHY,
    971				   SJA1105_NO_PHY},
    972	.name			= "SJA1110D",
    973};