0001
0002
0003
0004
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
0029
0030
0031
0032
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
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
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
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
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
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
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
0123
0124
0125
0126
0127
0128
0129
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
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
0160
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
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
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
0203
0204
0205
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
0239
0240
0241
0242 static void sja1105_status_unpack(void *buf, struct sja1105_status *status)
0243 {
0244
0245 u32 *p = buf;
0246
0247
0248
0249
0250
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
0276
0277
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
0297 sja1105_static_config_pack(config_buf, config);
0298
0299
0300
0301 crc_len = buf_len - 4;
0302
0303 final_header_ptr = config_buf + buf_len - SJA1105_SIZE_TABLE_HEADER;
0304 sja1105_table_header_packing(final_header_ptr, &final_header, UNPACK);
0305
0306 final_header.crc = sja1105_crc32(config_buf, crc_len);
0307
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
0338
0339
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
0348
0349
0350
0351 usleep_range(500, 1000);
0352 do {
0353
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
0360 usleep_range(1000, 5000);
0361
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
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
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
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
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,
0437 .ptppinst = 0x14,
0438 .ptppindur = 0x16,
0439 .ptp_control = 0x17,
0440 .ptpclkval = 0x18,
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
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
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,
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),
0491 .vl_status = 0x10000,
0492 .config = 0x020000,
0493 .rgu = SJA1110_RGU_ADDR(0x100),
0494
0495
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,
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,
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,
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,
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,
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,
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 };