net: dsa: sja1105: register the MDIO buses for 100base-T1 and 100base-TX
[linux-2.6-microblaze.git] / drivers / net / dsa / sja1105 / sja1105_spi.c
index f7a1514..54ecb55 100644 (file)
@@ -7,10 +7,6 @@
 #include <linux/packing.h>
 #include "sja1105.h"
 
-#define SJA1105_SIZE_RESET_CMD         4
-#define SJA1105_SIZE_SPI_MSG_HEADER    4
-#define SJA1105_SIZE_SPI_MSG_MAXLEN    (64 * 4)
-
 struct sja1105_chunk {
        u8      *buf;
        size_t  len;
@@ -29,13 +25,6 @@ sja1105_spi_message_pack(void *buf, const struct sja1105_spi_message *msg)
        sja1105_pack(buf, &msg->address,    24,  4, size);
 }
 
-#define sja1105_hdr_xfer(xfers, chunk) \
-       ((xfers) + 2 * (chunk))
-#define sja1105_chunk_xfer(xfers, chunk) \
-       ((xfers) + 2 * (chunk) + 1)
-#define sja1105_hdr_buf(hdr_bufs, chunk) \
-       ((hdr_bufs) + (chunk) * SJA1105_SIZE_SPI_MSG_HEADER)
-
 /* If @rw is:
  * - SPI_WRITE: creates and sends an SPI write message at absolute
  *             address reg_addr, taking @len bytes from *buf
@@ -46,41 +35,25 @@ static int sja1105_xfer(const struct sja1105_private *priv,
                        sja1105_spi_rw_mode_t rw, u64 reg_addr, u8 *buf,
                        size_t len, struct ptp_system_timestamp *ptp_sts)
 {
-       struct sja1105_chunk chunk = {
-               .len = min_t(size_t, len, SJA1105_SIZE_SPI_MSG_MAXLEN),
-               .reg_addr = reg_addr,
-               .buf = buf,
-       };
+       u8 hdr_buf[SJA1105_SIZE_SPI_MSG_HEADER] = {0};
        struct spi_device *spi = priv->spidev;
-       struct spi_transfer *xfers;
+       struct spi_transfer xfers[2] = {0};
+       struct spi_transfer *chunk_xfer;
+       struct spi_transfer *hdr_xfer;
+       struct sja1105_chunk chunk;
        int num_chunks;
        int rc, i = 0;
-       u8 *hdr_bufs;
 
-       num_chunks = DIV_ROUND_UP(len, SJA1105_SIZE_SPI_MSG_MAXLEN);
+       num_chunks = DIV_ROUND_UP(len, priv->max_xfer_len);
 
-       /* One transfer for each message header, one for each message
-        * payload (chunk).
-        */
-       xfers = kcalloc(2 * num_chunks, sizeof(struct spi_transfer),
-                       GFP_KERNEL);
-       if (!xfers)
-               return -ENOMEM;
+       chunk.reg_addr = reg_addr;
+       chunk.buf = buf;
+       chunk.len = min_t(size_t, len, priv->max_xfer_len);
 
-       /* Packed buffers for the num_chunks SPI message headers,
-        * stored as a contiguous array
-        */
-       hdr_bufs = kcalloc(num_chunks, SJA1105_SIZE_SPI_MSG_HEADER,
-                          GFP_KERNEL);
-       if (!hdr_bufs) {
-               kfree(xfers);
-               return -ENOMEM;
-       }
+       hdr_xfer = &xfers[0];
+       chunk_xfer = &xfers[1];
 
        for (i = 0; i < num_chunks; i++) {
-               struct spi_transfer *chunk_xfer = sja1105_chunk_xfer(xfers, i);
-               struct spi_transfer *hdr_xfer = sja1105_hdr_xfer(xfers, i);
-               u8 *hdr_buf = sja1105_hdr_buf(hdr_bufs, i);
                struct spi_transfer *ptp_sts_xfer;
                struct sja1105_spi_message msg;
 
@@ -127,21 +100,16 @@ static int sja1105_xfer(const struct sja1105_private *priv,
                chunk.buf += chunk.len;
                chunk.reg_addr += chunk.len / 4;
                chunk.len = min_t(size_t, (ptrdiff_t)(buf + len - chunk.buf),
-                                 SJA1105_SIZE_SPI_MSG_MAXLEN);
+                                 priv->max_xfer_len);
 
-               /* De-assert the chip select after each chunk. */
-               if (chunk.len)
-                       chunk_xfer->cs_change = 1;
+               rc = spi_sync_transfer(spi, xfers, 2);
+               if (rc < 0) {
+                       dev_err(&spi->dev, "SPI transfer failed: %d\n", rc);
+                       return rc;
+               }
        }
 
-       rc = spi_sync_transfer(spi, xfers, 2 * num_chunks);
-       if (rc < 0)
-               dev_err(&spi->dev, "SPI transfer failed: %d\n", rc);
-
-       kfree(hdr_bufs);
-       kfree(xfers);
-
-       return rc;
+       return 0;
 }
 
 int sja1105_xfer_buf(const struct sja1105_private *priv,
@@ -209,28 +177,30 @@ static int sja1105et_reset_cmd(struct dsa_switch *ds)
 {
        struct sja1105_private *priv = ds->priv;
        const struct sja1105_regs *regs = priv->info->regs;
-       u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0};
-       const int size = SJA1105_SIZE_RESET_CMD;
-       u64 cold_rst = 1;
+       u32 cold_reset = BIT(3);
 
-       sja1105_pack(packed_buf, &cold_rst, 3, 3, size);
-
-       return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf,
-                               SJA1105_SIZE_RESET_CMD);
+       /* Cold reset */
+       return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
 }
 
 static int sja1105pqrs_reset_cmd(struct dsa_switch *ds)
 {
        struct sja1105_private *priv = ds->priv;
        const struct sja1105_regs *regs = priv->info->regs;
-       u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0};
-       const int size = SJA1105_SIZE_RESET_CMD;
-       u64 cold_rst = 1;
+       u32 cold_reset = BIT(2);
 
-       sja1105_pack(packed_buf, &cold_rst, 2, 2, size);
+       /* Cold reset */
+       return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
+}
 
-       return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf,
-                               SJA1105_SIZE_RESET_CMD);
+static int sja1110_reset_cmd(struct dsa_switch *ds)
+{
+       struct sja1105_private *priv = ds->priv;
+       const struct sja1105_regs *regs = priv->info->regs;
+       u32 switch_reset = BIT(20);
+
+       /* Switch core reset */
+       return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &switch_reset, NULL);
 }
 
 int sja1105_inhibit_tx(const struct sja1105_private *priv,
@@ -311,7 +281,8 @@ int static_config_buf_prepare_for_upload(struct sja1105_private *priv,
        char *final_header_ptr;
        int crc_len;
 
-       valid = sja1105_static_config_check_valid(config);
+       valid = sja1105_static_config_check_valid(config,
+                                                 priv->info->max_frame_mem);
        if (valid != SJA1105_CONFIG_OK) {
                dev_err(&priv->spidev->dev,
                        sja1105_static_config_error_msg[valid]);
@@ -339,10 +310,10 @@ int static_config_buf_prepare_for_upload(struct sja1105_private *priv,
 
 int sja1105_static_config_upload(struct sja1105_private *priv)
 {
-       unsigned long port_bitmap = GENMASK_ULL(SJA1105_NUM_PORTS - 1, 0);
        struct sja1105_static_config *config = &priv->static_config;
        const struct sja1105_regs *regs = priv->info->regs;
        struct device *dev = &priv->spidev->dev;
+       struct dsa_switch *ds = priv->ds;
        struct sja1105_status status;
        int rc, retries = RETRIES;
        u8 *config_buf;
@@ -363,7 +334,7 @@ int sja1105_static_config_upload(struct sja1105_private *priv)
         * Tx on all ports and waiting for current packet to drain.
         * Otherwise, the PHY will see an unterminated Ethernet packet.
         */
-       rc = sja1105_inhibit_tx(priv, port_bitmap, true);
+       rc = sja1105_inhibit_tx(priv, GENMASK_ULL(ds->num_ports - 1, 0), true);
        if (rc < 0) {
                dev_err(dev, "Failed to inhibit Tx on ports\n");
                rc = -ENXIO;
@@ -446,9 +417,9 @@ static struct sja1105_regs sja1105et_regs = {
        .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
        .rmii_pll1 = 0x10000A,
        .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
-       .mac = {0x200, 0x202, 0x204, 0x206, 0x208},
-       .mac_hl1 = {0x400, 0x410, 0x420, 0x430, 0x440},
-       .mac_hl2 = {0x600, 0x610, 0x620, 0x630, 0x640},
+       .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208},
+       .stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440},
+       .stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640},
        /* UM10944.pdf, Table 78, CGU Register overview */
        .mii_tx_clk = {0x100013, 0x10001A, 0x100021, 0x100028, 0x10002F},
        .mii_rx_clk = {0x100014, 0x10001B, 0x100022, 0x100029, 0x100030},
@@ -465,6 +436,8 @@ static struct sja1105_regs sja1105et_regs = {
        .ptpclkval = 0x18, /* Spans 0x18 to 0x19 */
        .ptpclkrate = 0x1A,
        .ptpclkcorp = 0x1D,
+       .mdio_100base_tx = SJA1105_RSV_ADDR,
+       .mdio_100base_t1 = SJA1105_RSV_ADDR,
 };
 
 static struct sja1105_regs sja1105pqrs_regs = {
@@ -479,13 +452,12 @@ static struct sja1105_regs sja1105pqrs_regs = {
        .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
        .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
        .pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814},
-       .sgmii = 0x1F0000,
        .rmii_pll1 = 0x10000A,
        .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
-       .mac = {0x200, 0x202, 0x204, 0x206, 0x208},
-       .mac_hl1 = {0x400, 0x410, 0x420, 0x430, 0x440},
-       .mac_hl2 = {0x600, 0x610, 0x620, 0x630, 0x640},
-       .ether_stats = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460},
+       .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208},
+       .stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440},
+       .stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640},
+       .stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460},
        /* UM11040.pdf, Table 114 */
        .mii_tx_clk = {0x100013, 0x100019, 0x10001F, 0x100025, 0x10002B},
        .mii_rx_clk = {0x100014, 0x10001A, 0x100020, 0x100026, 0x10002C},
@@ -494,7 +466,6 @@ static struct sja1105_regs sja1105pqrs_regs = {
        .rgmii_tx_clk = {0x100016, 0x10001C, 0x100022, 0x100028, 0x10002E},
        .rmii_ref_clk = {0x100015, 0x10001B, 0x100021, 0x100027, 0x10002D},
        .rmii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
-       .qlevel = {0x604, 0x614, 0x624, 0x634, 0x644},
        .ptpegr_ts = {0xC0, 0xC4, 0xC8, 0xCC, 0xD0},
        .ptpschtm = 0x13, /* Spans 0x13 to 0x14 */
        .ptppinst = 0x15,
@@ -504,6 +475,92 @@ static struct sja1105_regs sja1105pqrs_regs = {
        .ptpclkrate = 0x1B,
        .ptpclkcorp = 0x1E,
        .ptpsyncts = 0x1F,
+       .mdio_100base_tx = SJA1105_RSV_ADDR,
+       .mdio_100base_t1 = SJA1105_RSV_ADDR,
+};
+
+static struct sja1105_regs sja1110_regs = {
+       .device_id = SJA1110_SPI_ADDR(0x0),
+       .prod_id = SJA1110_ACU_ADDR(0xf00),
+       .status = SJA1110_SPI_ADDR(0x4),
+       .port_control = SJA1110_SPI_ADDR(0x50), /* actually INHIB_TX */
+       .vl_status = 0x10000,
+       .config = 0x020000,
+       .rgu = SJA1110_RGU_ADDR(0x100), /* Reset Control Register 0 */
+       /* Ports 2 and 3 are capable of xMII, but there isn't anything to
+        * configure in the CGU/ACU for them.
+        */
+       .pad_mii_tx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR},
+       .pad_mii_rx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR},
+       .pad_mii_id = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1110_ACU_ADDR(0x18), SJA1110_ACU_ADDR(0x28),
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR},
+       .rmii_pll1 = SJA1105_RSV_ADDR,
+       .cgu_idiv = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
+       .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208, 0x20a,
+                      0x20c, 0x20e, 0x210, 0x212, 0x214},
+       .stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440, 0x450,
+                      0x460, 0x470, 0x480, 0x490, 0x4a0},
+       .stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640, 0x650,
+                      0x660, 0x670, 0x680, 0x690, 0x6a0},
+       .stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460, 0x1478,
+                        0x1490, 0x14a8, 0x14c0, 0x14d8, 0x14f0},
+       .mii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
+       .mii_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                      SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
+       .mii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                          SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                          SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                          SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
+       .mii_ext_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                          SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                          SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                          SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
+       .rgmii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                        SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                        SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                        SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
+       .rmii_ref_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                        SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                        SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                        SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
+       .rmii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                           SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                           SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                           SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                           SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                           SJA1105_RSV_ADDR},
+       .ptpschtm = SJA1110_SPI_ADDR(0x54),
+       .ptppinst = SJA1110_SPI_ADDR(0x5c),
+       .ptppindur = SJA1110_SPI_ADDR(0x64),
+       .ptp_control = SJA1110_SPI_ADDR(0x68),
+       .ptpclkval = SJA1110_SPI_ADDR(0x6c),
+       .ptpclkrate = SJA1110_SPI_ADDR(0x74),
+       .ptpclkcorp = SJA1110_SPI_ADDR(0x80),
+       .ptpsyncts = SJA1110_SPI_ADDR(0x84),
+       .mdio_100base_tx = 0x1c2400,
+       .mdio_100base_t1 = 0x1c1000,
 };
 
 const struct sja1105_info sja1105e_info = {
@@ -515,12 +572,25 @@ const struct sja1105_info sja1105e_info = {
        .can_limit_mcast_flood  = false,
        .ptp_ts_bits            = 24,
        .ptpegr_ts_bytes        = 4,
+       .max_frame_mem          = SJA1105_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1105_NUM_PORTS,
        .num_cbs_shapers        = SJA1105ET_MAX_CBS_COUNT,
        .reset_cmd              = sja1105et_reset_cmd,
        .fdb_add_cmd            = sja1105et_fdb_add,
        .fdb_del_cmd            = sja1105et_fdb_del,
        .ptp_cmd_packing        = sja1105et_ptp_cmd_packing,
+       .clocking_setup         = sja1105_clocking_setup,
        .regs                   = &sja1105et_regs,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 3,
+               [SJA1105_SPEED_100MBPS] = 2,
+               [SJA1105_SPEED_1000MBPS] = 1,
+               [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
+       },
+       .supports_mii           = {true, true, true, true, true},
+       .supports_rmii          = {true, true, true, true, true},
+       .supports_rgmii         = {true, true, true, true, true},
        .name                   = "SJA1105E",
 };
 
@@ -533,12 +603,25 @@ const struct sja1105_info sja1105t_info = {
        .can_limit_mcast_flood  = false,
        .ptp_ts_bits            = 24,
        .ptpegr_ts_bytes        = 4,
+       .max_frame_mem          = SJA1105_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1105_NUM_PORTS,
        .num_cbs_shapers        = SJA1105ET_MAX_CBS_COUNT,
        .reset_cmd              = sja1105et_reset_cmd,
        .fdb_add_cmd            = sja1105et_fdb_add,
        .fdb_del_cmd            = sja1105et_fdb_del,
        .ptp_cmd_packing        = sja1105et_ptp_cmd_packing,
+       .clocking_setup         = sja1105_clocking_setup,
        .regs                   = &sja1105et_regs,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 3,
+               [SJA1105_SPEED_100MBPS] = 2,
+               [SJA1105_SPEED_1000MBPS] = 1,
+               [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
+       },
+       .supports_mii           = {true, true, true, true, true},
+       .supports_rmii          = {true, true, true, true, true},
+       .supports_rgmii         = {true, true, true, true, true},
        .name                   = "SJA1105T",
 };
 
@@ -551,13 +634,26 @@ const struct sja1105_info sja1105p_info = {
        .can_limit_mcast_flood  = true,
        .ptp_ts_bits            = 32,
        .ptpegr_ts_bytes        = 8,
+       .max_frame_mem          = SJA1105_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1105_NUM_PORTS,
        .num_cbs_shapers        = SJA1105PQRS_MAX_CBS_COUNT,
        .setup_rgmii_delay      = sja1105pqrs_setup_rgmii_delay,
        .reset_cmd              = sja1105pqrs_reset_cmd,
        .fdb_add_cmd            = sja1105pqrs_fdb_add,
        .fdb_del_cmd            = sja1105pqrs_fdb_del,
        .ptp_cmd_packing        = sja1105pqrs_ptp_cmd_packing,
+       .clocking_setup         = sja1105_clocking_setup,
        .regs                   = &sja1105pqrs_regs,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 3,
+               [SJA1105_SPEED_100MBPS] = 2,
+               [SJA1105_SPEED_1000MBPS] = 1,
+               [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
+       },
+       .supports_mii           = {true, true, true, true, true},
+       .supports_rmii          = {true, true, true, true, true},
+       .supports_rgmii         = {true, true, true, true, true},
        .name                   = "SJA1105P",
 };
 
@@ -570,13 +666,26 @@ const struct sja1105_info sja1105q_info = {
        .can_limit_mcast_flood  = true,
        .ptp_ts_bits            = 32,
        .ptpegr_ts_bytes        = 8,
+       .max_frame_mem          = SJA1105_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1105_NUM_PORTS,
        .num_cbs_shapers        = SJA1105PQRS_MAX_CBS_COUNT,
        .setup_rgmii_delay      = sja1105pqrs_setup_rgmii_delay,
        .reset_cmd              = sja1105pqrs_reset_cmd,
        .fdb_add_cmd            = sja1105pqrs_fdb_add,
        .fdb_del_cmd            = sja1105pqrs_fdb_del,
        .ptp_cmd_packing        = sja1105pqrs_ptp_cmd_packing,
+       .clocking_setup         = sja1105_clocking_setup,
        .regs                   = &sja1105pqrs_regs,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 3,
+               [SJA1105_SPEED_100MBPS] = 2,
+               [SJA1105_SPEED_1000MBPS] = 1,
+               [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
+       },
+       .supports_mii           = {true, true, true, true, true},
+       .supports_rmii          = {true, true, true, true, true},
+       .supports_rgmii         = {true, true, true, true, true},
        .name                   = "SJA1105Q",
 };
 
@@ -589,13 +698,27 @@ const struct sja1105_info sja1105r_info = {
        .can_limit_mcast_flood  = true,
        .ptp_ts_bits            = 32,
        .ptpegr_ts_bytes        = 8,
+       .max_frame_mem          = SJA1105_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1105_NUM_PORTS,
        .num_cbs_shapers        = SJA1105PQRS_MAX_CBS_COUNT,
        .setup_rgmii_delay      = sja1105pqrs_setup_rgmii_delay,
        .reset_cmd              = sja1105pqrs_reset_cmd,
        .fdb_add_cmd            = sja1105pqrs_fdb_add,
        .fdb_del_cmd            = sja1105pqrs_fdb_del,
        .ptp_cmd_packing        = sja1105pqrs_ptp_cmd_packing,
+       .clocking_setup         = sja1105_clocking_setup,
        .regs                   = &sja1105pqrs_regs,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 3,
+               [SJA1105_SPEED_100MBPS] = 2,
+               [SJA1105_SPEED_1000MBPS] = 1,
+               [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
+       },
+       .supports_mii           = {true, true, true, true, true},
+       .supports_rmii          = {true, true, true, true, true},
+       .supports_rgmii         = {true, true, true, true, true},
+       .supports_sgmii         = {false, false, false, false, true},
        .name                   = "SJA1105R",
 };
 
@@ -609,11 +732,203 @@ const struct sja1105_info sja1105s_info = {
        .can_limit_mcast_flood  = true,
        .ptp_ts_bits            = 32,
        .ptpegr_ts_bytes        = 8,
+       .max_frame_mem          = SJA1105_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1105_NUM_PORTS,
        .num_cbs_shapers        = SJA1105PQRS_MAX_CBS_COUNT,
        .setup_rgmii_delay      = sja1105pqrs_setup_rgmii_delay,
        .reset_cmd              = sja1105pqrs_reset_cmd,
        .fdb_add_cmd            = sja1105pqrs_fdb_add,
        .fdb_del_cmd            = sja1105pqrs_fdb_del,
        .ptp_cmd_packing        = sja1105pqrs_ptp_cmd_packing,
+       .clocking_setup         = sja1105_clocking_setup,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 3,
+               [SJA1105_SPEED_100MBPS] = 2,
+               [SJA1105_SPEED_1000MBPS] = 1,
+               [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */
+       },
+       .supports_mii           = {true, true, true, true, true},
+       .supports_rmii          = {true, true, true, true, true},
+       .supports_rgmii         = {true, true, true, true, true},
+       .supports_sgmii         = {false, false, false, false, true},
        .name                   = "SJA1105S",
 };
+
+const struct sja1105_info sja1110a_info = {
+       .device_id              = SJA1110_DEVICE_ID,
+       .part_no                = SJA1110A_PART_NO,
+       .static_ops             = sja1110_table_ops,
+       .dyn_ops                = sja1110_dyn_ops,
+       .regs                   = &sja1110_regs,
+       .qinq_tpid              = ETH_P_8021AD,
+       .can_limit_mcast_flood  = true,
+       .ptp_ts_bits            = 32,
+       .ptpegr_ts_bytes        = 8,
+       .max_frame_mem          = SJA1110_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1110_NUM_PORTS,
+       .num_cbs_shapers        = SJA1110_MAX_CBS_COUNT,
+       .setup_rgmii_delay      = sja1110_setup_rgmii_delay,
+       .reset_cmd              = sja1110_reset_cmd,
+       .fdb_add_cmd            = sja1105pqrs_fdb_add,
+       .fdb_del_cmd            = sja1105pqrs_fdb_del,
+       .ptp_cmd_packing        = sja1105pqrs_ptp_cmd_packing,
+       .clocking_setup         = sja1110_clocking_setup,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 4,
+               [SJA1105_SPEED_100MBPS] = 3,
+               [SJA1105_SPEED_1000MBPS] = 2,
+               [SJA1105_SPEED_2500MBPS] = 1,
+       },
+       .supports_mii           = {true, true, true, true, false,
+                                  true, true, true, true, true, true},
+       .supports_rmii          = {false, false, true, true, false,
+                                  false, false, false, false, false, false},
+       .supports_rgmii         = {false, false, true, true, false,
+                                  false, false, false, false, false, false},
+       .supports_sgmii         = {false, true, true, true, true,
+                                  false, false, false, false, false, false},
+       .supports_2500basex     = {false, false, false, true, true,
+                                  false, false, false, false, false, false},
+       .internal_phy           = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
+                                  SJA1105_NO_PHY, SJA1105_NO_PHY,
+                                  SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
+                                  SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
+                                  SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
+                                  SJA1105_PHY_BASE_T1},
+       .name                   = "SJA1110A",
+};
+
+const struct sja1105_info sja1110b_info = {
+       .device_id              = SJA1110_DEVICE_ID,
+       .part_no                = SJA1110B_PART_NO,
+       .static_ops             = sja1110_table_ops,
+       .dyn_ops                = sja1110_dyn_ops,
+       .regs                   = &sja1110_regs,
+       .qinq_tpid              = ETH_P_8021AD,
+       .can_limit_mcast_flood  = true,
+       .ptp_ts_bits            = 32,
+       .ptpegr_ts_bytes        = 8,
+       .max_frame_mem          = SJA1110_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1110_NUM_PORTS,
+       .num_cbs_shapers        = SJA1110_MAX_CBS_COUNT,
+       .setup_rgmii_delay      = sja1110_setup_rgmii_delay,
+       .reset_cmd              = sja1110_reset_cmd,
+       .fdb_add_cmd            = sja1105pqrs_fdb_add,
+       .fdb_del_cmd            = sja1105pqrs_fdb_del,
+       .ptp_cmd_packing        = sja1105pqrs_ptp_cmd_packing,
+       .clocking_setup         = sja1110_clocking_setup,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 4,
+               [SJA1105_SPEED_100MBPS] = 3,
+               [SJA1105_SPEED_1000MBPS] = 2,
+               [SJA1105_SPEED_2500MBPS] = 1,
+       },
+       .supports_mii           = {true, true, true, true, false,
+                                  true, true, true, true, true, false},
+       .supports_rmii          = {false, false, true, true, false,
+                                  false, false, false, false, false, false},
+       .supports_rgmii         = {false, false, true, true, false,
+                                  false, false, false, false, false, false},
+       .supports_sgmii         = {false, false, false, true, true,
+                                  false, false, false, false, false, false},
+       .supports_2500basex     = {false, false, false, true, true,
+                                  false, false, false, false, false, false},
+       .internal_phy           = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
+                                  SJA1105_NO_PHY, SJA1105_NO_PHY,
+                                  SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
+                                  SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
+                                  SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
+                                  SJA1105_NO_PHY},
+       .name                   = "SJA1110B",
+};
+
+const struct sja1105_info sja1110c_info = {
+       .device_id              = SJA1110_DEVICE_ID,
+       .part_no                = SJA1110C_PART_NO,
+       .static_ops             = sja1110_table_ops,
+       .dyn_ops                = sja1110_dyn_ops,
+       .regs                   = &sja1110_regs,
+       .qinq_tpid              = ETH_P_8021AD,
+       .can_limit_mcast_flood  = true,
+       .ptp_ts_bits            = 32,
+       .ptpegr_ts_bytes        = 8,
+       .max_frame_mem          = SJA1110_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1110_NUM_PORTS,
+       .num_cbs_shapers        = SJA1110_MAX_CBS_COUNT,
+       .setup_rgmii_delay      = sja1110_setup_rgmii_delay,
+       .reset_cmd              = sja1110_reset_cmd,
+       .fdb_add_cmd            = sja1105pqrs_fdb_add,
+       .fdb_del_cmd            = sja1105pqrs_fdb_del,
+       .ptp_cmd_packing        = sja1105pqrs_ptp_cmd_packing,
+       .clocking_setup         = sja1110_clocking_setup,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 4,
+               [SJA1105_SPEED_100MBPS] = 3,
+               [SJA1105_SPEED_1000MBPS] = 2,
+               [SJA1105_SPEED_2500MBPS] = 1,
+       },
+       .supports_mii           = {true, true, true, true, false,
+                                  true, true, true, false, false, false},
+       .supports_rmii          = {false, false, true, true, false,
+                                  false, false, false, false, false, false},
+       .supports_rgmii         = {false, false, true, true, false,
+                                  false, false, false, false, false, false},
+       .supports_sgmii         = {false, false, false, false, true,
+                                  false, false, false, false, false, false},
+       .supports_2500basex     = {false, false, false, false, true,
+                                  false, false, false, false, false, false},
+       .internal_phy           = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX,
+                                  SJA1105_NO_PHY, SJA1105_NO_PHY,
+                                  SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
+                                  SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
+                                  SJA1105_NO_PHY, SJA1105_NO_PHY,
+                                  SJA1105_NO_PHY},
+       .name                   = "SJA1110C",
+};
+
+const struct sja1105_info sja1110d_info = {
+       .device_id              = SJA1110_DEVICE_ID,
+       .part_no                = SJA1110D_PART_NO,
+       .static_ops             = sja1110_table_ops,
+       .dyn_ops                = sja1110_dyn_ops,
+       .regs                   = &sja1110_regs,
+       .qinq_tpid              = ETH_P_8021AD,
+       .can_limit_mcast_flood  = true,
+       .ptp_ts_bits            = 32,
+       .ptpegr_ts_bytes        = 8,
+       .max_frame_mem          = SJA1110_MAX_FRAME_MEMORY,
+       .num_ports              = SJA1110_NUM_PORTS,
+       .num_cbs_shapers        = SJA1110_MAX_CBS_COUNT,
+       .setup_rgmii_delay      = sja1110_setup_rgmii_delay,
+       .reset_cmd              = sja1110_reset_cmd,
+       .fdb_add_cmd            = sja1105pqrs_fdb_add,
+       .fdb_del_cmd            = sja1105pqrs_fdb_del,
+       .ptp_cmd_packing        = sja1105pqrs_ptp_cmd_packing,
+       .clocking_setup         = sja1110_clocking_setup,
+       .port_speed             = {
+               [SJA1105_SPEED_AUTO] = 0,
+               [SJA1105_SPEED_10MBPS] = 4,
+               [SJA1105_SPEED_100MBPS] = 3,
+               [SJA1105_SPEED_1000MBPS] = 2,
+               [SJA1105_SPEED_2500MBPS] = 1,
+       },
+       .supports_mii           = {true, false, true, false, false,
+                                  true, true, true, false, false, false},
+       .supports_rmii          = {false, false, true, false, false,
+                                  false, false, false, false, false, false},
+       .supports_rgmii         = {false, false, true, false, false,
+                                  false, false, false, false, false, false},
+       .supports_sgmii         = {false, true, true, true, true,
+                                  false, false, false, false, false, false},
+       .internal_phy           = {SJA1105_NO_PHY, SJA1105_NO_PHY,
+                                  SJA1105_NO_PHY, SJA1105_NO_PHY,
+                                  SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,
+                                  SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
+                                  SJA1105_NO_PHY, SJA1105_NO_PHY,
+                                  SJA1105_NO_PHY},
+       .name                   = "SJA1110D",
+};