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