linux/drivers/net/dsa/sja1105/sja1105_spi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause
   2/* Copyright (c) 2016-2018, NXP Semiconductors
   3 * Copyright (c) 2018, Sensor-Technik Wiedemann GmbH
   4 * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
   5 */
   6#include <linux/spi/spi.h>
   7#include <linux/packing.h>
   8#include "sja1105.h"
   9
  10#define SJA1105_SIZE_PORT_CTRL          4
  11#define SJA1105_SIZE_RESET_CMD          4
  12#define SJA1105_SIZE_SPI_MSG_HEADER     4
  13#define SJA1105_SIZE_SPI_MSG_MAXLEN     (64 * 4)
  14#define SJA1105_SIZE_SPI_TRANSFER_MAX   \
  15        (SJA1105_SIZE_SPI_MSG_HEADER + SJA1105_SIZE_SPI_MSG_MAXLEN)
  16
  17static int sja1105_spi_transfer(const struct sja1105_private *priv,
  18                                const void *tx, void *rx, int size)
  19{
  20        struct spi_device *spi = priv->spidev;
  21        struct spi_transfer transfer = {
  22                .tx_buf = tx,
  23                .rx_buf = rx,
  24                .len = size,
  25        };
  26        struct spi_message msg;
  27        int rc;
  28
  29        if (size > SJA1105_SIZE_SPI_TRANSFER_MAX) {
  30                dev_err(&spi->dev, "SPI message (%d) longer than max of %d\n",
  31                        size, SJA1105_SIZE_SPI_TRANSFER_MAX);
  32                return -EMSGSIZE;
  33        }
  34
  35        spi_message_init(&msg);
  36        spi_message_add_tail(&transfer, &msg);
  37
  38        rc = spi_sync(spi, &msg);
  39        if (rc < 0) {
  40                dev_err(&spi->dev, "SPI transfer failed: %d\n", rc);
  41                return rc;
  42        }
  43
  44        return rc;
  45}
  46
  47static void
  48sja1105_spi_message_pack(void *buf, const struct sja1105_spi_message *msg)
  49{
  50        const int size = SJA1105_SIZE_SPI_MSG_HEADER;
  51
  52        memset(buf, 0, size);
  53
  54        sja1105_pack(buf, &msg->access,     31, 31, size);
  55        sja1105_pack(buf, &msg->read_count, 30, 25, size);
  56        sja1105_pack(buf, &msg->address,    24,  4, size);
  57}
  58
  59/* If @rw is:
  60 * - SPI_WRITE: creates and sends an SPI write message at absolute
  61 *              address reg_addr, taking size_bytes from *packed_buf
  62 * - SPI_READ:  creates and sends an SPI read message from absolute
  63 *              address reg_addr, writing size_bytes into *packed_buf
  64 *
  65 * This function should only be called if it is priorly known that
  66 * @size_bytes is smaller than SIZE_SPI_MSG_MAXLEN. Larger packed buffers
  67 * are chunked in smaller pieces by sja1105_spi_send_long_packed_buf below.
  68 */
  69int sja1105_spi_send_packed_buf(const struct sja1105_private *priv,
  70                                sja1105_spi_rw_mode_t rw, u64 reg_addr,
  71                                void *packed_buf, size_t size_bytes)
  72{
  73        u8 tx_buf[SJA1105_SIZE_SPI_TRANSFER_MAX] = {0};
  74        u8 rx_buf[SJA1105_SIZE_SPI_TRANSFER_MAX] = {0};
  75        const int msg_len = size_bytes + SJA1105_SIZE_SPI_MSG_HEADER;
  76        struct sja1105_spi_message msg = {0};
  77        int rc;
  78
  79        if (msg_len > SJA1105_SIZE_SPI_TRANSFER_MAX)
  80                return -ERANGE;
  81
  82        msg.access = rw;
  83        msg.address = reg_addr;
  84        if (rw == SPI_READ)
  85                msg.read_count = size_bytes / 4;
  86
  87        sja1105_spi_message_pack(tx_buf, &msg);
  88
  89        if (rw == SPI_WRITE)
  90                memcpy(tx_buf + SJA1105_SIZE_SPI_MSG_HEADER,
  91                       packed_buf, size_bytes);
  92
  93        rc = sja1105_spi_transfer(priv, tx_buf, rx_buf, msg_len);
  94        if (rc < 0)
  95                return rc;
  96
  97        if (rw == SPI_READ)
  98                memcpy(packed_buf, rx_buf + SJA1105_SIZE_SPI_MSG_HEADER,
  99                       size_bytes);
 100
 101        return 0;
 102}
 103
 104/* If @rw is:
 105 * - SPI_WRITE: creates and sends an SPI write message at absolute
 106 *              address reg_addr, taking size_bytes from *packed_buf
 107 * - SPI_READ:  creates and sends an SPI read message from absolute
 108 *              address reg_addr, writing size_bytes into *packed_buf
 109 *
 110 * The u64 *value is unpacked, meaning that it's stored in the native
 111 * CPU endianness and directly usable by software running on the core.
 112 *
 113 * This is a wrapper around sja1105_spi_send_packed_buf().
 114 */
 115int sja1105_spi_send_int(const struct sja1105_private *priv,
 116                         sja1105_spi_rw_mode_t rw, u64 reg_addr,
 117                         u64 *value, u64 size_bytes)
 118{
 119        u8 packed_buf[SJA1105_SIZE_SPI_MSG_MAXLEN];
 120        int rc;
 121
 122        if (size_bytes > SJA1105_SIZE_SPI_MSG_MAXLEN)
 123                return -ERANGE;
 124
 125        if (rw == SPI_WRITE)
 126                sja1105_pack(packed_buf, value, 8 * size_bytes - 1, 0,
 127                             size_bytes);
 128
 129        rc = sja1105_spi_send_packed_buf(priv, rw, reg_addr, packed_buf,
 130                                         size_bytes);
 131
 132        if (rw == SPI_READ)
 133                sja1105_unpack(packed_buf, value, 8 * size_bytes - 1, 0,
 134                               size_bytes);
 135
 136        return rc;
 137}
 138
 139/* Should be used if a @packed_buf larger than SJA1105_SIZE_SPI_MSG_MAXLEN
 140 * must be sent/received. Splitting the buffer into chunks and assembling
 141 * those into SPI messages is done automatically by this function.
 142 */
 143int sja1105_spi_send_long_packed_buf(const struct sja1105_private *priv,
 144                                     sja1105_spi_rw_mode_t rw, u64 base_addr,
 145                                     void *packed_buf, u64 buf_len)
 146{
 147        struct chunk {
 148                void *buf_ptr;
 149                int len;
 150                u64 spi_address;
 151        } chunk;
 152        int distance_to_end;
 153        int rc;
 154
 155        /* Initialize chunk */
 156        chunk.buf_ptr = packed_buf;
 157        chunk.spi_address = base_addr;
 158        chunk.len = min_t(int, buf_len, SJA1105_SIZE_SPI_MSG_MAXLEN);
 159
 160        while (chunk.len) {
 161                rc = sja1105_spi_send_packed_buf(priv, rw, chunk.spi_address,
 162                                                 chunk.buf_ptr, chunk.len);
 163                if (rc < 0)
 164                        return rc;
 165
 166                chunk.buf_ptr += chunk.len;
 167                chunk.spi_address += chunk.len / 4;
 168                distance_to_end = (uintptr_t)(packed_buf + buf_len -
 169                                              chunk.buf_ptr);
 170                chunk.len = min(distance_to_end, SJA1105_SIZE_SPI_MSG_MAXLEN);
 171        }
 172
 173        return 0;
 174}
 175
 176/* Back-ported structure from UM11040 Table 112.
 177 * Reset control register (addr. 100440h)
 178 * In the SJA1105 E/T, only warm_rst and cold_rst are
 179 * supported (exposed in UM10944 as rst_ctrl), but the bit
 180 * offsets of warm_rst and cold_rst are actually reversed.
 181 */
 182struct sja1105_reset_cmd {
 183        u64 switch_rst;
 184        u64 cfg_rst;
 185        u64 car_rst;
 186        u64 otp_rst;
 187        u64 warm_rst;
 188        u64 cold_rst;
 189        u64 por_rst;
 190};
 191
 192static void
 193sja1105et_reset_cmd_pack(void *buf, const struct sja1105_reset_cmd *reset)
 194{
 195        const int size = SJA1105_SIZE_RESET_CMD;
 196
 197        memset(buf, 0, size);
 198
 199        sja1105_pack(buf, &reset->cold_rst, 3, 3, size);
 200        sja1105_pack(buf, &reset->warm_rst, 2, 2, size);
 201}
 202
 203static void
 204sja1105pqrs_reset_cmd_pack(void *buf, const struct sja1105_reset_cmd *reset)
 205{
 206        const int size = SJA1105_SIZE_RESET_CMD;
 207
 208        memset(buf, 0, size);
 209
 210        sja1105_pack(buf, &reset->switch_rst, 8, 8, size);
 211        sja1105_pack(buf, &reset->cfg_rst,    7, 7, size);
 212        sja1105_pack(buf, &reset->car_rst,    5, 5, size);
 213        sja1105_pack(buf, &reset->otp_rst,    4, 4, size);
 214        sja1105_pack(buf, &reset->warm_rst,   3, 3, size);
 215        sja1105_pack(buf, &reset->cold_rst,   2, 2, size);
 216        sja1105_pack(buf, &reset->por_rst,    1, 1, size);
 217}
 218
 219static int sja1105et_reset_cmd(const void *ctx, const void *data)
 220{
 221        const struct sja1105_private *priv = ctx;
 222        const struct sja1105_reset_cmd *reset = data;
 223        const struct sja1105_regs *regs = priv->info->regs;
 224        struct device *dev = priv->ds->dev;
 225        u8 packed_buf[SJA1105_SIZE_RESET_CMD];
 226
 227        if (reset->switch_rst ||
 228            reset->cfg_rst ||
 229            reset->car_rst ||
 230            reset->otp_rst ||
 231            reset->por_rst) {
 232                dev_err(dev, "Only warm and cold reset is supported "
 233                        "for SJA1105 E/T!\n");
 234                return -EINVAL;
 235        }
 236
 237        if (reset->warm_rst)
 238                dev_dbg(dev, "Warm reset requested\n");
 239        if (reset->cold_rst)
 240                dev_dbg(dev, "Cold reset requested\n");
 241
 242        sja1105et_reset_cmd_pack(packed_buf, reset);
 243
 244        return sja1105_spi_send_packed_buf(priv, SPI_WRITE, regs->rgu,
 245                                           packed_buf, SJA1105_SIZE_RESET_CMD);
 246}
 247
 248static int sja1105pqrs_reset_cmd(const void *ctx, const void *data)
 249{
 250        const struct sja1105_private *priv = ctx;
 251        const struct sja1105_reset_cmd *reset = data;
 252        const struct sja1105_regs *regs = priv->info->regs;
 253        struct device *dev = priv->ds->dev;
 254        u8 packed_buf[SJA1105_SIZE_RESET_CMD];
 255
 256        if (reset->switch_rst)
 257                dev_dbg(dev, "Main reset for all functional modules requested\n");
 258        if (reset->cfg_rst)
 259                dev_dbg(dev, "Chip configuration reset requested\n");
 260        if (reset->car_rst)
 261                dev_dbg(dev, "Clock and reset control logic reset requested\n");
 262        if (reset->otp_rst)
 263                dev_dbg(dev, "OTP read cycle for reading product "
 264                        "config settings requested\n");
 265        if (reset->warm_rst)
 266                dev_dbg(dev, "Warm reset requested\n");
 267        if (reset->cold_rst)
 268                dev_dbg(dev, "Cold reset requested\n");
 269        if (reset->por_rst)
 270                dev_dbg(dev, "Power-on reset requested\n");
 271
 272        sja1105pqrs_reset_cmd_pack(packed_buf, reset);
 273
 274        return sja1105_spi_send_packed_buf(priv, SPI_WRITE, regs->rgu,
 275                                           packed_buf, SJA1105_SIZE_RESET_CMD);
 276}
 277
 278static int sja1105_cold_reset(const struct sja1105_private *priv)
 279{
 280        struct sja1105_reset_cmd reset = {0};
 281
 282        reset.cold_rst = 1;
 283        return priv->info->reset_cmd(priv, &reset);
 284}
 285
 286int sja1105_inhibit_tx(const struct sja1105_private *priv,
 287                       unsigned long port_bitmap, bool tx_inhibited)
 288{
 289        const struct sja1105_regs *regs = priv->info->regs;
 290        u64 inhibit_cmd;
 291        int rc;
 292
 293        rc = sja1105_spi_send_int(priv, SPI_READ, regs->port_control,
 294                                  &inhibit_cmd, SJA1105_SIZE_PORT_CTRL);
 295        if (rc < 0)
 296                return rc;
 297
 298        if (tx_inhibited)
 299                inhibit_cmd |= port_bitmap;
 300        else
 301                inhibit_cmd &= ~port_bitmap;
 302
 303        return sja1105_spi_send_int(priv, SPI_WRITE, regs->port_control,
 304                                    &inhibit_cmd, SJA1105_SIZE_PORT_CTRL);
 305}
 306
 307struct sja1105_status {
 308        u64 configs;
 309        u64 crcchkl;
 310        u64 ids;
 311        u64 crcchkg;
 312};
 313
 314/* This is not reading the entire General Status area, which is also
 315 * divergent between E/T and P/Q/R/S, but only the relevant bits for
 316 * ensuring that the static config upload procedure was successful.
 317 */
 318static void sja1105_status_unpack(void *buf, struct sja1105_status *status)
 319{
 320        /* So that addition translates to 4 bytes */
 321        u32 *p = buf;
 322
 323        /* device_id is missing from the buffer, but we don't
 324         * want to diverge from the manual definition of the
 325         * register addresses, so we'll back off one step with
 326         * the register pointer, and never access p[0].
 327         */
 328        p--;
 329        sja1105_unpack(p + 0x1, &status->configs,   31, 31, 4);
 330        sja1105_unpack(p + 0x1, &status->crcchkl,   30, 30, 4);
 331        sja1105_unpack(p + 0x1, &status->ids,       29, 29, 4);
 332        sja1105_unpack(p + 0x1, &status->crcchkg,   28, 28, 4);
 333}
 334
 335static int sja1105_status_get(struct sja1105_private *priv,
 336                              struct sja1105_status *status)
 337{
 338        const struct sja1105_regs *regs = priv->info->regs;
 339        u8 packed_buf[4];
 340        int rc;
 341
 342        rc = sja1105_spi_send_packed_buf(priv, SPI_READ,
 343                                         regs->status,
 344                                         packed_buf, 4);
 345        if (rc < 0)
 346                return rc;
 347
 348        sja1105_status_unpack(packed_buf, status);
 349
 350        return 0;
 351}
 352
 353/* Not const because unpacking priv->static_config into buffers and preparing
 354 * for upload requires the recalculation of table CRCs and updating the
 355 * structures with these.
 356 */
 357static int
 358static_config_buf_prepare_for_upload(struct sja1105_private *priv,
 359                                     void *config_buf, int buf_len)
 360{
 361        struct sja1105_static_config *config = &priv->static_config;
 362        struct sja1105_table_header final_header;
 363        sja1105_config_valid_t valid;
 364        char *final_header_ptr;
 365        int crc_len;
 366
 367        valid = sja1105_static_config_check_valid(config);
 368        if (valid != SJA1105_CONFIG_OK) {
 369                dev_err(&priv->spidev->dev,
 370                        sja1105_static_config_error_msg[valid]);
 371                return -EINVAL;
 372        }
 373
 374        /* Write Device ID and config tables to config_buf */
 375        sja1105_static_config_pack(config_buf, config);
 376        /* Recalculate CRC of the last header (right now 0xDEADBEEF).
 377         * Don't include the CRC field itself.
 378         */
 379        crc_len = buf_len - 4;
 380        /* Read the whole table header */
 381        final_header_ptr = config_buf + buf_len - SJA1105_SIZE_TABLE_HEADER;
 382        sja1105_table_header_packing(final_header_ptr, &final_header, UNPACK);
 383        /* Modify */
 384        final_header.crc = sja1105_crc32(config_buf, crc_len);
 385        /* Rewrite */
 386        sja1105_table_header_packing(final_header_ptr, &final_header, PACK);
 387
 388        return 0;
 389}
 390
 391#define RETRIES 10
 392
 393int sja1105_static_config_upload(struct sja1105_private *priv)
 394{
 395        unsigned long port_bitmap = GENMASK_ULL(SJA1105_NUM_PORTS - 1, 0);
 396        struct sja1105_static_config *config = &priv->static_config;
 397        const struct sja1105_regs *regs = priv->info->regs;
 398        struct device *dev = &priv->spidev->dev;
 399        struct sja1105_status status;
 400        int rc, retries = RETRIES;
 401        u8 *config_buf;
 402        int buf_len;
 403
 404        buf_len = sja1105_static_config_get_length(config);
 405        config_buf = kcalloc(buf_len, sizeof(char), GFP_KERNEL);
 406        if (!config_buf)
 407                return -ENOMEM;
 408
 409        rc = static_config_buf_prepare_for_upload(priv, config_buf, buf_len);
 410        if (rc < 0) {
 411                dev_err(dev, "Invalid config, cannot upload\n");
 412                return -EINVAL;
 413        }
 414        /* Prevent PHY jabbering during switch reset by inhibiting
 415         * Tx on all ports and waiting for current packet to drain.
 416         * Otherwise, the PHY will see an unterminated Ethernet packet.
 417         */
 418        rc = sja1105_inhibit_tx(priv, port_bitmap, true);
 419        if (rc < 0) {
 420                dev_err(dev, "Failed to inhibit Tx on ports\n");
 421                return -ENXIO;
 422        }
 423        /* Wait for an eventual egress packet to finish transmission
 424         * (reach IFG). It is guaranteed that a second one will not
 425         * follow, and that switch cold reset is thus safe
 426         */
 427        usleep_range(500, 1000);
 428        do {
 429                /* Put the SJA1105 in programming mode */
 430                rc = sja1105_cold_reset(priv);
 431                if (rc < 0) {
 432                        dev_err(dev, "Failed to reset switch, retrying...\n");
 433                        continue;
 434                }
 435                /* Wait for the switch to come out of reset */
 436                usleep_range(1000, 5000);
 437                /* Upload the static config to the device */
 438                rc = sja1105_spi_send_long_packed_buf(priv, SPI_WRITE,
 439                                                      regs->config,
 440                                                      config_buf, buf_len);
 441                if (rc < 0) {
 442                        dev_err(dev, "Failed to upload config, retrying...\n");
 443                        continue;
 444                }
 445                /* Check that SJA1105 responded well to the config upload */
 446                rc = sja1105_status_get(priv, &status);
 447                if (rc < 0)
 448                        continue;
 449
 450                if (status.ids == 1) {
 451                        dev_err(dev, "Mismatch between hardware and static config "
 452                                "device id. Wrote 0x%llx, wants 0x%llx\n",
 453                                config->device_id, priv->info->device_id);
 454                        continue;
 455                }
 456                if (status.crcchkl == 1) {
 457                        dev_err(dev, "Switch reported invalid local CRC on "
 458                                "the uploaded config, retrying...\n");
 459                        continue;
 460                }
 461                if (status.crcchkg == 1) {
 462                        dev_err(dev, "Switch reported invalid global CRC on "
 463                                "the uploaded config, retrying...\n");
 464                        continue;
 465                }
 466                if (status.configs == 0) {
 467                        dev_err(dev, "Switch reported that configuration is "
 468                                "invalid, retrying...\n");
 469                        continue;
 470                }
 471                /* Success! */
 472                break;
 473        } while (--retries);
 474
 475        if (!retries) {
 476                rc = -EIO;
 477                dev_err(dev, "Failed to upload config to device, giving up\n");
 478                goto out;
 479        } else if (retries != RETRIES) {
 480                dev_info(dev, "Succeeded after %d tried\n", RETRIES - retries);
 481        }
 482
 483        rc = sja1105_ptp_reset(priv);
 484        if (rc < 0)
 485                dev_err(dev, "Failed to reset PTP clock: %d\n", rc);
 486
 487        dev_info(dev, "Reset switch and programmed static config\n");
 488
 489out:
 490        kfree(config_buf);
 491        return rc;
 492}
 493
 494static struct sja1105_regs sja1105et_regs = {
 495        .device_id = 0x0,
 496        .prod_id = 0x100BC3,
 497        .status = 0x1,
 498        .port_control = 0x11,
 499        .config = 0x020000,
 500        .rgu = 0x100440,
 501        /* UM10944.pdf, Table 86, ACU Register overview */
 502        .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
 503        .rmii_pll1 = 0x10000A,
 504        .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
 505        .mac = {0x200, 0x202, 0x204, 0x206, 0x208},
 506        .mac_hl1 = {0x400, 0x410, 0x420, 0x430, 0x440},
 507        .mac_hl2 = {0x600, 0x610, 0x620, 0x630, 0x640},
 508        /* UM10944.pdf, Table 78, CGU Register overview */
 509        .mii_tx_clk = {0x100013, 0x10001A, 0x100021, 0x100028, 0x10002F},
 510        .mii_rx_clk = {0x100014, 0x10001B, 0x100022, 0x100029, 0x100030},
 511        .mii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
 512        .mii_ext_rx_clk = {0x100019, 0x100020, 0x100027, 0x10002E, 0x100035},
 513        .rgmii_tx_clk = {0x100016, 0x10001D, 0x100024, 0x10002B, 0x100032},
 514        .rmii_ref_clk = {0x100015, 0x10001C, 0x100023, 0x10002A, 0x100031},
 515        .rmii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
 516        .ptpegr_ts = {0xC0, 0xC2, 0xC4, 0xC6, 0xC8},
 517        .ptp_control = 0x17,
 518        .ptpclk = 0x18, /* Spans 0x18 to 0x19 */
 519        .ptpclkrate = 0x1A,
 520        .ptptsclk = 0x1B, /* Spans 0x1B to 0x1C */
 521};
 522
 523static struct sja1105_regs sja1105pqrs_regs = {
 524        .device_id = 0x0,
 525        .prod_id = 0x100BC3,
 526        .status = 0x1,
 527        .port_control = 0x12,
 528        .config = 0x020000,
 529        .rgu = 0x100440,
 530        /* UM10944.pdf, Table 86, ACU Register overview */
 531        .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
 532        .pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814},
 533        .rmii_pll1 = 0x10000A,
 534        .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
 535        .mac = {0x200, 0x202, 0x204, 0x206, 0x208},
 536        .mac_hl1 = {0x400, 0x410, 0x420, 0x430, 0x440},
 537        .mac_hl2 = {0x600, 0x610, 0x620, 0x630, 0x640},
 538        /* UM11040.pdf, Table 114 */
 539        .mii_tx_clk = {0x100013, 0x100019, 0x10001F, 0x100025, 0x10002B},
 540        .mii_rx_clk = {0x100014, 0x10001A, 0x100020, 0x100026, 0x10002C},
 541        .mii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
 542        .mii_ext_rx_clk = {0x100018, 0x10001E, 0x100024, 0x10002A, 0x100030},
 543        .rgmii_tx_clk = {0x100016, 0x10001C, 0x100022, 0x100028, 0x10002E},
 544        .rmii_ref_clk = {0x100015, 0x10001B, 0x100021, 0x100027, 0x10002D},
 545        .rmii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
 546        .qlevel = {0x604, 0x614, 0x624, 0x634, 0x644},
 547        .ptpegr_ts = {0xC0, 0xC4, 0xC8, 0xCC, 0xD0},
 548        .ptp_control = 0x18,
 549        .ptpclk = 0x19,
 550        .ptpclkrate = 0x1B,
 551        .ptptsclk = 0x1C,
 552};
 553
 554struct sja1105_info sja1105e_info = {
 555        .device_id              = SJA1105E_DEVICE_ID,
 556        .part_no                = SJA1105ET_PART_NO,
 557        .static_ops             = sja1105e_table_ops,
 558        .dyn_ops                = sja1105et_dyn_ops,
 559        .ptp_ts_bits            = 24,
 560        .ptpegr_ts_bytes        = 4,
 561        .reset_cmd              = sja1105et_reset_cmd,
 562        .fdb_add_cmd            = sja1105et_fdb_add,
 563        .fdb_del_cmd            = sja1105et_fdb_del,
 564        .ptp_cmd                = sja1105et_ptp_cmd,
 565        .regs                   = &sja1105et_regs,
 566        .name                   = "SJA1105E",
 567};
 568struct sja1105_info sja1105t_info = {
 569        .device_id              = SJA1105T_DEVICE_ID,
 570        .part_no                = SJA1105ET_PART_NO,
 571        .static_ops             = sja1105t_table_ops,
 572        .dyn_ops                = sja1105et_dyn_ops,
 573        .ptp_ts_bits            = 24,
 574        .ptpegr_ts_bytes        = 4,
 575        .reset_cmd              = sja1105et_reset_cmd,
 576        .fdb_add_cmd            = sja1105et_fdb_add,
 577        .fdb_del_cmd            = sja1105et_fdb_del,
 578        .ptp_cmd                = sja1105et_ptp_cmd,
 579        .regs                   = &sja1105et_regs,
 580        .name                   = "SJA1105T",
 581};
 582struct sja1105_info sja1105p_info = {
 583        .device_id              = SJA1105PR_DEVICE_ID,
 584        .part_no                = SJA1105P_PART_NO,
 585        .static_ops             = sja1105p_table_ops,
 586        .dyn_ops                = sja1105pqrs_dyn_ops,
 587        .ptp_ts_bits            = 32,
 588        .ptpegr_ts_bytes        = 8,
 589        .setup_rgmii_delay      = sja1105pqrs_setup_rgmii_delay,
 590        .reset_cmd              = sja1105pqrs_reset_cmd,
 591        .fdb_add_cmd            = sja1105pqrs_fdb_add,
 592        .fdb_del_cmd            = sja1105pqrs_fdb_del,
 593        .ptp_cmd                = sja1105pqrs_ptp_cmd,
 594        .regs                   = &sja1105pqrs_regs,
 595        .name                   = "SJA1105P",
 596};
 597struct sja1105_info sja1105q_info = {
 598        .device_id              = SJA1105QS_DEVICE_ID,
 599        .part_no                = SJA1105Q_PART_NO,
 600        .static_ops             = sja1105q_table_ops,
 601        .dyn_ops                = sja1105pqrs_dyn_ops,
 602        .ptp_ts_bits            = 32,
 603        .ptpegr_ts_bytes        = 8,
 604        .setup_rgmii_delay      = sja1105pqrs_setup_rgmii_delay,
 605        .reset_cmd              = sja1105pqrs_reset_cmd,
 606        .fdb_add_cmd            = sja1105pqrs_fdb_add,
 607        .fdb_del_cmd            = sja1105pqrs_fdb_del,
 608        .ptp_cmd                = sja1105pqrs_ptp_cmd,
 609        .regs                   = &sja1105pqrs_regs,
 610        .name                   = "SJA1105Q",
 611};
 612struct sja1105_info sja1105r_info = {
 613        .device_id              = SJA1105PR_DEVICE_ID,
 614        .part_no                = SJA1105R_PART_NO,
 615        .static_ops             = sja1105r_table_ops,
 616        .dyn_ops                = sja1105pqrs_dyn_ops,
 617        .ptp_ts_bits            = 32,
 618        .ptpegr_ts_bytes        = 8,
 619        .setup_rgmii_delay      = sja1105pqrs_setup_rgmii_delay,
 620        .reset_cmd              = sja1105pqrs_reset_cmd,
 621        .fdb_add_cmd            = sja1105pqrs_fdb_add,
 622        .fdb_del_cmd            = sja1105pqrs_fdb_del,
 623        .ptp_cmd                = sja1105pqrs_ptp_cmd,
 624        .regs                   = &sja1105pqrs_regs,
 625        .name                   = "SJA1105R",
 626};
 627struct sja1105_info sja1105s_info = {
 628        .device_id              = SJA1105QS_DEVICE_ID,
 629        .part_no                = SJA1105S_PART_NO,
 630        .static_ops             = sja1105s_table_ops,
 631        .dyn_ops                = sja1105pqrs_dyn_ops,
 632        .regs                   = &sja1105pqrs_regs,
 633        .ptp_ts_bits            = 32,
 634        .ptpegr_ts_bytes        = 8,
 635        .setup_rgmii_delay      = sja1105pqrs_setup_rgmii_delay,
 636        .reset_cmd              = sja1105pqrs_reset_cmd,
 637        .fdb_add_cmd            = sja1105pqrs_fdb_add,
 638        .fdb_del_cmd            = sja1105pqrs_fdb_del,
 639        .ptp_cmd                = sja1105pqrs_ptp_cmd,
 640        .name                   = "SJA1105S",
 641};
 642