Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause
0002 /* Copyright 2016-2018 NXP
0003  * Copyright (c) 2018, Sensor-Technik Wiedemann GmbH
0004  * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
0005  */
0006 #include <linux/spi/spi.h>
0007 #include <linux/packing.h>
0008 #include "sja1105.h"
0009 
0010 struct sja1105_chunk {
0011     u8  *buf;
0012     size_t  len;
0013     u64 reg_addr;
0014 };
0015 
0016 static void
0017 sja1105_spi_message_pack(void *buf, const struct sja1105_spi_message *msg)
0018 {
0019     const int size = SJA1105_SIZE_SPI_MSG_HEADER;
0020 
0021     memset(buf, 0, size);
0022 
0023     sja1105_pack(buf, &msg->access,     31, 31, size);
0024     sja1105_pack(buf, &msg->read_count, 30, 25, size);
0025     sja1105_pack(buf, &msg->address,    24,  4, size);
0026 }
0027 
0028 /* If @rw is:
0029  * - SPI_WRITE: creates and sends an SPI write message at absolute
0030  *      address reg_addr, taking @len bytes from *buf
0031  * - SPI_READ:  creates and sends an SPI read message from absolute
0032  *      address reg_addr, writing @len bytes into *buf
0033  */
0034 static int sja1105_xfer(const struct sja1105_private *priv,
0035             sja1105_spi_rw_mode_t rw, u64 reg_addr, u8 *buf,
0036             size_t len, struct ptp_system_timestamp *ptp_sts)
0037 {
0038     u8 hdr_buf[SJA1105_SIZE_SPI_MSG_HEADER] = {0};
0039     struct spi_device *spi = priv->spidev;
0040     struct spi_transfer xfers[2] = {0};
0041     struct spi_transfer *chunk_xfer;
0042     struct spi_transfer *hdr_xfer;
0043     struct sja1105_chunk chunk;
0044     int num_chunks;
0045     int rc, i = 0;
0046 
0047     num_chunks = DIV_ROUND_UP(len, priv->max_xfer_len);
0048 
0049     chunk.reg_addr = reg_addr;
0050     chunk.buf = buf;
0051     chunk.len = min_t(size_t, len, priv->max_xfer_len);
0052 
0053     hdr_xfer = &xfers[0];
0054     chunk_xfer = &xfers[1];
0055 
0056     for (i = 0; i < num_chunks; i++) {
0057         struct spi_transfer *ptp_sts_xfer;
0058         struct sja1105_spi_message msg;
0059 
0060         /* Populate the transfer's header buffer */
0061         msg.address = chunk.reg_addr;
0062         msg.access = rw;
0063         if (rw == SPI_READ)
0064             msg.read_count = chunk.len / 4;
0065         else
0066             /* Ignored */
0067             msg.read_count = 0;
0068         sja1105_spi_message_pack(hdr_buf, &msg);
0069         hdr_xfer->tx_buf = hdr_buf;
0070         hdr_xfer->len = SJA1105_SIZE_SPI_MSG_HEADER;
0071 
0072         /* Populate the transfer's data buffer */
0073         if (rw == SPI_READ)
0074             chunk_xfer->rx_buf = chunk.buf;
0075         else
0076             chunk_xfer->tx_buf = chunk.buf;
0077         chunk_xfer->len = chunk.len;
0078 
0079         /* Request timestamping for the transfer. Instead of letting
0080          * callers specify which byte they want to timestamp, we can
0081          * make certain assumptions:
0082          * - A read operation will request a software timestamp when
0083          *   what's being read is the PTP time. That is snapshotted by
0084          *   the switch hardware at the end of the command portion
0085          *   (hdr_xfer).
0086          * - A write operation will request a software timestamp on
0087          *   actions that modify the PTP time. Taking clock stepping as
0088          *   an example, the switch writes the PTP time at the end of
0089          *   the data portion (chunk_xfer).
0090          */
0091         if (rw == SPI_READ)
0092             ptp_sts_xfer = hdr_xfer;
0093         else
0094             ptp_sts_xfer = chunk_xfer;
0095         ptp_sts_xfer->ptp_sts_word_pre = ptp_sts_xfer->len - 1;
0096         ptp_sts_xfer->ptp_sts_word_post = ptp_sts_xfer->len - 1;
0097         ptp_sts_xfer->ptp_sts = ptp_sts;
0098 
0099         /* Calculate next chunk */
0100         chunk.buf += chunk.len;
0101         chunk.reg_addr += chunk.len / 4;
0102         chunk.len = min_t(size_t, (ptrdiff_t)(buf + len - chunk.buf),
0103                   priv->max_xfer_len);
0104 
0105         rc = spi_sync_transfer(spi, xfers, 2);
0106         if (rc < 0) {
0107             dev_err(&spi->dev, "SPI transfer failed: %d\n", rc);
0108             return rc;
0109         }
0110     }
0111 
0112     return 0;
0113 }
0114 
0115 int sja1105_xfer_buf(const struct sja1105_private *priv,
0116              sja1105_spi_rw_mode_t rw, u64 reg_addr,
0117              u8 *buf, size_t len)
0118 {
0119     return sja1105_xfer(priv, rw, reg_addr, buf, len, NULL);
0120 }
0121 
0122 /* If @rw is:
0123  * - SPI_WRITE: creates and sends an SPI write message at absolute
0124  *      address reg_addr
0125  * - SPI_READ:  creates and sends an SPI read message from absolute
0126  *      address reg_addr
0127  *
0128  * The u64 *value is unpacked, meaning that it's stored in the native
0129  * CPU endianness and directly usable by software running on the core.
0130  */
0131 int sja1105_xfer_u64(const struct sja1105_private *priv,
0132              sja1105_spi_rw_mode_t rw, u64 reg_addr, u64 *value,
0133              struct ptp_system_timestamp *ptp_sts)
0134 {
0135     u8 packed_buf[8];
0136     int rc;
0137 
0138     if (rw == SPI_WRITE)
0139         sja1105_pack(packed_buf, value, 63, 0, 8);
0140 
0141     rc = sja1105_xfer(priv, rw, reg_addr, packed_buf, 8, ptp_sts);
0142 
0143     if (rw == SPI_READ)
0144         sja1105_unpack(packed_buf, value, 63, 0, 8);
0145 
0146     return rc;
0147 }
0148 
0149 /* Same as above, but transfers only a 4 byte word */
0150 int sja1105_xfer_u32(const struct sja1105_private *priv,
0151              sja1105_spi_rw_mode_t rw, u64 reg_addr, u32 *value,
0152              struct ptp_system_timestamp *ptp_sts)
0153 {
0154     u8 packed_buf[4];
0155     u64 tmp;
0156     int rc;
0157 
0158     if (rw == SPI_WRITE) {
0159         /* The packing API only supports u64 as CPU word size,
0160          * so we need to convert.
0161          */
0162         tmp = *value;
0163         sja1105_pack(packed_buf, &tmp, 31, 0, 4);
0164     }
0165 
0166     rc = sja1105_xfer(priv, rw, reg_addr, packed_buf, 4, ptp_sts);
0167 
0168     if (rw == SPI_READ) {
0169         sja1105_unpack(packed_buf, &tmp, 31, 0, 4);
0170         *value = tmp;
0171     }
0172 
0173     return rc;
0174 }
0175 
0176 static int sja1105et_reset_cmd(struct dsa_switch *ds)
0177 {
0178     struct sja1105_private *priv = ds->priv;
0179     const struct sja1105_regs *regs = priv->info->regs;
0180     u32 cold_reset = BIT(3);
0181 
0182     /* Cold reset */
0183     return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
0184 }
0185 
0186 static int sja1105pqrs_reset_cmd(struct dsa_switch *ds)
0187 {
0188     struct sja1105_private *priv = ds->priv;
0189     const struct sja1105_regs *regs = priv->info->regs;
0190     u32 cold_reset = BIT(2);
0191 
0192     /* Cold reset */
0193     return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
0194 }
0195 
0196 static int sja1110_reset_cmd(struct dsa_switch *ds)
0197 {
0198     struct sja1105_private *priv = ds->priv;
0199     const struct sja1105_regs *regs = priv->info->regs;
0200     u32 switch_reset = BIT(20);
0201 
0202     /* Only reset the switch core.
0203      * A full cold reset would re-enable the BASE_MCSS_CLOCK PLL which
0204      * would turn on the microcontroller, potentially letting it execute
0205      * code which could interfere with our configuration.
0206      */
0207     return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &switch_reset, NULL);
0208 }
0209 
0210 int sja1105_inhibit_tx(const struct sja1105_private *priv,
0211                unsigned long port_bitmap, bool tx_inhibited)
0212 {
0213     const struct sja1105_regs *regs = priv->info->regs;
0214     u32 inhibit_cmd;
0215     int rc;
0216 
0217     rc = sja1105_xfer_u32(priv, SPI_READ, regs->port_control,
0218                   &inhibit_cmd, NULL);
0219     if (rc < 0)
0220         return rc;
0221 
0222     if (tx_inhibited)
0223         inhibit_cmd |= port_bitmap;
0224     else
0225         inhibit_cmd &= ~port_bitmap;
0226 
0227     return sja1105_xfer_u32(priv, SPI_WRITE, regs->port_control,
0228                 &inhibit_cmd, NULL);
0229 }
0230 
0231 struct sja1105_status {
0232     u64 configs;
0233     u64 crcchkl;
0234     u64 ids;
0235     u64 crcchkg;
0236 };
0237 
0238 /* This is not reading the entire General Status area, which is also
0239  * divergent between E/T and P/Q/R/S, but only the relevant bits for
0240  * ensuring that the static config upload procedure was successful.
0241  */
0242 static void sja1105_status_unpack(void *buf, struct sja1105_status *status)
0243 {
0244     /* So that addition translates to 4 bytes */
0245     u32 *p = buf;
0246 
0247     /* device_id is missing from the buffer, but we don't
0248      * want to diverge from the manual definition of the
0249      * register addresses, so we'll back off one step with
0250      * the register pointer, and never access p[0].
0251      */
0252     p--;
0253     sja1105_unpack(p + 0x1, &status->configs,   31, 31, 4);
0254     sja1105_unpack(p + 0x1, &status->crcchkl,   30, 30, 4);
0255     sja1105_unpack(p + 0x1, &status->ids,       29, 29, 4);
0256     sja1105_unpack(p + 0x1, &status->crcchkg,   28, 28, 4);
0257 }
0258 
0259 static int sja1105_status_get(struct sja1105_private *priv,
0260                   struct sja1105_status *status)
0261 {
0262     const struct sja1105_regs *regs = priv->info->regs;
0263     u8 packed_buf[4];
0264     int rc;
0265 
0266     rc = sja1105_xfer_buf(priv, SPI_READ, regs->status, packed_buf, 4);
0267     if (rc < 0)
0268         return rc;
0269 
0270     sja1105_status_unpack(packed_buf, status);
0271 
0272     return 0;
0273 }
0274 
0275 /* Not const because unpacking priv->static_config into buffers and preparing
0276  * for upload requires the recalculation of table CRCs and updating the
0277  * structures with these.
0278  */
0279 int static_config_buf_prepare_for_upload(struct sja1105_private *priv,
0280                      void *config_buf, int buf_len)
0281 {
0282     struct sja1105_static_config *config = &priv->static_config;
0283     struct sja1105_table_header final_header;
0284     sja1105_config_valid_t valid;
0285     char *final_header_ptr;
0286     int crc_len;
0287 
0288     valid = sja1105_static_config_check_valid(config,
0289                           priv->info->max_frame_mem);
0290     if (valid != SJA1105_CONFIG_OK) {
0291         dev_err(&priv->spidev->dev,
0292             sja1105_static_config_error_msg[valid]);
0293         return -EINVAL;
0294     }
0295 
0296     /* Write Device ID and config tables to config_buf */
0297     sja1105_static_config_pack(config_buf, config);
0298     /* Recalculate CRC of the last header (right now 0xDEADBEEF).
0299      * Don't include the CRC field itself.
0300      */
0301     crc_len = buf_len - 4;
0302     /* Read the whole table header */
0303     final_header_ptr = config_buf + buf_len - SJA1105_SIZE_TABLE_HEADER;
0304     sja1105_table_header_packing(final_header_ptr, &final_header, UNPACK);
0305     /* Modify */
0306     final_header.crc = sja1105_crc32(config_buf, crc_len);
0307     /* Rewrite */
0308     sja1105_table_header_packing(final_header_ptr, &final_header, PACK);
0309 
0310     return 0;
0311 }
0312 
0313 #define RETRIES 10
0314 
0315 int sja1105_static_config_upload(struct sja1105_private *priv)
0316 {
0317     struct sja1105_static_config *config = &priv->static_config;
0318     const struct sja1105_regs *regs = priv->info->regs;
0319     struct device *dev = &priv->spidev->dev;
0320     struct dsa_switch *ds = priv->ds;
0321     struct sja1105_status status;
0322     int rc, retries = RETRIES;
0323     u8 *config_buf;
0324     int buf_len;
0325 
0326     buf_len = sja1105_static_config_get_length(config);
0327     config_buf = kcalloc(buf_len, sizeof(char), GFP_KERNEL);
0328     if (!config_buf)
0329         return -ENOMEM;
0330 
0331     rc = static_config_buf_prepare_for_upload(priv, config_buf, buf_len);
0332     if (rc < 0) {
0333         dev_err(dev, "Invalid config, cannot upload\n");
0334         rc = -EINVAL;
0335         goto out;
0336     }
0337     /* Prevent PHY jabbering during switch reset by inhibiting
0338      * Tx on all ports and waiting for current packet to drain.
0339      * Otherwise, the PHY will see an unterminated Ethernet packet.
0340      */
0341     rc = sja1105_inhibit_tx(priv, GENMASK_ULL(ds->num_ports - 1, 0), true);
0342     if (rc < 0) {
0343         dev_err(dev, "Failed to inhibit Tx on ports\n");
0344         rc = -ENXIO;
0345         goto out;
0346     }
0347     /* Wait for an eventual egress packet to finish transmission
0348      * (reach IFG). It is guaranteed that a second one will not
0349      * follow, and that switch cold reset is thus safe
0350      */
0351     usleep_range(500, 1000);
0352     do {
0353         /* Put the SJA1105 in programming mode */
0354         rc = priv->info->reset_cmd(priv->ds);
0355         if (rc < 0) {
0356             dev_err(dev, "Failed to reset switch, retrying...\n");
0357             continue;
0358         }
0359         /* Wait for the switch to come out of reset */
0360         usleep_range(1000, 5000);
0361         /* Upload the static config to the device */
0362         rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->config,
0363                       config_buf, buf_len);
0364         if (rc < 0) {
0365             dev_err(dev, "Failed to upload config, retrying...\n");
0366             continue;
0367         }
0368         /* Check that SJA1105 responded well to the config upload */
0369         rc = sja1105_status_get(priv, &status);
0370         if (rc < 0)
0371             continue;
0372 
0373         if (status.ids == 1) {
0374             dev_err(dev, "Mismatch between hardware and static config "
0375                 "device id. Wrote 0x%llx, wants 0x%llx\n",
0376                 config->device_id, priv->info->device_id);
0377             continue;
0378         }
0379         if (status.crcchkl == 1) {
0380             dev_err(dev, "Switch reported invalid local CRC on "
0381                 "the uploaded config, retrying...\n");
0382             continue;
0383         }
0384         if (status.crcchkg == 1) {
0385             dev_err(dev, "Switch reported invalid global CRC on "
0386                 "the uploaded config, retrying...\n");
0387             continue;
0388         }
0389         if (status.configs == 0) {
0390             dev_err(dev, "Switch reported that configuration is "
0391                 "invalid, retrying...\n");
0392             continue;
0393         }
0394         /* Success! */
0395         break;
0396     } while (--retries);
0397 
0398     if (!retries) {
0399         rc = -EIO;
0400         dev_err(dev, "Failed to upload config to device, giving up\n");
0401         goto out;
0402     } else if (retries != RETRIES) {
0403         dev_info(dev, "Succeeded after %d tried\n", RETRIES - retries);
0404     }
0405 
0406 out:
0407     kfree(config_buf);
0408     return rc;
0409 }
0410 
0411 static const struct sja1105_regs sja1105et_regs = {
0412     .device_id = 0x0,
0413     .prod_id = 0x100BC3,
0414     .status = 0x1,
0415     .port_control = 0x11,
0416     .vl_status = 0x10000,
0417     .config = 0x020000,
0418     .rgu = 0x100440,
0419     /* UM10944.pdf, Table 86, ACU Register overview */
0420     .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
0421     .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
0422     .rmii_pll1 = 0x10000A,
0423     .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
0424     .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208},
0425     .stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440},
0426     .stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640},
0427     /* UM10944.pdf, Table 78, CGU Register overview */
0428     .mii_tx_clk = {0x100013, 0x10001A, 0x100021, 0x100028, 0x10002F},
0429     .mii_rx_clk = {0x100014, 0x10001B, 0x100022, 0x100029, 0x100030},
0430     .mii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
0431     .mii_ext_rx_clk = {0x100019, 0x100020, 0x100027, 0x10002E, 0x100035},
0432     .rgmii_tx_clk = {0x100016, 0x10001D, 0x100024, 0x10002B, 0x100032},
0433     .rmii_ref_clk = {0x100015, 0x10001C, 0x100023, 0x10002A, 0x100031},
0434     .rmii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
0435     .ptpegr_ts = {0xC0, 0xC2, 0xC4, 0xC6, 0xC8},
0436     .ptpschtm = 0x12, /* Spans 0x12 to 0x13 */
0437     .ptppinst = 0x14,
0438     .ptppindur = 0x16,
0439     .ptp_control = 0x17,
0440     .ptpclkval = 0x18, /* Spans 0x18 to 0x19 */
0441     .ptpclkrate = 0x1A,
0442     .ptpclkcorp = 0x1D,
0443     .mdio_100base_tx = SJA1105_RSV_ADDR,
0444     .mdio_100base_t1 = SJA1105_RSV_ADDR,
0445 };
0446 
0447 static const struct sja1105_regs sja1105pqrs_regs = {
0448     .device_id = 0x0,
0449     .prod_id = 0x100BC3,
0450     .status = 0x1,
0451     .port_control = 0x12,
0452     .vl_status = 0x10000,
0453     .config = 0x020000,
0454     .rgu = 0x100440,
0455     /* UM10944.pdf, Table 86, ACU Register overview */
0456     .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
0457     .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
0458     .pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814},
0459     .rmii_pll1 = 0x10000A,
0460     .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
0461     .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208},
0462     .stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440},
0463     .stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640},
0464     .stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460},
0465     /* UM11040.pdf, Table 114 */
0466     .mii_tx_clk = {0x100013, 0x100019, 0x10001F, 0x100025, 0x10002B},
0467     .mii_rx_clk = {0x100014, 0x10001A, 0x100020, 0x100026, 0x10002C},
0468     .mii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
0469     .mii_ext_rx_clk = {0x100018, 0x10001E, 0x100024, 0x10002A, 0x100030},
0470     .rgmii_tx_clk = {0x100016, 0x10001C, 0x100022, 0x100028, 0x10002E},
0471     .rmii_ref_clk = {0x100015, 0x10001B, 0x100021, 0x100027, 0x10002D},
0472     .rmii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
0473     .ptpegr_ts = {0xC0, 0xC4, 0xC8, 0xCC, 0xD0},
0474     .ptpschtm = 0x13, /* Spans 0x13 to 0x14 */
0475     .ptppinst = 0x15,
0476     .ptppindur = 0x17,
0477     .ptp_control = 0x18,
0478     .ptpclkval = 0x19,
0479     .ptpclkrate = 0x1B,
0480     .ptpclkcorp = 0x1E,
0481     .ptpsyncts = 0x1F,
0482     .mdio_100base_tx = SJA1105_RSV_ADDR,
0483     .mdio_100base_t1 = SJA1105_RSV_ADDR,
0484 };
0485 
0486 static const struct sja1105_regs sja1110_regs = {
0487     .device_id = SJA1110_SPI_ADDR(0x0),
0488     .prod_id = SJA1110_ACU_ADDR(0xf00),
0489     .status = SJA1110_SPI_ADDR(0x4),
0490     .port_control = SJA1110_SPI_ADDR(0x50), /* actually INHIB_TX */
0491     .vl_status = 0x10000,
0492     .config = 0x020000,
0493     .rgu = SJA1110_RGU_ADDR(0x100), /* Reset Control Register 0 */
0494     /* Ports 2 and 3 are capable of xMII, but there isn't anything to
0495      * configure in the CGU/ACU for them.
0496      */
0497     .pad_mii_tx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0498                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0499                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0500                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0501                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0502                SJA1105_RSV_ADDR},
0503     .pad_mii_rx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0504                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0505                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0506                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0507                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0508                SJA1105_RSV_ADDR},
0509     .pad_mii_id = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0510                SJA1110_ACU_ADDR(0x18), SJA1110_ACU_ADDR(0x28),
0511                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0512                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0513                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0514                SJA1105_RSV_ADDR},
0515     .rmii_pll1 = SJA1105_RSV_ADDR,
0516     .cgu_idiv = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0517              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0518              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0519              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
0520     .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208, 0x20a,
0521                0x20c, 0x20e, 0x210, 0x212, 0x214},
0522     .stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440, 0x450,
0523                0x460, 0x470, 0x480, 0x490, 0x4a0},
0524     .stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640, 0x650,
0525                0x660, 0x670, 0x680, 0x690, 0x6a0},
0526     .stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460, 0x1478,
0527              0x1490, 0x14a8, 0x14c0, 0x14d8, 0x14f0},
0528     .mii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0529                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0530                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0531                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
0532     .mii_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0533                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0534                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0535                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
0536     .mii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0537                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0538                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0539                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
0540     .mii_ext_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0541                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0542                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0543                SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
0544     .rgmii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0545              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0546              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0547              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
0548     .rmii_ref_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0549              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0550              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0551              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
0552     .rmii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0553                 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0554                 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0555                 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0556                 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0557                 SJA1105_RSV_ADDR},
0558     .ptpschtm = SJA1110_SPI_ADDR(0x54),
0559     .ptppinst = SJA1110_SPI_ADDR(0x5c),
0560     .ptppindur = SJA1110_SPI_ADDR(0x64),
0561     .ptp_control = SJA1110_SPI_ADDR(0x68),
0562     .ptpclkval = SJA1110_SPI_ADDR(0x6c),
0563     .ptpclkrate = SJA1110_SPI_ADDR(0x74),
0564     .ptpclkcorp = SJA1110_SPI_ADDR(0x80),
0565     .ptpsyncts = SJA1110_SPI_ADDR(0x84),
0566     .mdio_100base_tx = 0x1c2400,
0567     .mdio_100base_t1 = 0x1c1000,
0568     .pcs_base = {SJA1105_RSV_ADDR, 0x1c1400, 0x1c1800, 0x1c1c00, 0x1c2000,
0569              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
0570              SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
0571 };
0572 
0573 const struct sja1105_info sja1105e_info = {
0574     .device_id      = SJA1105E_DEVICE_ID,
0575     .part_no        = SJA1105ET_PART_NO,
0576     .static_ops     = sja1105e_table_ops,
0577     .dyn_ops        = sja1105et_dyn_ops,
0578     .tag_proto      = DSA_TAG_PROTO_SJA1105,
0579     .can_limit_mcast_flood  = false,
0580     .ptp_ts_bits        = 24,
0581     .ptpegr_ts_bytes    = 4,
0582     .max_frame_mem      = SJA1105_MAX_FRAME_MEMORY,
0583     .num_ports      = SJA1105_NUM_PORTS,
0584     .num_cbs_shapers    = SJA1105ET_MAX_CBS_COUNT,
0585     .reset_cmd      = sja1105et_reset_cmd,
0586     .fdb_add_cmd        = sja1105et_fdb_add,
0587     .fdb_del_cmd        = sja1105et_fdb_del,
0588     .ptp_cmd_packing    = sja1105et_ptp_cmd_packing,
0589     .rxtstamp       = sja1105_rxtstamp,
0590     .clocking_setup     = sja1105_clocking_setup,
0591     .regs           = &sja1105et_regs,
0592     .port_speed     = {
0593         [SJA1105_SPEED_AUTO] = 0,
0594         [SJA1105_SPEED_10MBPS] = 3,
0595         [SJA1105_SPEED_100MBPS] = 2,
0596         [SJA1105_SPEED_1000MBPS] = 1,
0597         [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
0598     },
0599     .supports_mii       = {true, true, true, true, true},
0600     .supports_rmii      = {true, true, true, true, true},
0601     .supports_rgmii     = {true, true, true, true, true},
0602     .name           = "SJA1105E",
0603 };
0604 
0605 const struct sja1105_info sja1105t_info = {
0606     .device_id      = SJA1105T_DEVICE_ID,
0607     .part_no        = SJA1105ET_PART_NO,
0608     .static_ops     = sja1105t_table_ops,
0609     .dyn_ops        = sja1105et_dyn_ops,
0610     .tag_proto      = DSA_TAG_PROTO_SJA1105,
0611     .can_limit_mcast_flood  = false,
0612     .ptp_ts_bits        = 24,
0613     .ptpegr_ts_bytes    = 4,
0614     .max_frame_mem      = SJA1105_MAX_FRAME_MEMORY,
0615     .num_ports      = SJA1105_NUM_PORTS,
0616     .num_cbs_shapers    = SJA1105ET_MAX_CBS_COUNT,
0617     .reset_cmd      = sja1105et_reset_cmd,
0618     .fdb_add_cmd        = sja1105et_fdb_add,
0619     .fdb_del_cmd        = sja1105et_fdb_del,
0620     .ptp_cmd_packing    = sja1105et_ptp_cmd_packing,
0621     .rxtstamp       = sja1105_rxtstamp,
0622     .clocking_setup     = sja1105_clocking_setup,
0623     .regs           = &sja1105et_regs,
0624     .port_speed     = {
0625         [SJA1105_SPEED_AUTO] = 0,
0626         [SJA1105_SPEED_10MBPS] = 3,
0627         [SJA1105_SPEED_100MBPS] = 2,
0628         [SJA1105_SPEED_1000MBPS] = 1,
0629         [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
0630     },
0631     .supports_mii       = {true, true, true, true, true},
0632     .supports_rmii      = {true, true, true, true, true},
0633     .supports_rgmii     = {true, true, true, true, true},
0634     .name           = "SJA1105T",
0635 };
0636 
0637 const struct sja1105_info sja1105p_info = {
0638     .device_id      = SJA1105PR_DEVICE_ID,
0639     .part_no        = SJA1105P_PART_NO,
0640     .static_ops     = sja1105p_table_ops,
0641     .dyn_ops        = sja1105pqrs_dyn_ops,
0642     .tag_proto      = DSA_TAG_PROTO_SJA1105,
0643     .can_limit_mcast_flood  = true,
0644     .ptp_ts_bits        = 32,
0645     .ptpegr_ts_bytes    = 8,
0646     .max_frame_mem      = SJA1105_MAX_FRAME_MEMORY,
0647     .num_ports      = SJA1105_NUM_PORTS,
0648     .num_cbs_shapers    = SJA1105PQRS_MAX_CBS_COUNT,
0649     .setup_rgmii_delay  = sja1105pqrs_setup_rgmii_delay,
0650     .reset_cmd      = sja1105pqrs_reset_cmd,
0651     .fdb_add_cmd        = sja1105pqrs_fdb_add,
0652     .fdb_del_cmd        = sja1105pqrs_fdb_del,
0653     .ptp_cmd_packing    = sja1105pqrs_ptp_cmd_packing,
0654     .rxtstamp       = sja1105_rxtstamp,
0655     .clocking_setup     = sja1105_clocking_setup,
0656     .regs           = &sja1105pqrs_regs,
0657     .port_speed     = {
0658         [SJA1105_SPEED_AUTO] = 0,
0659         [SJA1105_SPEED_10MBPS] = 3,
0660         [SJA1105_SPEED_100MBPS] = 2,
0661         [SJA1105_SPEED_1000MBPS] = 1,
0662         [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
0663     },
0664     .supports_mii       = {true, true, true, true, true},
0665     .supports_rmii      = {true, true, true, true, true},
0666     .supports_rgmii     = {true, true, true, true, true},
0667     .name           = "SJA1105P",
0668 };
0669 
0670 const struct sja1105_info sja1105q_info = {
0671     .device_id      = SJA1105QS_DEVICE_ID,
0672     .part_no        = SJA1105Q_PART_NO,
0673     .static_ops     = sja1105q_table_ops,
0674     .dyn_ops        = sja1105pqrs_dyn_ops,
0675     .tag_proto      = DSA_TAG_PROTO_SJA1105,
0676     .can_limit_mcast_flood  = true,
0677     .ptp_ts_bits        = 32,
0678     .ptpegr_ts_bytes    = 8,
0679     .max_frame_mem      = SJA1105_MAX_FRAME_MEMORY,
0680     .num_ports      = SJA1105_NUM_PORTS,
0681     .num_cbs_shapers    = SJA1105PQRS_MAX_CBS_COUNT,
0682     .setup_rgmii_delay  = sja1105pqrs_setup_rgmii_delay,
0683     .reset_cmd      = sja1105pqrs_reset_cmd,
0684     .fdb_add_cmd        = sja1105pqrs_fdb_add,
0685     .fdb_del_cmd        = sja1105pqrs_fdb_del,
0686     .ptp_cmd_packing    = sja1105pqrs_ptp_cmd_packing,
0687     .rxtstamp       = sja1105_rxtstamp,
0688     .clocking_setup     = sja1105_clocking_setup,
0689     .regs           = &sja1105pqrs_regs,
0690     .port_speed     = {
0691         [SJA1105_SPEED_AUTO] = 0,
0692         [SJA1105_SPEED_10MBPS] = 3,
0693         [SJA1105_SPEED_100MBPS] = 2,
0694         [SJA1105_SPEED_1000MBPS] = 1,
0695         [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
0696     },
0697     .supports_mii       = {true, true, true, true, true},
0698     .supports_rmii      = {true, true, true, true, true},
0699     .supports_rgmii     = {true, true, true, true, true},
0700     .name           = "SJA1105Q",
0701 };
0702 
0703 const struct sja1105_info sja1105r_info = {
0704     .device_id      = SJA1105PR_DEVICE_ID,
0705     .part_no        = SJA1105R_PART_NO,
0706     .static_ops     = sja1105r_table_ops,
0707     .dyn_ops        = sja1105pqrs_dyn_ops,
0708     .tag_proto      = DSA_TAG_PROTO_SJA1105,
0709     .can_limit_mcast_flood  = true,
0710     .ptp_ts_bits        = 32,
0711     .ptpegr_ts_bytes    = 8,
0712     .max_frame_mem      = SJA1105_MAX_FRAME_MEMORY,
0713     .num_ports      = SJA1105_NUM_PORTS,
0714     .num_cbs_shapers    = SJA1105PQRS_MAX_CBS_COUNT,
0715     .setup_rgmii_delay  = sja1105pqrs_setup_rgmii_delay,
0716     .reset_cmd      = sja1105pqrs_reset_cmd,
0717     .fdb_add_cmd        = sja1105pqrs_fdb_add,
0718     .fdb_del_cmd        = sja1105pqrs_fdb_del,
0719     .ptp_cmd_packing    = sja1105pqrs_ptp_cmd_packing,
0720     .rxtstamp       = sja1105_rxtstamp,
0721     .clocking_setup     = sja1105_clocking_setup,
0722     .pcs_mdio_read      = sja1105_pcs_mdio_read,
0723     .pcs_mdio_write     = sja1105_pcs_mdio_write,
0724     .regs           = &sja1105pqrs_regs,
0725     .port_speed     = {
0726         [SJA1105_SPEED_AUTO] = 0,
0727         [SJA1105_SPEED_10MBPS] = 3,
0728         [SJA1105_SPEED_100MBPS] = 2,
0729         [SJA1105_SPEED_1000MBPS] = 1,
0730         [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
0731     },
0732     .supports_mii       = {true, true, true, true, true},
0733     .supports_rmii      = {true, true, true, true, true},
0734     .supports_rgmii     = {true, true, true, true, true},
0735     .supports_sgmii     = {false, false, false, false, true},
0736     .name           = "SJA1105R",
0737 };
0738 
0739 const struct sja1105_info sja1105s_info = {
0740     .device_id      = SJA1105QS_DEVICE_ID,
0741     .part_no        = SJA1105S_PART_NO,
0742     .static_ops     = sja1105s_table_ops,
0743     .dyn_ops        = sja1105pqrs_dyn_ops,
0744     .regs           = &sja1105pqrs_regs,
0745     .tag_proto      = DSA_TAG_PROTO_SJA1105,
0746     .can_limit_mcast_flood  = true,
0747     .ptp_ts_bits        = 32,
0748     .ptpegr_ts_bytes    = 8,
0749     .max_frame_mem      = SJA1105_MAX_FRAME_MEMORY,
0750     .num_ports      = SJA1105_NUM_PORTS,
0751     .num_cbs_shapers    = SJA1105PQRS_MAX_CBS_COUNT,
0752     .setup_rgmii_delay  = sja1105pqrs_setup_rgmii_delay,
0753     .reset_cmd      = sja1105pqrs_reset_cmd,
0754     .fdb_add_cmd        = sja1105pqrs_fdb_add,
0755     .fdb_del_cmd        = sja1105pqrs_fdb_del,
0756     .ptp_cmd_packing    = sja1105pqrs_ptp_cmd_packing,
0757     .rxtstamp       = sja1105_rxtstamp,
0758     .clocking_setup     = sja1105_clocking_setup,
0759     .pcs_mdio_read      = sja1105_pcs_mdio_read,
0760     .pcs_mdio_write     = sja1105_pcs_mdio_write,
0761     .port_speed     = {
0762         [SJA1105_SPEED_AUTO] = 0,
0763         [SJA1105_SPEED_10MBPS] = 3,
0764         [SJA1105_SPEED_100MBPS] = 2,
0765         [SJA1105_SPEED_1000MBPS] = 1,
0766         [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
0767     },
0768     .supports_mii       = {true, true, true, true, true},
0769     .supports_rmii      = {true, true, true, true, true},
0770     .supports_rgmii     = {true, true, true, true, true},
0771     .supports_sgmii     = {false, false, false, false, true},
0772     .name           = "SJA1105S",
0773 };
0774 
0775 const struct sja1105_info sja1110a_info = {
0776     .device_id      = SJA1110_DEVICE_ID,
0777     .part_no        = SJA1110A_PART_NO,
0778     .static_ops     = sja1110_table_ops,
0779     .dyn_ops        = sja1110_dyn_ops,
0780     .regs           = &sja1110_regs,
0781     .tag_proto      = DSA_TAG_PROTO_SJA1110,
0782     .can_limit_mcast_flood  = true,
0783     .multiple_cascade_ports = true,
0784     .ptp_ts_bits        = 32,
0785     .ptpegr_ts_bytes    = 8,
0786     .max_frame_mem      = SJA1110_MAX_FRAME_MEMORY,
0787     .num_ports      = SJA1110_NUM_PORTS,
0788     .num_cbs_shapers    = SJA1110_MAX_CBS_COUNT,
0789     .setup_rgmii_delay  = sja1110_setup_rgmii_delay,
0790     .reset_cmd      = sja1110_reset_cmd,
0791     .fdb_add_cmd        = sja1105pqrs_fdb_add,
0792     .fdb_del_cmd        = sja1105pqrs_fdb_del,
0793     .ptp_cmd_packing    = sja1105pqrs_ptp_cmd_packing,
0794     .rxtstamp       = sja1110_rxtstamp,
0795     .txtstamp       = sja1110_txtstamp,
0796     .disable_microcontroller = sja1110_disable_microcontroller,
0797     .pcs_mdio_read      = sja1110_pcs_mdio_read,
0798     .pcs_mdio_write     = sja1110_pcs_mdio_write,
0799     .port_speed     = {
0800         [SJA1105_SPEED_AUTO] = 0,
0801         [SJA1105_SPEED_10MBPS] = 4,
0802         [SJA1105_SPEED_100MBPS] = 3,
0803         [SJA1105_SPEED_1000MBPS] = 2,
0804         [SJA1105_SPEED_2500MBPS] = 1,
0805     },
0806     .supports_mii       = {true, true, true, true, false,
0807                    true, true, true, true, true, true},
0808     .supports_rmii      = {false, false, true, true, false,
0809                    false, false, false, false, false, false},
0810     .supports_rgmii     = {false, false, true, true, false,
0811                    false, false, false, false, false, false},
0812     .supports_sgmii     = {false, true, true, true, true,
0813                    false, false, false, false, false, false},
0814     .supports_2500basex = {false, false, false, true, true,
0815                    false, false, false, false, false, false},
0816     .internal_phy       = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
0817                    SJA1105_NO_PHY, SJA1105_NO_PHY,
0818                    SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
0819                    SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
0820                    SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
0821                    SJA1105_PHY_BASE_T1},
0822     .name           = "SJA1110A",
0823 };
0824 
0825 const struct sja1105_info sja1110b_info = {
0826     .device_id      = SJA1110_DEVICE_ID,
0827     .part_no        = SJA1110B_PART_NO,
0828     .static_ops     = sja1110_table_ops,
0829     .dyn_ops        = sja1110_dyn_ops,
0830     .regs           = &sja1110_regs,
0831     .tag_proto      = DSA_TAG_PROTO_SJA1110,
0832     .can_limit_mcast_flood  = true,
0833     .multiple_cascade_ports = true,
0834     .ptp_ts_bits        = 32,
0835     .ptpegr_ts_bytes    = 8,
0836     .max_frame_mem      = SJA1110_MAX_FRAME_MEMORY,
0837     .num_ports      = SJA1110_NUM_PORTS,
0838     .num_cbs_shapers    = SJA1110_MAX_CBS_COUNT,
0839     .setup_rgmii_delay  = sja1110_setup_rgmii_delay,
0840     .reset_cmd      = sja1110_reset_cmd,
0841     .fdb_add_cmd        = sja1105pqrs_fdb_add,
0842     .fdb_del_cmd        = sja1105pqrs_fdb_del,
0843     .ptp_cmd_packing    = sja1105pqrs_ptp_cmd_packing,
0844     .rxtstamp       = sja1110_rxtstamp,
0845     .txtstamp       = sja1110_txtstamp,
0846     .disable_microcontroller = sja1110_disable_microcontroller,
0847     .pcs_mdio_read      = sja1110_pcs_mdio_read,
0848     .pcs_mdio_write     = sja1110_pcs_mdio_write,
0849     .port_speed     = {
0850         [SJA1105_SPEED_AUTO] = 0,
0851         [SJA1105_SPEED_10MBPS] = 4,
0852         [SJA1105_SPEED_100MBPS] = 3,
0853         [SJA1105_SPEED_1000MBPS] = 2,
0854         [SJA1105_SPEED_2500MBPS] = 1,
0855     },
0856     .supports_mii       = {true, true, true, true, false,
0857                    true, true, true, true, true, false},
0858     .supports_rmii      = {false, false, true, true, false,
0859                    false, false, false, false, false, false},
0860     .supports_rgmii     = {false, false, true, true, false,
0861                    false, false, false, false, false, false},
0862     .supports_sgmii     = {false, false, false, true, true,
0863                    false, false, false, false, false, false},
0864     .supports_2500basex = {false, false, false, true, true,
0865                    false, false, false, false, false, false},
0866     .internal_phy       = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
0867                    SJA1105_NO_PHY, SJA1105_NO_PHY,
0868                    SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
0869                    SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
0870                    SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
0871                    SJA1105_NO_PHY},
0872     .name           = "SJA1110B",
0873 };
0874 
0875 const struct sja1105_info sja1110c_info = {
0876     .device_id      = SJA1110_DEVICE_ID,
0877     .part_no        = SJA1110C_PART_NO,
0878     .static_ops     = sja1110_table_ops,
0879     .dyn_ops        = sja1110_dyn_ops,
0880     .regs           = &sja1110_regs,
0881     .tag_proto      = DSA_TAG_PROTO_SJA1110,
0882     .can_limit_mcast_flood  = true,
0883     .multiple_cascade_ports = true,
0884     .ptp_ts_bits        = 32,
0885     .ptpegr_ts_bytes    = 8,
0886     .max_frame_mem      = SJA1110_MAX_FRAME_MEMORY,
0887     .num_ports      = SJA1110_NUM_PORTS,
0888     .num_cbs_shapers    = SJA1110_MAX_CBS_COUNT,
0889     .setup_rgmii_delay  = sja1110_setup_rgmii_delay,
0890     .reset_cmd      = sja1110_reset_cmd,
0891     .fdb_add_cmd        = sja1105pqrs_fdb_add,
0892     .fdb_del_cmd        = sja1105pqrs_fdb_del,
0893     .ptp_cmd_packing    = sja1105pqrs_ptp_cmd_packing,
0894     .rxtstamp       = sja1110_rxtstamp,
0895     .txtstamp       = sja1110_txtstamp,
0896     .disable_microcontroller = sja1110_disable_microcontroller,
0897     .pcs_mdio_read      = sja1110_pcs_mdio_read,
0898     .pcs_mdio_write     = sja1110_pcs_mdio_write,
0899     .port_speed     = {
0900         [SJA1105_SPEED_AUTO] = 0,
0901         [SJA1105_SPEED_10MBPS] = 4,
0902         [SJA1105_SPEED_100MBPS] = 3,
0903         [SJA1105_SPEED_1000MBPS] = 2,
0904         [SJA1105_SPEED_2500MBPS] = 1,
0905     },
0906     .supports_mii       = {true, true, true, true, false,
0907                    true, true, true, false, false, false},
0908     .supports_rmii      = {false, false, true, true, false,
0909                    false, false, false, false, false, false},
0910     .supports_rgmii     = {false, false, true, true, false,
0911                    false, false, false, false, false, false},
0912     .supports_sgmii     = {false, false, false, false, true,
0913                    false, false, false, false, false, false},
0914     .supports_2500basex = {false, false, false, false, true,
0915                    false, false, false, false, false, false},
0916     .internal_phy       = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
0917                    SJA1105_NO_PHY, SJA1105_NO_PHY,
0918                    SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
0919                    SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
0920                    SJA1105_NO_PHY, SJA1105_NO_PHY,
0921                    SJA1105_NO_PHY},
0922     .name           = "SJA1110C",
0923 };
0924 
0925 const struct sja1105_info sja1110d_info = {
0926     .device_id      = SJA1110_DEVICE_ID,
0927     .part_no        = SJA1110D_PART_NO,
0928     .static_ops     = sja1110_table_ops,
0929     .dyn_ops        = sja1110_dyn_ops,
0930     .regs           = &sja1110_regs,
0931     .tag_proto      = DSA_TAG_PROTO_SJA1110,
0932     .can_limit_mcast_flood  = true,
0933     .multiple_cascade_ports = true,
0934     .ptp_ts_bits        = 32,
0935     .ptpegr_ts_bytes    = 8,
0936     .max_frame_mem      = SJA1110_MAX_FRAME_MEMORY,
0937     .num_ports      = SJA1110_NUM_PORTS,
0938     .num_cbs_shapers    = SJA1110_MAX_CBS_COUNT,
0939     .setup_rgmii_delay  = sja1110_setup_rgmii_delay,
0940     .reset_cmd      = sja1110_reset_cmd,
0941     .fdb_add_cmd        = sja1105pqrs_fdb_add,
0942     .fdb_del_cmd        = sja1105pqrs_fdb_del,
0943     .ptp_cmd_packing    = sja1105pqrs_ptp_cmd_packing,
0944     .rxtstamp       = sja1110_rxtstamp,
0945     .txtstamp       = sja1110_txtstamp,
0946     .disable_microcontroller = sja1110_disable_microcontroller,
0947     .pcs_mdio_read      = sja1110_pcs_mdio_read,
0948     .pcs_mdio_write     = sja1110_pcs_mdio_write,
0949     .port_speed     = {
0950         [SJA1105_SPEED_AUTO] = 0,
0951         [SJA1105_SPEED_10MBPS] = 4,
0952         [SJA1105_SPEED_100MBPS] = 3,
0953         [SJA1105_SPEED_1000MBPS] = 2,
0954         [SJA1105_SPEED_2500MBPS] = 1,
0955     },
0956     .supports_mii       = {true, false, true, false, false,
0957                    true, true, true, false, false, false},
0958     .supports_rmii      = {false, false, true, false, false,
0959                    false, false, false, false, false, false},
0960     .supports_rgmii     = {false, false, true, false, false,
0961                    false, false, false, false, false, false},
0962     .supports_sgmii     = {false, true, true, true, true,
0963                    false, false, false, false, false, false},
0964     .supports_2500basex     = {false, false, false, true, true,
0965                    false, false, false, false, false, false},
0966     .internal_phy       = {SJA1105_NO_PHY, SJA1105_NO_PHY,
0967                    SJA1105_NO_PHY, SJA1105_NO_PHY,
0968                    SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
0969                    SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
0970                    SJA1105_NO_PHY, SJA1105_NO_PHY,
0971                    SJA1105_NO_PHY},
0972     .name           = "SJA1110D",
0973 };