]>
Commit | Line | Data |
---|---|---|
8aa9ebcc VO |
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 | ||
08839c06 VO |
10 | struct sja1105_chunk { |
11 | u8 *buf; | |
12 | size_t len; | |
13 | u64 reg_addr; | |
14 | }; | |
8aa9ebcc | 15 | |
8aa9ebcc VO |
16 | static void |
17 | sja1105_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 absolute | |
08839c06 | 30 | * address reg_addr, taking @len bytes from *buf |
8aa9ebcc | 31 | * - SPI_READ: creates and sends an SPI read message from absolute |
08839c06 | 32 | * address reg_addr, writing @len bytes into *buf |
8aa9ebcc | 33 | */ |
34d76e9f VO |
34 | static 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) | |
8aa9ebcc | 37 | { |
ca021f0d | 38 | u8 hdr_buf[SJA1105_SIZE_SPI_MSG_HEADER] = {0}; |
08839c06 | 39 | struct spi_device *spi = priv->spidev; |
ca021f0d VO |
40 | struct spi_transfer xfers[2] = {0}; |
41 | struct spi_transfer *chunk_xfer; | |
42 | struct spi_transfer *hdr_xfer; | |
718bad0e | 43 | struct sja1105_chunk chunk; |
08839c06 VO |
44 | int num_chunks; |
45 | int rc, i = 0; | |
8aa9ebcc | 46 | |
718bad0e VO |
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); | |
8aa9ebcc | 52 | |
ca021f0d VO |
53 | hdr_xfer = &xfers[0]; |
54 | chunk_xfer = &xfers[1]; | |
8aa9ebcc | 55 | |
08839c06 | 56 | for (i = 0; i < num_chunks; i++) { |
34d76e9f | 57 | struct spi_transfer *ptp_sts_xfer; |
08839c06 VO |
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 | else | |
66 | /* 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 | else | |
76 | chunk_xfer->tx_buf = chunk.buf; | |
77 | chunk_xfer->len = chunk.len; | |
78 | ||
34d76e9f VO |
79 | /* Request timestamping for the transfer. Instead of letting |
80 | * callers specify which byte they want to timestamp, we can | |
81 | * make certain assumptions: | |
82 | * - A read operation will request a software timestamp when | |
83 | * what's being read is the PTP time. That is snapshotted by | |
84 | * the switch hardware at the end of the command portion | |
85 | * (hdr_xfer). | |
86 | * - A write operation will request a software timestamp on | |
87 | * actions that modify the PTP time. Taking clock stepping as | |
88 | * an example, the switch writes the PTP time at the end of | |
89 | * the data portion (chunk_xfer). | |
90 | */ | |
91 | if (rw == SPI_READ) | |
92 | ptp_sts_xfer = hdr_xfer; | |
93 | else | |
94 | 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 | ||
08839c06 VO |
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), | |
718bad0e | 103 | priv->max_xfer_len); |
08839c06 | 104 | |
ca021f0d VO |
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 | } | |
08839c06 | 110 | } |
8a559400 | 111 | |
ca021f0d | 112 | return 0; |
8aa9ebcc VO |
113 | } |
114 | ||
34d76e9f VO |
115 | int 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 | ||
8aa9ebcc VO |
122 | /* If @rw is: |
123 | * - SPI_WRITE: creates and sends an SPI write message at absolute | |
dff79620 | 124 | * address reg_addr |
8aa9ebcc | 125 | * - SPI_READ: creates and sends an SPI read message from absolute |
dff79620 | 126 | * address reg_addr |
8aa9ebcc VO |
127 | * |
128 | * The u64 *value is unpacked, meaning that it's stored in the native | |
129 | * CPU endianness and directly usable by software running on the core. | |
8aa9ebcc | 130 | */ |
dff79620 | 131 | int sja1105_xfer_u64(const struct sja1105_private *priv, |
34d76e9f VO |
132 | sja1105_spi_rw_mode_t rw, u64 reg_addr, u64 *value, |
133 | struct ptp_system_timestamp *ptp_sts) | |
8aa9ebcc | 134 | { |
dff79620 | 135 | u8 packed_buf[8]; |
8aa9ebcc VO |
136 | int rc; |
137 | ||
8aa9ebcc | 138 | if (rw == SPI_WRITE) |
dff79620 | 139 | sja1105_pack(packed_buf, value, 63, 0, 8); |
8aa9ebcc | 140 | |
34d76e9f | 141 | rc = sja1105_xfer(priv, rw, reg_addr, packed_buf, 8, ptp_sts); |
8aa9ebcc VO |
142 | |
143 | if (rw == SPI_READ) | |
dff79620 VO |
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 */ | |
150 | int sja1105_xfer_u32(const struct sja1105_private *priv, | |
34d76e9f VO |
151 | sja1105_spi_rw_mode_t rw, u64 reg_addr, u32 *value, |
152 | struct ptp_system_timestamp *ptp_sts) | |
dff79620 VO |
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 | ||
34d76e9f | 166 | rc = sja1105_xfer(priv, rw, reg_addr, packed_buf, 4, ptp_sts); |
dff79620 VO |
167 | |
168 | if (rw == SPI_READ) { | |
169 | sja1105_unpack(packed_buf, &tmp, 31, 0, 4); | |
170 | *value = tmp; | |
171 | } | |
8aa9ebcc VO |
172 | |
173 | return rc; | |
174 | } | |
175 | ||
abfb228a | 176 | static int sja1105et_reset_cmd(struct dsa_switch *ds) |
8aa9ebcc | 177 | { |
abfb228a | 178 | struct sja1105_private *priv = ds->priv; |
8aa9ebcc | 179 | const struct sja1105_regs *regs = priv->info->regs; |
f78a2517 | 180 | u32 cold_reset = BIT(3); |
8aa9ebcc | 181 | |
f78a2517 VO |
182 | /* Cold reset */ |
183 | return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL); | |
8aa9ebcc VO |
184 | } |
185 | ||
abfb228a | 186 | static int sja1105pqrs_reset_cmd(struct dsa_switch *ds) |
8aa9ebcc | 187 | { |
abfb228a | 188 | struct sja1105_private *priv = ds->priv; |
8aa9ebcc | 189 | const struct sja1105_regs *regs = priv->info->regs; |
f78a2517 | 190 | u32 cold_reset = BIT(2); |
8aa9ebcc | 191 | |
f78a2517 VO |
192 | /* Cold reset */ |
193 | return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL); | |
8aa9ebcc VO |
194 | } |
195 | ||
3e77e59b VO |
196 | static 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 | ||
cb5a82d2 VO |
202 | /* Only reset the switch core. |
203 | * A full cold reset would re-enable the BASE_MCSS_CLOCK PLL which | |
204 | * would turn on the microcontroller, potentially letting it execute | |
205 | * code which could interfere with our configuration. | |
206 | */ | |
3e77e59b VO |
207 | return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &switch_reset, NULL); |
208 | } | |
209 | ||
d114fb04 VO |
210 | int sja1105_inhibit_tx(const struct sja1105_private *priv, |
211 | unsigned long port_bitmap, bool tx_inhibited) | |
1a4c6940 VO |
212 | { |
213 | const struct sja1105_regs *regs = priv->info->regs; | |
dff79620 | 214 | u32 inhibit_cmd; |
d114fb04 | 215 | int rc; |
1a4c6940 | 216 | |
dff79620 | 217 | rc = sja1105_xfer_u32(priv, SPI_READ, regs->port_control, |
34d76e9f | 218 | &inhibit_cmd, NULL); |
1a4c6940 VO |
219 | if (rc < 0) |
220 | return rc; | |
221 | ||
d114fb04 VO |
222 | if (tx_inhibited) |
223 | inhibit_cmd |= port_bitmap; | |
224 | else | |
225 | inhibit_cmd &= ~port_bitmap; | |
1a4c6940 | 226 | |
dff79620 | 227 | return sja1105_xfer_u32(priv, SPI_WRITE, regs->port_control, |
34d76e9f | 228 | &inhibit_cmd, NULL); |
1a4c6940 VO |
229 | } |
230 | ||
8aa9ebcc VO |
231 | struct 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 also | |
239 | * divergent between E/T and P/Q/R/S, but only the relevant bits for | |
240 | * ensuring that the static config upload procedure was successful. | |
241 | */ | |
242 | static 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't | |
248 | * want to diverge from the manual definition of the | |
249 | * register addresses, so we'll back off one step with | |
250 | * 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 | ||
259 | static 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 | ||
1bd44870 | 266 | rc = sja1105_xfer_buf(priv, SPI_READ, regs->status, packed_buf, 4); |
8aa9ebcc VO |
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 preparing | |
276 | * for upload requires the recalculation of table CRCs and updating the | |
277 | * structures with these. | |
278 | */ | |
bf425b82 VO |
279 | int static_config_buf_prepare_for_upload(struct sja1105_private *priv, |
280 | void *config_buf, int buf_len) | |
8aa9ebcc VO |
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 | ||
1bf658ee VO |
288 | valid = sja1105_static_config_check_valid(config, |
289 | priv->info->max_frame_mem); | |
8aa9ebcc VO |
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 10 | |
314 | ||
315 | int 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; | |
542043e9 | 320 | struct dsa_switch *ds = priv->ds; |
8aa9ebcc VO |
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"); | |
68501df9 NE |
334 | rc = -EINVAL; |
335 | goto out; | |
8aa9ebcc | 336 | } |
1a4c6940 VO |
337 | /* Prevent PHY jabbering during switch reset by inhibiting |
338 | * Tx on all ports and waiting for current packet to drain. | |
339 | * Otherwise, the PHY will see an unterminated Ethernet packet. | |
340 | */ | |
542043e9 | 341 | rc = sja1105_inhibit_tx(priv, GENMASK_ULL(ds->num_ports - 1, 0), true); |
1a4c6940 VO |
342 | if (rc < 0) { |
343 | dev_err(dev, "Failed to inhibit Tx on ports\n"); | |
68501df9 NE |
344 | rc = -ENXIO; |
345 | goto out; | |
1a4c6940 VO |
346 | } |
347 | /* Wait for an eventual egress packet to finish transmission | |
348 | * (reach IFG). It is guaranteed that a second one will not | |
349 | * follow, and that switch cold reset is thus safe | |
350 | */ | |
351 | usleep_range(500, 1000); | |
8aa9ebcc VO |
352 | do { |
353 | /* Put the SJA1105 in programming mode */ | |
abfb228a | 354 | rc = priv->info->reset_cmd(priv->ds); |
8aa9ebcc VO |
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 */ | |
08839c06 VO |
362 | rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->config, |
363 | config_buf, buf_len); | |
8aa9ebcc VO |
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 | } | |
5425711b CIK |
394 | /* Success! */ |
395 | break; | |
396 | } while (--retries); | |
8aa9ebcc VO |
397 | |
398 | if (!retries) { | |
399 | rc = -EIO; | |
400 | dev_err(dev, "Failed to upload config to device, giving up\n"); | |
401 | goto out; | |
5425711b | 402 | } else if (retries != RETRIES) { |
8aa9ebcc VO |
403 | dev_info(dev, "Succeeded after %d tried\n", RETRIES - retries); |
404 | } | |
405 | ||
8aa9ebcc VO |
406 | out: |
407 | kfree(config_buf); | |
408 | return rc; | |
409 | } | |
410 | ||
3009e8aa | 411 | static const struct sja1105_regs sja1105et_regs = { |
8aa9ebcc VO |
412 | .device_id = 0x0, |
413 | .prod_id = 0x100BC3, | |
414 | .status = 0x1, | |
1a4c6940 | 415 | .port_control = 0x11, |
834f8933 | 416 | .vl_status = 0x10000, |
8aa9ebcc VO |
417 | .config = 0x020000, |
418 | .rgu = 0x100440, | |
b5b0c7f4 | 419 | /* UM10944.pdf, Table 86, ACU Register overview */ |
8aa9ebcc | 420 | .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808}, |
135e3018 | 421 | .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809}, |
8aa9ebcc VO |
422 | .rmii_pll1 = 0x10000A, |
423 | .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F}, | |
039b167d VO |
424 | .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208}, |
425 | .stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440}, | |
426 | .stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640}, | |
8aa9ebcc VO |
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}, | |
47ed985e | 435 | .ptpegr_ts = {0xC0, 0xC2, 0xC4, 0xC6, 0xC8}, |
86db36a3 | 436 | .ptpschtm = 0x12, /* Spans 0x12 to 0x13 */ |
747e5eb3 VO |
437 | .ptppinst = 0x14, |
438 | .ptppindur = 0x16, | |
bb77f36a | 439 | .ptp_control = 0x17, |
2fb079a2 | 440 | .ptpclkval = 0x18, /* Spans 0x18 to 0x19 */ |
bb77f36a | 441 | .ptpclkrate = 0x1A, |
86db36a3 | 442 | .ptpclkcorp = 0x1D, |
5a8f0974 VO |
443 | .mdio_100base_tx = SJA1105_RSV_ADDR, |
444 | .mdio_100base_t1 = SJA1105_RSV_ADDR, | |
8aa9ebcc VO |
445 | }; |
446 | ||
3009e8aa | 447 | static const struct sja1105_regs sja1105pqrs_regs = { |
8aa9ebcc VO |
448 | .device_id = 0x0, |
449 | .prod_id = 0x100BC3, | |
450 | .status = 0x1, | |
1a4c6940 | 451 | .port_control = 0x12, |
834f8933 | 452 | .vl_status = 0x10000, |
8aa9ebcc VO |
453 | .config = 0x020000, |
454 | .rgu = 0x100440, | |
b5b0c7f4 | 455 | /* UM10944.pdf, Table 86, ACU Register overview */ |
8aa9ebcc | 456 | .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808}, |
135e3018 | 457 | .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809}, |
c05ec3d4 | 458 | .pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814}, |
8aa9ebcc VO |
459 | .rmii_pll1 = 0x10000A, |
460 | .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F}, | |
039b167d VO |
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}, | |
8aa9ebcc VO |
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}, | |
47ed985e | 473 | .ptpegr_ts = {0xC0, 0xC4, 0xC8, 0xCC, 0xD0}, |
86db36a3 | 474 | .ptpschtm = 0x13, /* Spans 0x13 to 0x14 */ |
747e5eb3 VO |
475 | .ptppinst = 0x15, |
476 | .ptppindur = 0x17, | |
bb77f36a | 477 | .ptp_control = 0x18, |
2fb079a2 | 478 | .ptpclkval = 0x19, |
bb77f36a | 479 | .ptpclkrate = 0x1B, |
86db36a3 | 480 | .ptpclkcorp = 0x1E, |
747e5eb3 | 481 | .ptpsyncts = 0x1F, |
5a8f0974 VO |
482 | .mdio_100base_tx = SJA1105_RSV_ADDR, |
483 | .mdio_100base_t1 = SJA1105_RSV_ADDR, | |
8aa9ebcc VO |
484 | }; |
485 | ||
3009e8aa | 486 | static const struct sja1105_regs sja1110_regs = { |
3e77e59b VO |
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 to | |
495 | * 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), | |
5a8f0974 VO |
566 | .mdio_100base_tx = 0x1c2400, |
567 | .mdio_100base_t1 = 0x1c1000, | |
27871359 VO |
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}, | |
3e77e59b VO |
571 | }; |
572 | ||
13c832a4 | 573 | const struct sja1105_info sja1105e_info = { |
8aa9ebcc VO |
574 | .device_id = SJA1105E_DEVICE_ID, |
575 | .part_no = SJA1105ET_PART_NO, | |
576 | .static_ops = sja1105e_table_ops, | |
577 | .dyn_ops = sja1105et_dyn_ops, | |
4913b8eb | 578 | .tag_proto = DSA_TAG_PROTO_SJA1105, |
4d942354 | 579 | .can_limit_mcast_flood = false, |
47ed985e VO |
580 | .ptp_ts_bits = 24, |
581 | .ptpegr_ts_bytes = 4, | |
1bf658ee | 582 | .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, |
3e77e59b | 583 | .num_ports = SJA1105_NUM_PORTS, |
4d752508 | 584 | .num_cbs_shapers = SJA1105ET_MAX_CBS_COUNT, |
8aa9ebcc | 585 | .reset_cmd = sja1105et_reset_cmd, |
9dfa6911 VO |
586 | .fdb_add_cmd = sja1105et_fdb_add, |
587 | .fdb_del_cmd = sja1105et_fdb_del, | |
41603d78 | 588 | .ptp_cmd_packing = sja1105et_ptp_cmd_packing, |
30b73242 | 589 | .rxtstamp = sja1105_rxtstamp, |
c5037678 | 590 | .clocking_setup = sja1105_clocking_setup, |
8aa9ebcc | 591 | .regs = &sja1105et_regs, |
41fed17f VO |
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 | }, | |
91a05078 VO |
599 | .supports_mii = {true, true, true, true, true}, |
600 | .supports_rmii = {true, true, true, true, true}, | |
601 | .supports_rgmii = {true, true, true, true, true}, | |
8aa9ebcc VO |
602 | .name = "SJA1105E", |
603 | }; | |
13c832a4 VO |
604 | |
605 | const struct sja1105_info sja1105t_info = { | |
8aa9ebcc VO |
606 | .device_id = SJA1105T_DEVICE_ID, |
607 | .part_no = SJA1105ET_PART_NO, | |
608 | .static_ops = sja1105t_table_ops, | |
609 | .dyn_ops = sja1105et_dyn_ops, | |
4913b8eb | 610 | .tag_proto = DSA_TAG_PROTO_SJA1105, |
4d942354 | 611 | .can_limit_mcast_flood = false, |
47ed985e VO |
612 | .ptp_ts_bits = 24, |
613 | .ptpegr_ts_bytes = 4, | |
1bf658ee | 614 | .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, |
3e77e59b | 615 | .num_ports = SJA1105_NUM_PORTS, |
4d752508 | 616 | .num_cbs_shapers = SJA1105ET_MAX_CBS_COUNT, |
8aa9ebcc | 617 | .reset_cmd = sja1105et_reset_cmd, |
9dfa6911 VO |
618 | .fdb_add_cmd = sja1105et_fdb_add, |
619 | .fdb_del_cmd = sja1105et_fdb_del, | |
41603d78 | 620 | .ptp_cmd_packing = sja1105et_ptp_cmd_packing, |
30b73242 | 621 | .rxtstamp = sja1105_rxtstamp, |
c5037678 | 622 | .clocking_setup = sja1105_clocking_setup, |
8aa9ebcc | 623 | .regs = &sja1105et_regs, |
41fed17f VO |
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 | }, | |
91a05078 VO |
631 | .supports_mii = {true, true, true, true, true}, |
632 | .supports_rmii = {true, true, true, true, true}, | |
633 | .supports_rgmii = {true, true, true, true, true}, | |
8aa9ebcc VO |
634 | .name = "SJA1105T", |
635 | }; | |
13c832a4 VO |
636 | |
637 | const struct sja1105_info sja1105p_info = { | |
8aa9ebcc VO |
638 | .device_id = SJA1105PR_DEVICE_ID, |
639 | .part_no = SJA1105P_PART_NO, | |
640 | .static_ops = sja1105p_table_ops, | |
641 | .dyn_ops = sja1105pqrs_dyn_ops, | |
4913b8eb | 642 | .tag_proto = DSA_TAG_PROTO_SJA1105, |
4d942354 | 643 | .can_limit_mcast_flood = true, |
47ed985e VO |
644 | .ptp_ts_bits = 32, |
645 | .ptpegr_ts_bytes = 8, | |
1bf658ee | 646 | .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, |
3e77e59b | 647 | .num_ports = SJA1105_NUM_PORTS, |
4d752508 | 648 | .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, |
c05ec3d4 | 649 | .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, |
8aa9ebcc | 650 | .reset_cmd = sja1105pqrs_reset_cmd, |
9dfa6911 VO |
651 | .fdb_add_cmd = sja1105pqrs_fdb_add, |
652 | .fdb_del_cmd = sja1105pqrs_fdb_del, | |
41603d78 | 653 | .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, |
30b73242 | 654 | .rxtstamp = sja1105_rxtstamp, |
c5037678 | 655 | .clocking_setup = sja1105_clocking_setup, |
8aa9ebcc | 656 | .regs = &sja1105pqrs_regs, |
41fed17f VO |
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 | }, | |
91a05078 VO |
664 | .supports_mii = {true, true, true, true, true}, |
665 | .supports_rmii = {true, true, true, true, true}, | |
666 | .supports_rgmii = {true, true, true, true, true}, | |
8aa9ebcc VO |
667 | .name = "SJA1105P", |
668 | }; | |
13c832a4 VO |
669 | |
670 | const struct sja1105_info sja1105q_info = { | |
8aa9ebcc VO |
671 | .device_id = SJA1105QS_DEVICE_ID, |
672 | .part_no = SJA1105Q_PART_NO, | |
673 | .static_ops = sja1105q_table_ops, | |
674 | .dyn_ops = sja1105pqrs_dyn_ops, | |
4913b8eb | 675 | .tag_proto = DSA_TAG_PROTO_SJA1105, |
4d942354 | 676 | .can_limit_mcast_flood = true, |
47ed985e VO |
677 | .ptp_ts_bits = 32, |
678 | .ptpegr_ts_bytes = 8, | |
1bf658ee | 679 | .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, |
3e77e59b | 680 | .num_ports = SJA1105_NUM_PORTS, |
4d752508 | 681 | .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, |
c05ec3d4 | 682 | .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, |
8aa9ebcc | 683 | .reset_cmd = sja1105pqrs_reset_cmd, |
9dfa6911 VO |
684 | .fdb_add_cmd = sja1105pqrs_fdb_add, |
685 | .fdb_del_cmd = sja1105pqrs_fdb_del, | |
41603d78 | 686 | .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, |
30b73242 | 687 | .rxtstamp = sja1105_rxtstamp, |
c5037678 | 688 | .clocking_setup = sja1105_clocking_setup, |
8aa9ebcc | 689 | .regs = &sja1105pqrs_regs, |
41fed17f VO |
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 | }, | |
91a05078 VO |
697 | .supports_mii = {true, true, true, true, true}, |
698 | .supports_rmii = {true, true, true, true, true}, | |
699 | .supports_rgmii = {true, true, true, true, true}, | |
8aa9ebcc VO |
700 | .name = "SJA1105Q", |
701 | }; | |
13c832a4 VO |
702 | |
703 | const struct sja1105_info sja1105r_info = { | |
8aa9ebcc VO |
704 | .device_id = SJA1105PR_DEVICE_ID, |
705 | .part_no = SJA1105R_PART_NO, | |
706 | .static_ops = sja1105r_table_ops, | |
707 | .dyn_ops = sja1105pqrs_dyn_ops, | |
4913b8eb | 708 | .tag_proto = DSA_TAG_PROTO_SJA1105, |
4d942354 | 709 | .can_limit_mcast_flood = true, |
47ed985e VO |
710 | .ptp_ts_bits = 32, |
711 | .ptpegr_ts_bytes = 8, | |
1bf658ee | 712 | .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, |
3e77e59b | 713 | .num_ports = SJA1105_NUM_PORTS, |
4d752508 | 714 | .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, |
c05ec3d4 | 715 | .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, |
8aa9ebcc | 716 | .reset_cmd = sja1105pqrs_reset_cmd, |
9dfa6911 VO |
717 | .fdb_add_cmd = sja1105pqrs_fdb_add, |
718 | .fdb_del_cmd = sja1105pqrs_fdb_del, | |
41603d78 | 719 | .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, |
30b73242 | 720 | .rxtstamp = sja1105_rxtstamp, |
c5037678 | 721 | .clocking_setup = sja1105_clocking_setup, |
3ad1d171 VO |
722 | .pcs_mdio_read = sja1105_pcs_mdio_read, |
723 | .pcs_mdio_write = sja1105_pcs_mdio_write, | |
8aa9ebcc | 724 | .regs = &sja1105pqrs_regs, |
41fed17f VO |
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 | }, | |
91a05078 VO |
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}, | |
8aa9ebcc VO |
736 | .name = "SJA1105R", |
737 | }; | |
13c832a4 VO |
738 | |
739 | const struct sja1105_info sja1105s_info = { | |
8aa9ebcc VO |
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, | |
4913b8eb | 745 | .tag_proto = DSA_TAG_PROTO_SJA1105, |
4d942354 | 746 | .can_limit_mcast_flood = true, |
47ed985e VO |
747 | .ptp_ts_bits = 32, |
748 | .ptpegr_ts_bytes = 8, | |
1bf658ee | 749 | .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, |
3e77e59b | 750 | .num_ports = SJA1105_NUM_PORTS, |
4d752508 | 751 | .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, |
c05ec3d4 | 752 | .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, |
8aa9ebcc | 753 | .reset_cmd = sja1105pqrs_reset_cmd, |
9dfa6911 VO |
754 | .fdb_add_cmd = sja1105pqrs_fdb_add, |
755 | .fdb_del_cmd = sja1105pqrs_fdb_del, | |
41603d78 | 756 | .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, |
30b73242 | 757 | .rxtstamp = sja1105_rxtstamp, |
c5037678 | 758 | .clocking_setup = sja1105_clocking_setup, |
3ad1d171 VO |
759 | .pcs_mdio_read = sja1105_pcs_mdio_read, |
760 | .pcs_mdio_write = sja1105_pcs_mdio_write, | |
41fed17f VO |
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 | }, | |
91a05078 VO |
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}, | |
8aa9ebcc VO |
772 | .name = "SJA1105S", |
773 | }; | |
3e77e59b VO |
774 | |
775 | const 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, | |
4913b8eb | 781 | .tag_proto = DSA_TAG_PROTO_SJA1110, |
3e77e59b | 782 | .can_limit_mcast_flood = true, |
6c0de59b | 783 | .multiple_cascade_ports = true, |
3e77e59b VO |
784 | .ptp_ts_bits = 32, |
785 | .ptpegr_ts_bytes = 8, | |
786 | .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, | |
787 | .num_ports = SJA1110_NUM_PORTS, | |
788 | .num_cbs_shapers = SJA1110_MAX_CBS_COUNT, | |
789 | .setup_rgmii_delay = sja1110_setup_rgmii_delay, | |
790 | .reset_cmd = sja1110_reset_cmd, | |
791 | .fdb_add_cmd = sja1105pqrs_fdb_add, | |
792 | .fdb_del_cmd = sja1105pqrs_fdb_del, | |
793 | .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, | |
30b73242 | 794 | .rxtstamp = sja1110_rxtstamp, |
566b18c8 | 795 | .txtstamp = sja1110_txtstamp, |
cb5a82d2 | 796 | .disable_microcontroller = sja1110_disable_microcontroller, |
27871359 VO |
797 | .pcs_mdio_read = sja1110_pcs_mdio_read, |
798 | .pcs_mdio_write = sja1110_pcs_mdio_write, | |
3e77e59b VO |
799 | .port_speed = { |
800 | [SJA1105_SPEED_AUTO] = 0, | |
801 | [SJA1105_SPEED_10MBPS] = 4, | |
802 | [SJA1105_SPEED_100MBPS] = 3, | |
803 | [SJA1105_SPEED_1000MBPS] = 2, | |
804 | [SJA1105_SPEED_2500MBPS] = 1, | |
805 | }, | |
806 | .supports_mii = {true, true, true, true, false, | |
807 | true, true, true, true, true, true}, | |
808 | .supports_rmii = {false, false, true, true, false, | |
809 | false, false, false, false, false, false}, | |
810 | .supports_rgmii = {false, false, true, true, false, | |
811 | false, false, false, false, false, false}, | |
812 | .supports_sgmii = {false, true, true, true, true, | |
813 | false, false, false, false, false, false}, | |
814 | .supports_2500basex = {false, false, false, true, true, | |
815 | false, false, false, false, false, false}, | |
5a8f0974 VO |
816 | .internal_phy = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX, |
817 | SJA1105_NO_PHY, SJA1105_NO_PHY, | |
818 | SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, | |
819 | SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, | |
820 | SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, | |
821 | SJA1105_PHY_BASE_T1}, | |
3e77e59b VO |
822 | .name = "SJA1110A", |
823 | }; | |
824 | ||
825 | const struct sja1105_info sja1110b_info = { | |
826 | .device_id = SJA1110_DEVICE_ID, | |
827 | .part_no = SJA1110B_PART_NO, | |
828 | .static_ops = sja1110_table_ops, | |
829 | .dyn_ops = sja1110_dyn_ops, | |
830 | .regs = &sja1110_regs, | |
4913b8eb | 831 | .tag_proto = DSA_TAG_PROTO_SJA1110, |
3e77e59b | 832 | .can_limit_mcast_flood = true, |
6c0de59b | 833 | .multiple_cascade_ports = true, |
3e77e59b VO |
834 | .ptp_ts_bits = 32, |
835 | .ptpegr_ts_bytes = 8, | |
836 | .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, | |
837 | .num_ports = SJA1110_NUM_PORTS, | |
838 | .num_cbs_shapers = SJA1110_MAX_CBS_COUNT, | |
839 | .setup_rgmii_delay = sja1110_setup_rgmii_delay, | |
840 | .reset_cmd = sja1110_reset_cmd, | |
841 | .fdb_add_cmd = sja1105pqrs_fdb_add, | |
842 | .fdb_del_cmd = sja1105pqrs_fdb_del, | |
843 | .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, | |
30b73242 | 844 | .rxtstamp = sja1110_rxtstamp, |
566b18c8 | 845 | .txtstamp = sja1110_txtstamp, |
cb5a82d2 | 846 | .disable_microcontroller = sja1110_disable_microcontroller, |
27871359 VO |
847 | .pcs_mdio_read = sja1110_pcs_mdio_read, |
848 | .pcs_mdio_write = sja1110_pcs_mdio_write, | |
3e77e59b VO |
849 | .port_speed = { |
850 | [SJA1105_SPEED_AUTO] = 0, | |
851 | [SJA1105_SPEED_10MBPS] = 4, | |
852 | [SJA1105_SPEED_100MBPS] = 3, | |
853 | [SJA1105_SPEED_1000MBPS] = 2, | |
854 | [SJA1105_SPEED_2500MBPS] = 1, | |
855 | }, | |
856 | .supports_mii = {true, true, true, true, false, | |
857 | true, true, true, true, true, false}, | |
858 | .supports_rmii = {false, false, true, true, false, | |
859 | false, false, false, false, false, false}, | |
860 | .supports_rgmii = {false, false, true, true, false, | |
861 | false, false, false, false, false, false}, | |
862 | .supports_sgmii = {false, false, false, true, true, | |
863 | false, false, false, false, false, false}, | |
864 | .supports_2500basex = {false, false, false, true, true, | |
865 | false, false, false, false, false, false}, | |
5a8f0974 VO |
866 | .internal_phy = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX, |
867 | SJA1105_NO_PHY, SJA1105_NO_PHY, | |
868 | SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, | |
869 | SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, | |
870 | SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, | |
871 | SJA1105_NO_PHY}, | |
3e77e59b VO |
872 | .name = "SJA1110B", |
873 | }; | |
874 | ||
875 | const struct sja1105_info sja1110c_info = { | |
876 | .device_id = SJA1110_DEVICE_ID, | |
877 | .part_no = SJA1110C_PART_NO, | |
878 | .static_ops = sja1110_table_ops, | |
879 | .dyn_ops = sja1110_dyn_ops, | |
880 | .regs = &sja1110_regs, | |
4913b8eb | 881 | .tag_proto = DSA_TAG_PROTO_SJA1110, |
3e77e59b | 882 | .can_limit_mcast_flood = true, |
6c0de59b | 883 | .multiple_cascade_ports = true, |
3e77e59b VO |
884 | .ptp_ts_bits = 32, |
885 | .ptpegr_ts_bytes = 8, | |
886 | .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, | |
887 | .num_ports = SJA1110_NUM_PORTS, | |
888 | .num_cbs_shapers = SJA1110_MAX_CBS_COUNT, | |
889 | .setup_rgmii_delay = sja1110_setup_rgmii_delay, | |
890 | .reset_cmd = sja1110_reset_cmd, | |
891 | .fdb_add_cmd = sja1105pqrs_fdb_add, | |
892 | .fdb_del_cmd = sja1105pqrs_fdb_del, | |
893 | .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, | |
30b73242 | 894 | .rxtstamp = sja1110_rxtstamp, |
566b18c8 | 895 | .txtstamp = sja1110_txtstamp, |
cb5a82d2 | 896 | .disable_microcontroller = sja1110_disable_microcontroller, |
27871359 VO |
897 | .pcs_mdio_read = sja1110_pcs_mdio_read, |
898 | .pcs_mdio_write = sja1110_pcs_mdio_write, | |
3e77e59b VO |
899 | .port_speed = { |
900 | [SJA1105_SPEED_AUTO] = 0, | |
901 | [SJA1105_SPEED_10MBPS] = 4, | |
902 | [SJA1105_SPEED_100MBPS] = 3, | |
903 | [SJA1105_SPEED_1000MBPS] = 2, | |
904 | [SJA1105_SPEED_2500MBPS] = 1, | |
905 | }, | |
906 | .supports_mii = {true, true, true, true, false, | |
907 | true, true, true, false, false, false}, | |
908 | .supports_rmii = {false, false, true, true, false, | |
909 | false, false, false, false, false, false}, | |
910 | .supports_rgmii = {false, false, true, true, false, | |
911 | false, false, false, false, false, false}, | |
912 | .supports_sgmii = {false, false, false, false, true, | |
913 | false, false, false, false, false, false}, | |
914 | .supports_2500basex = {false, false, false, false, true, | |
915 | false, false, false, false, false, false}, | |
5a8f0974 VO |
916 | .internal_phy = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX, |
917 | SJA1105_NO_PHY, SJA1105_NO_PHY, | |
918 | SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, | |
919 | SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, | |
920 | SJA1105_NO_PHY, SJA1105_NO_PHY, | |
921 | SJA1105_NO_PHY}, | |
3e77e59b VO |
922 | .name = "SJA1110C", |
923 | }; | |
924 | ||
925 | const struct sja1105_info sja1110d_info = { | |
926 | .device_id = SJA1110_DEVICE_ID, | |
927 | .part_no = SJA1110D_PART_NO, | |
928 | .static_ops = sja1110_table_ops, | |
929 | .dyn_ops = sja1110_dyn_ops, | |
930 | .regs = &sja1110_regs, | |
4913b8eb | 931 | .tag_proto = DSA_TAG_PROTO_SJA1110, |
3e77e59b | 932 | .can_limit_mcast_flood = true, |
6c0de59b | 933 | .multiple_cascade_ports = true, |
3e77e59b VO |
934 | .ptp_ts_bits = 32, |
935 | .ptpegr_ts_bytes = 8, | |
936 | .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, | |
937 | .num_ports = SJA1110_NUM_PORTS, | |
938 | .num_cbs_shapers = SJA1110_MAX_CBS_COUNT, | |
939 | .setup_rgmii_delay = sja1110_setup_rgmii_delay, | |
940 | .reset_cmd = sja1110_reset_cmd, | |
941 | .fdb_add_cmd = sja1105pqrs_fdb_add, | |
942 | .fdb_del_cmd = sja1105pqrs_fdb_del, | |
943 | .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, | |
30b73242 | 944 | .rxtstamp = sja1110_rxtstamp, |
566b18c8 | 945 | .txtstamp = sja1110_txtstamp, |
cb5a82d2 | 946 | .disable_microcontroller = sja1110_disable_microcontroller, |
27871359 VO |
947 | .pcs_mdio_read = sja1110_pcs_mdio_read, |
948 | .pcs_mdio_write = sja1110_pcs_mdio_write, | |
3e77e59b VO |
949 | .port_speed = { |
950 | [SJA1105_SPEED_AUTO] = 0, | |
951 | [SJA1105_SPEED_10MBPS] = 4, | |
952 | [SJA1105_SPEED_100MBPS] = 3, | |
953 | [SJA1105_SPEED_1000MBPS] = 2, | |
954 | [SJA1105_SPEED_2500MBPS] = 1, | |
955 | }, | |
956 | .supports_mii = {true, false, true, false, false, | |
957 | true, true, true, false, false, false}, | |
958 | .supports_rmii = {false, false, true, false, false, | |
959 | false, false, false, false, false, false}, | |
960 | .supports_rgmii = {false, false, true, false, false, | |
961 | false, false, false, false, false, false}, | |
962 | .supports_sgmii = {false, true, true, true, true, | |
963 | false, false, false, false, false, false}, | |
56b63466 VO |
964 | .supports_2500basex = {false, false, false, true, true, |
965 | false, false, false, false, false, false}, | |
5a8f0974 VO |
966 | .internal_phy = {SJA1105_NO_PHY, SJA1105_NO_PHY, |
967 | SJA1105_NO_PHY, SJA1105_NO_PHY, | |
968 | SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, | |
969 | SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, | |
970 | SJA1105_NO_PHY, SJA1105_NO_PHY, | |
971 | SJA1105_NO_PHY}, | |
3e77e59b VO |
972 | .name = "SJA1110D", |
973 | }; |