blob: 0772403116190d05dbff90428378f131be5397a6 [file] [log] [blame]
Vladimir Oltean67bfc852021-09-29 18:04:41 +03001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2016-2018 NXP
4 * Copyright 2018, Sensor-Technik Wiedemann GmbH
5 * Copyright 2018-2019, Vladimir Oltean <olteanv@gmail.com>
6 * Copyright 2020-2021 NXP
7 *
8 * Ported from Linux (drivers/net/dsa/sja1105/).
9 */
10
11#include <common.h>
12#include <dm/device_compat.h>
13#include <linux/bitops.h>
14#include <linux/bitrev.h>
15#include <linux/errno.h>
16#include <linux/delay.h>
17#include <linux/if_ether.h>
18#include <linux/if_vlan.h>
19#include <linux/types.h>
20#include <net/dsa.h>
21#include <stdlib.h>
22#include <spi.h>
23#include <miiphy.h>
24#include <dm/of_extra.h>
25
26enum packing_op {
27 PACK,
28 UNPACK,
29};
30
31#define ETHER_CRC32_POLY 0x04C11DB7
32#define ETH_P_SJA1105 0xdadb
33#define SJA1105_NUM_PORTS 5
34#define SJA1110_NUM_PORTS 11
35#define SJA1105_MAX_NUM_PORTS SJA1110_NUM_PORTS
36#define SJA1105_NUM_TC 8
37#define SJA1105ET_FDB_BIN_SIZE 4
38#define SJA1105_SIZE_CGU_CMD 4
39#define SJA1105_SIZE_RESET_CMD 4
40#define SJA1105_SIZE_SPI_MSG_HEADER 4
41#define SJA1105_SIZE_SPI_MSG_MAXLEN (64 * 4)
42#define SJA1105_SIZE_DEVICE_ID 4
43#define SJA1105_SIZE_TABLE_HEADER 12
44#define SJA1105_SIZE_L2_POLICING_ENTRY 8
45#define SJA1105_SIZE_VLAN_LOOKUP_ENTRY 8
46#define SJA1110_SIZE_VLAN_LOOKUP_ENTRY 12
47#define SJA1105_SIZE_L2_FORWARDING_ENTRY 8
48#define SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY 12
49#define SJA1105_SIZE_XMII_PARAMS_ENTRY 4
50#define SJA1110_SIZE_XMII_PARAMS_ENTRY 8
51#define SJA1105ET_SIZE_MAC_CONFIG_ENTRY 28
52#define SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY 40
53#define SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY 32
54#define SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY 44
55#define SJA1110_SIZE_GENERAL_PARAMS_ENTRY 56
56
57#define SJA1105_MAX_L2_LOOKUP_COUNT 1024
58#define SJA1105_MAX_L2_POLICING_COUNT 45
59#define SJA1110_MAX_L2_POLICING_COUNT 110
60#define SJA1105_MAX_VLAN_LOOKUP_COUNT 4096
61#define SJA1105_MAX_L2_FORWARDING_COUNT 13
62#define SJA1110_MAX_L2_FORWARDING_COUNT 19
63#define SJA1105_MAX_MAC_CONFIG_COUNT 5
64#define SJA1110_MAX_MAC_CONFIG_COUNT 11
65#define SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT 1
66#define SJA1105_MAX_GENERAL_PARAMS_COUNT 1
67#define SJA1105_MAX_XMII_PARAMS_COUNT 1
68
69#define SJA1105_MAX_FRAME_MEMORY 929
70
71#define SJA1105E_DEVICE_ID 0x9C00000Cull
72#define SJA1105T_DEVICE_ID 0x9E00030Eull
73#define SJA1105PR_DEVICE_ID 0xAF00030Eull
74#define SJA1105QS_DEVICE_ID 0xAE00030Eull
75#define SJA1110_DEVICE_ID 0xB700030Full
76
77#define SJA1105ET_PART_NO 0x9A83
78#define SJA1105P_PART_NO 0x9A84
79#define SJA1105Q_PART_NO 0x9A85
80#define SJA1105R_PART_NO 0x9A86
81#define SJA1105S_PART_NO 0x9A87
82#define SJA1110A_PART_NO 0x1110
83#define SJA1110B_PART_NO 0x1111
84#define SJA1110C_PART_NO 0x1112
85#define SJA1110D_PART_NO 0x1113
86
87#define SJA1110_ACU 0x1c4400
88#define SJA1110_RGU 0x1c6000
89#define SJA1110_CGU 0x1c6400
90
91#define SJA1110_SPI_ADDR(x) ((x) / 4)
92#define SJA1110_ACU_ADDR(x) (SJA1110_ACU + SJA1110_SPI_ADDR(x))
93#define SJA1110_CGU_ADDR(x) (SJA1110_CGU + SJA1110_SPI_ADDR(x))
94#define SJA1110_RGU_ADDR(x) (SJA1110_RGU + SJA1110_SPI_ADDR(x))
95
96#define SJA1105_RSV_ADDR 0xffffffffffffffffull
97
98#define DSA_8021Q_DIR_TX BIT(11)
99#define DSA_8021Q_PORT_SHIFT 0
100#define DSA_8021Q_PORT_MASK GENMASK(3, 0)
101#define DSA_8021Q_PORT(x) (((x) << DSA_8021Q_PORT_SHIFT) & \
102 DSA_8021Q_PORT_MASK)
103
104#define SJA1105_RATE_MBPS(speed) (((speed) * 64000) / 1000)
105
106/* UM10944.pdf Page 11, Table 2. Configuration Blocks */
107enum {
108 BLKID_L2_POLICING = 0x06,
109 BLKID_VLAN_LOOKUP = 0x07,
110 BLKID_L2_FORWARDING = 0x08,
111 BLKID_MAC_CONFIG = 0x09,
112 BLKID_L2_FORWARDING_PARAMS = 0x0E,
113 BLKID_GENERAL_PARAMS = 0x11,
114 BLKID_XMII_PARAMS = 0x4E,
115};
116
117enum sja1105_blk_idx {
118 BLK_IDX_L2_POLICING = 0,
119 BLK_IDX_VLAN_LOOKUP,
120 BLK_IDX_L2_FORWARDING,
121 BLK_IDX_MAC_CONFIG,
122 BLK_IDX_L2_FORWARDING_PARAMS,
123 BLK_IDX_GENERAL_PARAMS,
124 BLK_IDX_XMII_PARAMS,
125 BLK_IDX_MAX,
126};
127
128struct sja1105_general_params_entry {
129 u64 mac_fltres1;
130 u64 mac_fltres0;
131 u64 mac_flt1;
132 u64 mac_flt0;
133 u64 casc_port;
134 u64 host_port;
135 u64 mirr_port;
136 u64 tpid;
137 u64 tpid2;
138};
139
140struct sja1105_vlan_lookup_entry {
141 u64 vmemb_port;
142 u64 vlan_bc;
143 u64 tag_port;
144 u64 vlanid;
145 u64 type_entry; /* SJA1110 only */
146};
147
148struct sja1105_l2_forwarding_entry {
149 u64 bc_domain;
150 u64 reach_port;
151 u64 fl_domain;
152};
153
154struct sja1105_l2_forwarding_params_entry {
155 u64 part_spc[SJA1105_NUM_TC];
156};
157
158struct sja1105_l2_policing_entry {
159 u64 sharindx;
160 u64 smax;
161 u64 rate;
162 u64 maxlen;
163 u64 partition;
164};
165
166struct sja1105_mac_config_entry {
167 u64 top[SJA1105_NUM_TC];
168 u64 base[SJA1105_NUM_TC];
169 u64 enabled[SJA1105_NUM_TC];
170 u64 speed;
171 u64 vlanid;
172 u64 egress;
173 u64 ingress;
174};
175
176struct sja1105_xmii_params_entry {
177 u64 phy_mac[SJA1105_MAX_NUM_PORTS];
178 u64 xmii_mode[SJA1105_MAX_NUM_PORTS];
179 u64 special[SJA1105_MAX_NUM_PORTS];
180};
181
182struct sja1105_table_header {
183 u64 block_id;
184 u64 len;
185 u64 crc;
186};
187
188struct sja1105_table_ops {
189 size_t (*packing)(void *buf, void *entry_ptr, enum packing_op op);
190 size_t unpacked_entry_size;
191 size_t packed_entry_size;
192 size_t max_entry_count;
193};
194
195struct sja1105_table {
196 const struct sja1105_table_ops *ops;
197 size_t entry_count;
198 void *entries;
199};
200
201struct sja1105_static_config {
202 u64 device_id;
203 struct sja1105_table tables[BLK_IDX_MAX];
204};
205
206struct sja1105_private {
207 struct sja1105_static_config static_config;
208 bool rgmii_rx_delay[SJA1105_MAX_NUM_PORTS];
209 bool rgmii_tx_delay[SJA1105_MAX_NUM_PORTS];
210 u16 pvid[SJA1105_MAX_NUM_PORTS];
211 const struct sja1105_info *info;
212 struct udevice *dev;
213};
214
215typedef enum {
216 SPI_READ = 0,
217 SPI_WRITE = 1,
218} sja1105_spi_rw_mode_t;
219
220typedef enum {
221 XMII_MAC = 0,
222 XMII_PHY = 1,
223} sja1105_mii_role_t;
224
225typedef enum {
226 XMII_MODE_MII = 0,
227 XMII_MODE_RMII = 1,
228 XMII_MODE_RGMII = 2,
229} sja1105_phy_interface_t;
230
231enum {
232 SJA1105_SPEED_AUTO,
233 SJA1105_SPEED_10MBPS,
234 SJA1105_SPEED_100MBPS,
235 SJA1105_SPEED_1000MBPS,
236 SJA1105_SPEED_MAX,
237};
238
239enum sja1110_vlan_type {
240 SJA1110_VLAN_INVALID = 0,
241 SJA1110_VLAN_C_TAG = 1, /* Single inner VLAN tag */
242 SJA1110_VLAN_S_TAG = 2, /* Single outer VLAN tag */
243 SJA1110_VLAN_D_TAG = 3, /* Double tagged, use outer tag for lookup */
244};
245
246/* Keeps the different addresses between E/T and P/Q/R/S */
247struct sja1105_regs {
248 u64 device_id;
249 u64 prod_id;
250 u64 status;
251 u64 port_control;
252 u64 rgu;
253 u64 config;
254 u64 rmii_pll1;
255 u64 pad_mii_tx[SJA1105_MAX_NUM_PORTS];
256 u64 pad_mii_rx[SJA1105_MAX_NUM_PORTS];
257 u64 pad_mii_id[SJA1105_MAX_NUM_PORTS];
258 u64 cgu_idiv[SJA1105_MAX_NUM_PORTS];
259 u64 mii_tx_clk[SJA1105_MAX_NUM_PORTS];
260 u64 mii_rx_clk[SJA1105_MAX_NUM_PORTS];
261 u64 mii_ext_tx_clk[SJA1105_MAX_NUM_PORTS];
262 u64 mii_ext_rx_clk[SJA1105_MAX_NUM_PORTS];
263 u64 rgmii_tx_clk[SJA1105_MAX_NUM_PORTS];
264 u64 rmii_ref_clk[SJA1105_MAX_NUM_PORTS];
265 u64 rmii_ext_tx_clk[SJA1105_MAX_NUM_PORTS];
266};
267
268struct sja1105_info {
269 u64 device_id;
270 u64 part_no;
271 const struct sja1105_table_ops *static_ops;
272 const struct sja1105_regs *regs;
273 int (*reset_cmd)(struct sja1105_private *priv);
274 int (*setup_rgmii_delay)(struct sja1105_private *priv, int port);
275 const char *name;
276 bool supports_mii[SJA1105_MAX_NUM_PORTS];
277 bool supports_rmii[SJA1105_MAX_NUM_PORTS];
278 bool supports_rgmii[SJA1105_MAX_NUM_PORTS];
279 const u64 port_speed[SJA1105_SPEED_MAX];
280};
281
282struct sja1105_chunk {
283 u8 *buf;
284 size_t len;
285 u64 reg_addr;
286};
287
288struct sja1105_spi_message {
289 u64 access;
290 u64 read_count;
291 u64 address;
292};
293
294/* Common structure for CFG_PAD_MIIx_RX and CFG_PAD_MIIx_TX */
295struct sja1105_cfg_pad_mii {
296 u64 d32_os;
297 u64 d32_ih;
298 u64 d32_ipud;
299 u64 d10_ih;
300 u64 d10_os;
301 u64 d10_ipud;
302 u64 ctrl_os;
303 u64 ctrl_ih;
304 u64 ctrl_ipud;
305 u64 clk_os;
306 u64 clk_ih;
307 u64 clk_ipud;
308};
309
310struct sja1105_cfg_pad_mii_id {
311 u64 rxc_stable_ovr;
312 u64 rxc_delay;
313 u64 rxc_bypass;
314 u64 rxc_pd;
315 u64 txc_stable_ovr;
316 u64 txc_delay;
317 u64 txc_bypass;
318 u64 txc_pd;
319};
320
321struct sja1105_cgu_idiv {
322 u64 clksrc;
323 u64 autoblock;
324 u64 idiv;
325 u64 pd;
326};
327
328struct sja1105_cgu_pll_ctrl {
329 u64 pllclksrc;
330 u64 msel;
331 u64 autoblock;
332 u64 psel;
333 u64 direct;
334 u64 fbsel;
335 u64 bypass;
336 u64 pd;
337};
338
339enum {
340 CLKSRC_MII0_TX_CLK = 0x00,
341 CLKSRC_MII0_RX_CLK = 0x01,
342 CLKSRC_MII1_TX_CLK = 0x02,
343 CLKSRC_MII1_RX_CLK = 0x03,
344 CLKSRC_MII2_TX_CLK = 0x04,
345 CLKSRC_MII2_RX_CLK = 0x05,
346 CLKSRC_MII3_TX_CLK = 0x06,
347 CLKSRC_MII3_RX_CLK = 0x07,
348 CLKSRC_MII4_TX_CLK = 0x08,
349 CLKSRC_MII4_RX_CLK = 0x09,
350 CLKSRC_PLL0 = 0x0B,
351 CLKSRC_PLL1 = 0x0E,
352 CLKSRC_IDIV0 = 0x11,
353 CLKSRC_IDIV1 = 0x12,
354 CLKSRC_IDIV2 = 0x13,
355 CLKSRC_IDIV3 = 0x14,
356 CLKSRC_IDIV4 = 0x15,
357};
358
359struct sja1105_cgu_mii_ctrl {
360 u64 clksrc;
361 u64 autoblock;
362 u64 pd;
363};
364
365static int get_reverse_lsw32_offset(int offset, size_t len)
366{
367 int closest_multiple_of_4;
368 int word_index;
369
370 word_index = offset / 4;
371 closest_multiple_of_4 = word_index * 4;
372 offset -= closest_multiple_of_4;
373 word_index = (len / 4) - word_index - 1;
374 return word_index * 4 + offset;
375}
376
377/* Simplified version of the "packing" function from Linux, adapted
378 * to support only sja1105's quirk: QUIRK_LSW32_IS_FIRST
379 */
380static void sja1105_packing(void *pbuf, u64 *uval, int startbit, int endbit,
381 size_t pbuflen, enum packing_op op)
382{
383 int plogical_first_u8, plogical_last_u8, box;
384
385 if (op == UNPACK)
386 *uval = 0;
387
388 plogical_first_u8 = startbit / 8;
389 plogical_last_u8 = endbit / 8;
390
391 for (box = plogical_first_u8; box >= plogical_last_u8; box--) {
392 int box_start_bit, box_end_bit, box_addr;
393 int proj_start_bit, proj_end_bit;
394 u64 proj_mask;
395 u8 box_mask;
396
397 if (box == plogical_first_u8)
398 box_start_bit = startbit % 8;
399 else
400 box_start_bit = 7;
401 if (box == plogical_last_u8)
402 box_end_bit = endbit % 8;
403 else
404 box_end_bit = 0;
405
406 proj_start_bit = ((box * 8) + box_start_bit) - endbit;
407 proj_end_bit = ((box * 8) + box_end_bit) - endbit;
408 proj_mask = GENMASK_ULL(proj_start_bit, proj_end_bit);
409 box_mask = GENMASK_ULL(box_start_bit, box_end_bit);
410
411 box_addr = pbuflen - box - 1;
412 box_addr = get_reverse_lsw32_offset(box_addr, pbuflen);
413
414 if (op == UNPACK) {
415 u64 pval;
416
417 /* Read from pbuf, write to uval */
418 pval = ((u8 *)pbuf)[box_addr] & box_mask;
419
420 pval >>= box_end_bit;
421 pval <<= proj_end_bit;
422 *uval &= ~proj_mask;
423 *uval |= pval;
424 } else {
425 u64 pval;
426
427 /* Write to pbuf, read from uval */
428 pval = (*uval) & proj_mask;
429 pval >>= proj_end_bit;
430
431 pval <<= box_end_bit;
432 ((u8 *)pbuf)[box_addr] &= ~box_mask;
433 ((u8 *)pbuf)[box_addr] |= pval;
434 }
435 }
436}
437
438static u32 crc32_add(u32 crc, u8 byte)
439{
440 u32 byte32 = bitrev32(byte);
441 int i;
442
443 for (i = 0; i < 8; i++) {
444 if ((crc ^ byte32) & BIT(31)) {
445 crc <<= 1;
446 crc ^= ETHER_CRC32_POLY;
447 } else {
448 crc <<= 1;
449 }
450 byte32 <<= 1;
451 }
452 return crc;
453}
454
455/* Little-endian Ethernet CRC32 of data packed as big-endian u32 words */
456static uint32_t sja1105_crc32(void *buf, size_t len)
457{
458 unsigned int i;
459 u64 chunk;
460 u32 crc;
461
462 /* seed */
463 crc = 0xFFFFFFFF;
464 for (i = 0; i < len; i += 4) {
465 sja1105_packing(buf + i, &chunk, 31, 0, 4, UNPACK);
466 crc = crc32_add(crc, chunk & 0xFF);
467 crc = crc32_add(crc, (chunk >> 8) & 0xFF);
468 crc = crc32_add(crc, (chunk >> 16) & 0xFF);
469 crc = crc32_add(crc, (chunk >> 24) & 0xFF);
470 }
471 return bitrev32(~crc);
472}
473
474static void sja1105_spi_message_pack(void *buf, struct sja1105_spi_message *msg)
475{
476 const int size = SJA1105_SIZE_SPI_MSG_HEADER;
477
478 memset(buf, 0, size);
479
480 sja1105_packing(buf, &msg->access, 31, 31, size, PACK);
481 sja1105_packing(buf, &msg->read_count, 30, 25, size, PACK);
482 sja1105_packing(buf, &msg->address, 24, 4, size, PACK);
483}
484
485static int sja1105_xfer_buf(const struct sja1105_private *priv,
486 sja1105_spi_rw_mode_t rw, u64 reg_addr,
487 u8 *buf, size_t len)
488{
489 struct udevice *dev = priv->dev;
490 struct sja1105_chunk chunk = {
491 .len = min_t(size_t, len, SJA1105_SIZE_SPI_MSG_MAXLEN),
492 .reg_addr = reg_addr,
493 .buf = buf,
494 };
495 int num_chunks;
496 int rc, i;
497
498 rc = dm_spi_claim_bus(dev);
499 if (rc)
500 return rc;
501
502 num_chunks = DIV_ROUND_UP(len, SJA1105_SIZE_SPI_MSG_MAXLEN);
503
504 for (i = 0; i < num_chunks; i++) {
505 u8 hdr_buf[SJA1105_SIZE_SPI_MSG_HEADER];
506 struct sja1105_spi_message msg;
507 u8 *rx_buf = NULL;
508 u8 *tx_buf = NULL;
509
510 /* Populate the transfer's header buffer */
511 msg.address = chunk.reg_addr;
512 msg.access = rw;
513 if (rw == SPI_READ)
514 msg.read_count = chunk.len / 4;
515 else
516 /* Ignored */
517 msg.read_count = 0;
518 sja1105_spi_message_pack(hdr_buf, &msg);
519 rc = dm_spi_xfer(dev, SJA1105_SIZE_SPI_MSG_HEADER * 8, hdr_buf,
520 NULL, SPI_XFER_BEGIN);
521 if (rc)
522 goto out;
523
524 /* Populate the transfer's data buffer */
525 if (rw == SPI_READ)
526 rx_buf = chunk.buf;
527 else
528 tx_buf = chunk.buf;
529 rc = dm_spi_xfer(dev, chunk.len * 8, tx_buf, rx_buf,
530 SPI_XFER_END);
531 if (rc)
532 goto out;
533
534 /* Calculate next chunk */
535 chunk.buf += chunk.len;
536 chunk.reg_addr += chunk.len / 4;
537 chunk.len = min_t(size_t, (ptrdiff_t)(buf + len - chunk.buf),
538 SJA1105_SIZE_SPI_MSG_MAXLEN);
539 }
540
541out:
542 dm_spi_release_bus(dev);
543
544 return rc;
545}
546
547static int sja1105et_reset_cmd(struct sja1105_private *priv)
548{
549 const struct sja1105_regs *regs = priv->info->regs;
550 u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0};
551 const int size = SJA1105_SIZE_RESET_CMD;
552 u64 cold_rst = 1;
553
554 sja1105_packing(packed_buf, &cold_rst, 3, 3, size, PACK);
555
556 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf,
557 SJA1105_SIZE_RESET_CMD);
558}
559
560static int sja1105pqrs_reset_cmd(struct sja1105_private *priv)
561{
562 const struct sja1105_regs *regs = priv->info->regs;
563 u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0};
564 const int size = SJA1105_SIZE_RESET_CMD;
565 u64 cold_rst = 1;
566
567 sja1105_packing(packed_buf, &cold_rst, 2, 2, size, PACK);
568
569 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf,
570 SJA1105_SIZE_RESET_CMD);
571}
572
573static int sja1110_reset_cmd(struct sja1105_private *priv)
574{
575 const struct sja1105_regs *regs = priv->info->regs;
576 u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0};
577 const int size = SJA1105_SIZE_RESET_CMD;
578 u64 switch_rst = 1;
579
580 /* Only reset the switch core.
581 * A full cold reset would re-enable the BASE_MCSS_CLOCK PLL which
582 * would turn on the microcontroller, potentially letting it execute
583 * code which could interfere with our configuration.
584 */
585 sja1105_packing(packed_buf, &switch_rst, 20, 20, size, PACK);
586
587 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf,
588 SJA1105_SIZE_RESET_CMD);
589}
590
591static size_t sja1105et_general_params_entry_packing(void *buf, void *entry_ptr,
592 enum packing_op op)
593{
594 const size_t size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY;
595 struct sja1105_general_params_entry *entry = entry_ptr;
596
597 sja1105_packing(buf, &entry->mac_fltres1, 311, 264, size, op);
598 sja1105_packing(buf, &entry->mac_fltres0, 263, 216, size, op);
599 sja1105_packing(buf, &entry->mac_flt1, 215, 168, size, op);
600 sja1105_packing(buf, &entry->mac_flt0, 167, 120, size, op);
601 sja1105_packing(buf, &entry->casc_port, 115, 113, size, op);
602 sja1105_packing(buf, &entry->host_port, 112, 110, size, op);
603 sja1105_packing(buf, &entry->mirr_port, 109, 107, size, op);
604 sja1105_packing(buf, &entry->tpid, 42, 27, size, op);
605 sja1105_packing(buf, &entry->tpid2, 25, 10, size, op);
606 return size;
607}
608
609static size_t sja1110_general_params_entry_packing(void *buf, void *entry_ptr,
610 enum packing_op op)
611{
612 struct sja1105_general_params_entry *entry = entry_ptr;
613 const size_t size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY;
614
615 sja1105_packing(buf, &entry->mac_fltres1, 438, 391, size, op);
616 sja1105_packing(buf, &entry->mac_fltres0, 390, 343, size, op);
617 sja1105_packing(buf, &entry->mac_flt1, 342, 295, size, op);
618 sja1105_packing(buf, &entry->mac_flt0, 294, 247, size, op);
619 sja1105_packing(buf, &entry->casc_port, 242, 232, size, op);
620 sja1105_packing(buf, &entry->host_port, 231, 228, size, op);
621 sja1105_packing(buf, &entry->mirr_port, 227, 224, size, op);
622 sja1105_packing(buf, &entry->tpid2, 159, 144, size, op);
623 sja1105_packing(buf, &entry->tpid, 142, 127, size, op);
624 return size;
625}
626
627static size_t
628sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr,
629 enum packing_op op)
630{
631 const size_t size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY;
632 struct sja1105_general_params_entry *entry = entry_ptr;
633
634 sja1105_packing(buf, &entry->mac_fltres1, 343, 296, size, op);
635 sja1105_packing(buf, &entry->mac_fltres0, 295, 248, size, op);
636 sja1105_packing(buf, &entry->mac_flt1, 247, 200, size, op);
637 sja1105_packing(buf, &entry->mac_flt0, 199, 152, size, op);
638 sja1105_packing(buf, &entry->casc_port, 147, 145, size, op);
639 sja1105_packing(buf, &entry->host_port, 144, 142, size, op);
640 sja1105_packing(buf, &entry->mirr_port, 141, 139, size, op);
641 sja1105_packing(buf, &entry->tpid, 74, 59, size, op);
642 sja1105_packing(buf, &entry->tpid2, 57, 42, size, op);
643 return size;
644}
645
646static size_t
647sja1105_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr,
648 enum packing_op op)
649{
650 const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY;
651 struct sja1105_l2_forwarding_params_entry *entry = entry_ptr;
652 int offset, i;
653
654 for (i = 0, offset = 13; i < SJA1105_NUM_TC; i++, offset += 10)
655 sja1105_packing(buf, &entry->part_spc[i],
656 offset + 9, offset + 0, size, op);
657 return size;
658}
659
660static size_t
661sja1110_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr,
662 enum packing_op op)
663{
664 struct sja1105_l2_forwarding_params_entry *entry = entry_ptr;
665 const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY;
666 int offset, i;
667
668 for (i = 0, offset = 5; i < 8; i++, offset += 11)
669 sja1105_packing(buf, &entry->part_spc[i],
670 offset + 10, offset + 0, size, op);
671 return size;
672}
673
674static size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr,
675 enum packing_op op)
676{
677 const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY;
678 struct sja1105_l2_forwarding_entry *entry = entry_ptr;
679
680 sja1105_packing(buf, &entry->bc_domain, 63, 59, size, op);
681 sja1105_packing(buf, &entry->reach_port, 58, 54, size, op);
682 sja1105_packing(buf, &entry->fl_domain, 53, 49, size, op);
683 return size;
684}
685
686static size_t sja1110_l2_forwarding_entry_packing(void *buf, void *entry_ptr,
687 enum packing_op op)
688{
689 struct sja1105_l2_forwarding_entry *entry = entry_ptr;
690 const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY;
691
692 sja1105_packing(buf, &entry->bc_domain, 63, 53, size, op);
693 sja1105_packing(buf, &entry->reach_port, 52, 42, size, op);
694 sja1105_packing(buf, &entry->fl_domain, 41, 31, size, op);
695 return size;
696}
697
698static size_t sja1105_l2_policing_entry_packing(void *buf, void *entry_ptr,
699 enum packing_op op)
700{
701 struct sja1105_l2_policing_entry *entry = entry_ptr;
702 const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY;
703
704 sja1105_packing(buf, &entry->sharindx, 63, 58, size, op);
705 sja1105_packing(buf, &entry->smax, 57, 42, size, op);
706 sja1105_packing(buf, &entry->rate, 41, 26, size, op);
707 sja1105_packing(buf, &entry->maxlen, 25, 15, size, op);
708 sja1105_packing(buf, &entry->partition, 14, 12, size, op);
709 return size;
710}
711
712static size_t sja1110_l2_policing_entry_packing(void *buf, void *entry_ptr,
713 enum packing_op op)
714{
715 struct sja1105_l2_policing_entry *entry = entry_ptr;
716 const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY;
717
718 sja1105_packing(buf, &entry->sharindx, 63, 57, size, op);
719 sja1105_packing(buf, &entry->smax, 56, 39, size, op);
720 sja1105_packing(buf, &entry->rate, 38, 21, size, op);
721 sja1105_packing(buf, &entry->maxlen, 20, 10, size, op);
722 sja1105_packing(buf, &entry->partition, 9, 7, size, op);
723 return size;
724}
725
726static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr,
727 enum packing_op op)
728{
729 const size_t size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY;
730 struct sja1105_mac_config_entry *entry = entry_ptr;
731 int offset, i;
732
733 for (i = 0, offset = 72; i < SJA1105_NUM_TC; i++, offset += 19) {
734 sja1105_packing(buf, &entry->enabled[i],
735 offset + 0, offset + 0, size, op);
736 sja1105_packing(buf, &entry->base[i],
737 offset + 9, offset + 1, size, op);
738 sja1105_packing(buf, &entry->top[i],
739 offset + 18, offset + 10, size, op);
740 }
741 sja1105_packing(buf, &entry->speed, 66, 65, size, op);
742 sja1105_packing(buf, &entry->vlanid, 21, 10, size, op);
743 sja1105_packing(buf, &entry->egress, 2, 2, size, op);
744 sja1105_packing(buf, &entry->ingress, 1, 1, size, op);
745 return size;
746}
747
748static size_t sja1105pqrs_mac_config_entry_packing(void *buf, void *entry_ptr,
749 enum packing_op op)
750{
751 const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
752 struct sja1105_mac_config_entry *entry = entry_ptr;
753 int offset, i;
754
755 for (i = 0, offset = 104; i < SJA1105_NUM_TC; i++, offset += 19) {
756 sja1105_packing(buf, &entry->enabled[i],
757 offset + 0, offset + 0, size, op);
758 sja1105_packing(buf, &entry->base[i],
759 offset + 9, offset + 1, size, op);
760 sja1105_packing(buf, &entry->top[i],
761 offset + 18, offset + 10, size, op);
762 }
763 sja1105_packing(buf, &entry->speed, 98, 97, size, op);
764 sja1105_packing(buf, &entry->vlanid, 53, 42, size, op);
765 sja1105_packing(buf, &entry->egress, 32, 32, size, op);
766 sja1105_packing(buf, &entry->ingress, 31, 31, size, op);
767 return size;
768}
769
770static size_t sja1110_mac_config_entry_packing(void *buf, void *entry_ptr,
771 enum packing_op op)
772{
773 const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
774 struct sja1105_mac_config_entry *entry = entry_ptr;
775 int offset, i;
776
777 for (i = 0, offset = 104; i < 8; i++, offset += 19) {
778 sja1105_packing(buf, &entry->enabled[i],
779 offset + 0, offset + 0, size, op);
780 sja1105_packing(buf, &entry->base[i],
781 offset + 9, offset + 1, size, op);
782 sja1105_packing(buf, &entry->top[i],
783 offset + 18, offset + 10, size, op);
784 }
785 sja1105_packing(buf, &entry->speed, 98, 96, size, op);
786 sja1105_packing(buf, &entry->vlanid, 52, 41, size, op);
787 sja1105_packing(buf, &entry->egress, 31, 31, size, op);
788 sja1105_packing(buf, &entry->ingress, 30, 30, size, op);
789 return size;
790}
791
792static size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr,
793 enum packing_op op)
794{
795 const size_t size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY;
796 struct sja1105_vlan_lookup_entry *entry = entry_ptr;
797
798 sja1105_packing(buf, &entry->vmemb_port, 53, 49, size, op);
799 sja1105_packing(buf, &entry->vlan_bc, 48, 44, size, op);
800 sja1105_packing(buf, &entry->tag_port, 43, 39, size, op);
801 sja1105_packing(buf, &entry->vlanid, 38, 27, size, op);
802 return size;
803}
804
805static size_t sja1110_vlan_lookup_entry_packing(void *buf, void *entry_ptr,
806 enum packing_op op)
807{
808 struct sja1105_vlan_lookup_entry *entry = entry_ptr;
809 const size_t size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY;
810
811 sja1105_packing(buf, &entry->vmemb_port, 73, 63, size, op);
812 sja1105_packing(buf, &entry->vlan_bc, 62, 52, size, op);
813 sja1105_packing(buf, &entry->tag_port, 51, 41, size, op);
814 sja1105_packing(buf, &entry->type_entry, 40, 39, size, op);
815 sja1105_packing(buf, &entry->vlanid, 38, 27, size, op);
816 return size;
817}
818
819static size_t sja1105_xmii_params_entry_packing(void *buf, void *entry_ptr,
820 enum packing_op op)
821{
822 const size_t size = SJA1105_SIZE_XMII_PARAMS_ENTRY;
823 struct sja1105_xmii_params_entry *entry = entry_ptr;
824 int offset, i;
825
826 for (i = 0, offset = 17; i < SJA1105_NUM_PORTS; i++, offset += 3) {
827 sja1105_packing(buf, &entry->xmii_mode[i],
828 offset + 1, offset + 0, size, op);
829 sja1105_packing(buf, &entry->phy_mac[i],
830 offset + 2, offset + 2, size, op);
831 }
832 return size;
833}
834
835static size_t sja1110_xmii_params_entry_packing(void *buf, void *entry_ptr,
836 enum packing_op op)
837{
838 const size_t size = SJA1110_SIZE_XMII_PARAMS_ENTRY;
839 struct sja1105_xmii_params_entry *entry = entry_ptr;
840 int offset, i;
841
842 for (i = 0, offset = 20; i < SJA1110_NUM_PORTS; i++, offset += 4) {
843 sja1105_packing(buf, &entry->xmii_mode[i],
844 offset + 1, offset + 0, size, op);
845 sja1105_packing(buf, &entry->phy_mac[i],
846 offset + 2, offset + 2, size, op);
847 sja1105_packing(buf, &entry->special[i],
848 offset + 3, offset + 3, size, op);
849 }
850 return size;
851}
852
853static size_t sja1105_table_header_packing(void *buf, void *entry_ptr,
854 enum packing_op op)
855{
856 const size_t size = SJA1105_SIZE_TABLE_HEADER;
857 struct sja1105_table_header *entry = entry_ptr;
858
859 sja1105_packing(buf, &entry->block_id, 31, 24, size, op);
860 sja1105_packing(buf, &entry->len, 55, 32, size, op);
861 sja1105_packing(buf, &entry->crc, 95, 64, size, op);
862 return size;
863}
864
865static void
866sja1105_table_header_pack_with_crc(void *buf, struct sja1105_table_header *hdr)
867{
868 /* First pack the table as-is, then calculate the CRC, and
869 * finally put the proper CRC into the packed buffer
870 */
871 memset(buf, 0, SJA1105_SIZE_TABLE_HEADER);
872 sja1105_table_header_packing(buf, hdr, PACK);
873 hdr->crc = sja1105_crc32(buf, SJA1105_SIZE_TABLE_HEADER - 4);
874 sja1105_packing(buf + SJA1105_SIZE_TABLE_HEADER - 4, &hdr->crc,
875 31, 0, 4, PACK);
876}
877
878static void sja1105_table_write_crc(u8 *table_start, u8 *crc_ptr)
879{
880 u64 computed_crc;
881 int len_bytes;
882
883 len_bytes = (uintptr_t)(crc_ptr - table_start);
884 computed_crc = sja1105_crc32(table_start, len_bytes);
885 sja1105_packing(crc_ptr, &computed_crc, 31, 0, 4, PACK);
886}
887
888/* The block IDs that the switches support are unfortunately sparse, so keep a
889 * mapping table to "block indices" and translate back and forth.
890 */
891static const u64 blk_id_map[BLK_IDX_MAX] = {
892 [BLK_IDX_L2_POLICING] = BLKID_L2_POLICING,
893 [BLK_IDX_VLAN_LOOKUP] = BLKID_VLAN_LOOKUP,
894 [BLK_IDX_L2_FORWARDING] = BLKID_L2_FORWARDING,
895 [BLK_IDX_MAC_CONFIG] = BLKID_MAC_CONFIG,
896 [BLK_IDX_L2_FORWARDING_PARAMS] = BLKID_L2_FORWARDING_PARAMS,
897 [BLK_IDX_GENERAL_PARAMS] = BLKID_GENERAL_PARAMS,
898 [BLK_IDX_XMII_PARAMS] = BLKID_XMII_PARAMS,
899};
900
901static void
902sja1105_static_config_pack(void *buf, struct sja1105_static_config *config)
903{
904 struct sja1105_table_header header = {0};
905 enum sja1105_blk_idx i;
906 u8 *p = buf;
907 int j;
908
909 sja1105_packing(p, &config->device_id, 31, 0, 4, PACK);
910 p += SJA1105_SIZE_DEVICE_ID;
911
912 for (i = 0; i < BLK_IDX_MAX; i++) {
913 const struct sja1105_table *table;
914 u8 *table_start;
915
916 table = &config->tables[i];
917 if (!table->entry_count)
918 continue;
919
920 header.block_id = blk_id_map[i];
921 header.len = table->entry_count *
922 table->ops->packed_entry_size / 4;
923 sja1105_table_header_pack_with_crc(p, &header);
924 p += SJA1105_SIZE_TABLE_HEADER;
925 table_start = p;
926 for (j = 0; j < table->entry_count; j++) {
927 u8 *entry_ptr = table->entries;
928
929 entry_ptr += j * table->ops->unpacked_entry_size;
930 memset(p, 0, table->ops->packed_entry_size);
931 table->ops->packing(p, entry_ptr, PACK);
932 p += table->ops->packed_entry_size;
933 }
934 sja1105_table_write_crc(table_start, p);
935 p += 4;
936 }
937 /* Final header:
938 * Block ID does not matter
939 * Length of 0 marks that header is final
940 * CRC will be replaced on-the-fly
941 */
942 header.block_id = 0;
943 header.len = 0;
944 header.crc = 0xDEADBEEF;
945 memset(p, 0, SJA1105_SIZE_TABLE_HEADER);
946 sja1105_table_header_packing(p, &header, PACK);
947}
948
949static size_t
950sja1105_static_config_get_length(const struct sja1105_static_config *config)
951{
952 unsigned int header_count;
953 enum sja1105_blk_idx i;
954 unsigned int sum;
955
956 /* Ending header */
957 header_count = 1;
958 sum = SJA1105_SIZE_DEVICE_ID;
959
960 /* Tables (headers and entries) */
961 for (i = 0; i < BLK_IDX_MAX; i++) {
962 const struct sja1105_table *table;
963
964 table = &config->tables[i];
965 if (table->entry_count)
966 header_count++;
967
968 sum += table->ops->packed_entry_size * table->entry_count;
969 }
970 /* Headers have an additional CRC at the end */
971 sum += header_count * (SJA1105_SIZE_TABLE_HEADER + 4);
972 /* Last header does not have an extra CRC because there is no data */
973 sum -= 4;
974
975 return sum;
976}
977
978/* Compatibility matrices */
979static const struct sja1105_table_ops sja1105et_table_ops[BLK_IDX_MAX] = {
980 [BLK_IDX_L2_POLICING] = {
981 .packing = sja1105_l2_policing_entry_packing,
982 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
983 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
984 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
985 },
986 [BLK_IDX_VLAN_LOOKUP] = {
987 .packing = sja1105_vlan_lookup_entry_packing,
988 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
989 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
990 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
991 },
992 [BLK_IDX_L2_FORWARDING] = {
993 .packing = sja1105_l2_forwarding_entry_packing,
994 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
995 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
996 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
997 },
998 [BLK_IDX_MAC_CONFIG] = {
999 .packing = sja1105et_mac_config_entry_packing,
1000 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1001 .packed_entry_size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY,
1002 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1003 },
1004 [BLK_IDX_L2_FORWARDING_PARAMS] = {
1005 .packing = sja1105_l2_forwarding_params_entry_packing,
1006 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1007 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1008 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1009 },
1010 [BLK_IDX_GENERAL_PARAMS] = {
1011 .packing = sja1105et_general_params_entry_packing,
1012 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1013 .packed_entry_size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY,
1014 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1015 },
1016 [BLK_IDX_XMII_PARAMS] = {
1017 .packing = sja1105_xmii_params_entry_packing,
1018 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1019 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1020 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1021 },
1022};
1023
1024static const struct sja1105_table_ops sja1105pqrs_table_ops[BLK_IDX_MAX] = {
1025 [BLK_IDX_L2_POLICING] = {
1026 .packing = sja1105_l2_policing_entry_packing,
1027 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1028 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1029 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
1030 },
1031 [BLK_IDX_VLAN_LOOKUP] = {
1032 .packing = sja1105_vlan_lookup_entry_packing,
1033 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1034 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
1035 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1036 },
1037 [BLK_IDX_L2_FORWARDING] = {
1038 .packing = sja1105_l2_forwarding_entry_packing,
1039 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1040 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1041 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1042 },
1043 [BLK_IDX_MAC_CONFIG] = {
1044 .packing = sja1105pqrs_mac_config_entry_packing,
1045 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1046 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
1047 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1048 },
1049 [BLK_IDX_L2_FORWARDING_PARAMS] = {
1050 .packing = sja1105_l2_forwarding_params_entry_packing,
1051 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1052 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1053 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1054 },
1055 [BLK_IDX_GENERAL_PARAMS] = {
1056 .packing = sja1105pqrs_general_params_entry_packing,
1057 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1058 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY,
1059 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1060 },
1061 [BLK_IDX_XMII_PARAMS] = {
1062 .packing = sja1105_xmii_params_entry_packing,
1063 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1064 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1065 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1066 },
1067};
1068
1069static const struct sja1105_table_ops sja1110_table_ops[BLK_IDX_MAX] = {
1070 [BLK_IDX_L2_POLICING] = {
1071 .packing = sja1110_l2_policing_entry_packing,
1072 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1073 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1074 .max_entry_count = SJA1110_MAX_L2_POLICING_COUNT,
1075 },
1076 [BLK_IDX_VLAN_LOOKUP] = {
1077 .packing = sja1110_vlan_lookup_entry_packing,
1078 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1079 .packed_entry_size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY,
1080 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1081 },
1082 [BLK_IDX_L2_FORWARDING] = {
1083 .packing = sja1110_l2_forwarding_entry_packing,
1084 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1085 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1086 .max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT,
1087 },
1088 [BLK_IDX_MAC_CONFIG] = {
1089 .packing = sja1110_mac_config_entry_packing,
1090 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1091 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
1092 .max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT,
1093 },
1094 [BLK_IDX_L2_FORWARDING_PARAMS] = {
1095 .packing = sja1110_l2_forwarding_params_entry_packing,
1096 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1097 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1098 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1099 },
1100 [BLK_IDX_GENERAL_PARAMS] = {
1101 .packing = sja1110_general_params_entry_packing,
1102 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1103 .packed_entry_size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY,
1104 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1105 },
1106 [BLK_IDX_XMII_PARAMS] = {
1107 .packing = sja1110_xmii_params_entry_packing,
1108 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1109 .packed_entry_size = SJA1110_SIZE_XMII_PARAMS_ENTRY,
1110 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1111 },
1112};
1113
1114static int sja1105_init_mii_settings(struct sja1105_private *priv)
1115{
1116 struct sja1105_table *table;
1117
1118 table = &priv->static_config.tables[BLK_IDX_XMII_PARAMS];
1119
1120 table->entries = calloc(SJA1105_MAX_XMII_PARAMS_COUNT,
1121 table->ops->unpacked_entry_size);
1122 if (!table->entries)
1123 return -ENOMEM;
1124
1125 /* Table will be populated at runtime */
1126 table->entry_count = SJA1105_MAX_XMII_PARAMS_COUNT;
1127
1128 return 0;
1129}
1130
1131static void sja1105_setup_tagging(struct sja1105_private *priv, int port)
1132{
1133 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1134 struct sja1105_vlan_lookup_entry *vlan;
1135 int cpu = pdata->cpu_port;
1136
1137 /* The CPU port is implicitly configured by
1138 * configuring the front-panel ports
1139 */
1140 if (port == cpu)
1141 return;
1142
1143 vlan = priv->static_config.tables[BLK_IDX_VLAN_LOOKUP].entries;
1144
1145 priv->pvid[port] = DSA_8021Q_DIR_TX | DSA_8021Q_PORT(port);
1146
1147 vlan[port].vmemb_port = BIT(port) | BIT(cpu);
1148 vlan[port].vlan_bc = BIT(port) | BIT(cpu);
1149 vlan[port].tag_port = BIT(cpu);
1150 vlan[port].vlanid = priv->pvid[port];
1151 vlan[port].type_entry = SJA1110_VLAN_D_TAG;
1152}
1153
1154static int sja1105_init_vlan(struct sja1105_private *priv)
1155{
1156 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1157 struct sja1105_table *table;
1158 int port;
1159
1160 table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP];
1161
1162 table->entries = calloc(pdata->num_ports,
1163 table->ops->unpacked_entry_size);
1164 if (!table->entries)
1165 return -ENOMEM;
1166
1167 table->entry_count = pdata->num_ports;
1168
1169 for (port = 0; port < pdata->num_ports; port++)
1170 sja1105_setup_tagging(priv, port);
1171
1172 return 0;
1173}
1174
1175static void
1176sja1105_port_allow_traffic(struct sja1105_l2_forwarding_entry *l2_fwd,
1177 int from, int to)
1178{
1179 l2_fwd[from].bc_domain |= BIT(to);
1180 l2_fwd[from].reach_port |= BIT(to);
1181 l2_fwd[from].fl_domain |= BIT(to);
1182}
1183
1184static int sja1105_init_l2_forwarding(struct sja1105_private *priv)
1185{
1186 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1187 struct sja1105_l2_forwarding_entry *l2fwd;
1188 struct sja1105_table *table;
1189 int cpu = pdata->cpu_port;
1190 int i;
1191
1192 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING];
1193
1194 table->entries = calloc(SJA1105_MAX_L2_FORWARDING_COUNT,
1195 table->ops->unpacked_entry_size);
1196 if (!table->entries)
1197 return -ENOMEM;
1198
1199 table->entry_count = SJA1105_MAX_L2_FORWARDING_COUNT;
1200
1201 l2fwd = table->entries;
1202
1203 /* First 5 entries define the forwarding rules */
1204 for (i = 0; i < pdata->num_ports; i++) {
1205 if (i == cpu)
1206 continue;
1207
1208 sja1105_port_allow_traffic(l2fwd, i, cpu);
1209 sja1105_port_allow_traffic(l2fwd, cpu, i);
1210 }
1211 /* Next 8 entries define VLAN PCP mapping from ingress to egress.
1212 * Leave them unpopulated (implicitly 0) but present.
1213 */
1214 return 0;
1215}
1216
1217static int sja1105_init_l2_forwarding_params(struct sja1105_private *priv)
1218{
1219 struct sja1105_l2_forwarding_params_entry default_l2fwd_params = {
1220 /* Use a single memory partition for all ingress queues */
1221 .part_spc = { SJA1105_MAX_FRAME_MEMORY, 0, 0, 0, 0, 0, 0, 0 },
1222 };
1223 struct sja1105_table *table;
1224
1225 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING_PARAMS];
1226
1227 table->entries = calloc(SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1228 table->ops->unpacked_entry_size);
1229 if (!table->entries)
1230 return -ENOMEM;
1231
1232 table->entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT;
1233
1234 /* This table only has a single entry */
1235 ((struct sja1105_l2_forwarding_params_entry *)table->entries)[0] =
1236 default_l2fwd_params;
1237
1238 return 0;
1239}
1240
1241static int sja1105_init_general_params(struct sja1105_private *priv)
1242{
1243 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1244 struct sja1105_general_params_entry default_general_params = {
1245 /* No frame trapping */
1246 .mac_fltres1 = 0x0,
1247 .mac_flt1 = 0xffffffffffff,
1248 .mac_fltres0 = 0x0,
1249 .mac_flt0 = 0xffffffffffff,
1250 .host_port = pdata->num_ports,
1251 /* No mirroring => specify an out-of-range port value */
1252 .mirr_port = pdata->num_ports,
1253 /* No link-local trapping => specify an out-of-range port value
1254 */
1255 .casc_port = pdata->num_ports,
1256 /* Force the switch to see all traffic as untagged. */
1257 .tpid = ETH_P_SJA1105,
1258 .tpid2 = ETH_P_SJA1105,
1259 };
1260 struct sja1105_table *table;
1261
1262 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS];
1263
1264 table->entries = calloc(SJA1105_MAX_GENERAL_PARAMS_COUNT,
1265 table->ops->unpacked_entry_size);
1266 if (!table->entries)
1267 return -ENOMEM;
1268
1269 table->entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT;
1270
1271 /* This table only has a single entry */
1272 ((struct sja1105_general_params_entry *)table->entries)[0] =
1273 default_general_params;
1274
1275 return 0;
1276}
1277
1278static void sja1105_setup_policer(struct sja1105_l2_policing_entry *policing,
1279 int index, int mtu)
1280{
1281 policing[index].sharindx = index;
1282 policing[index].smax = 65535; /* Burst size in bytes */
1283 policing[index].rate = SJA1105_RATE_MBPS(1000);
1284 policing[index].maxlen = mtu;
1285 policing[index].partition = 0;
1286}
1287
1288static int sja1105_init_l2_policing(struct sja1105_private *priv)
1289{
1290 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1291 struct sja1105_l2_policing_entry *policing;
1292 struct sja1105_table *table;
1293 int cpu = pdata->cpu_port;
1294 int i, j, k;
1295
1296 table = &priv->static_config.tables[BLK_IDX_L2_POLICING];
1297
1298 table->entries = calloc(SJA1105_MAX_L2_POLICING_COUNT,
1299 table->ops->unpacked_entry_size);
1300 if (!table->entries)
1301 return -ENOMEM;
1302
1303 table->entry_count = SJA1105_MAX_L2_POLICING_COUNT;
1304
1305 policing = table->entries;
1306
1307 /* k sweeps through all unicast policers (0-39).
1308 * bcast sweeps through policers 40-44.
1309 */
1310 for (i = 0, k = 0; i < pdata->num_ports; i++) {
1311 int bcast = (pdata->num_ports * SJA1105_NUM_TC) + i;
1312 int mtu = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN;
1313
1314 if (i == cpu)
1315 mtu += VLAN_HLEN;
1316
1317 for (j = 0; j < SJA1105_NUM_TC; j++, k++)
1318 sja1105_setup_policer(policing, k, mtu);
1319
1320 /* Set up this port's policer for broadcast traffic */
1321 sja1105_setup_policer(policing, bcast, mtu);
1322 }
1323 return 0;
1324}
1325
1326static int sja1105_init_mac_settings(struct sja1105_private *priv)
1327{
1328 struct sja1105_mac_config_entry default_mac = {
1329 /* Enable 1 priority queue on egress. */
1330 .top = {0x1FF, 0, 0, 0, 0, 0, 0},
1331 .base = {0x0, 0, 0, 0, 0, 0, 0, 0},
1332 .enabled = {1, 0, 0, 0, 0, 0, 0, 0},
1333 /* Will be overridden in sja1105_port_enable. */
1334 .speed = priv->info->port_speed[SJA1105_SPEED_AUTO],
1335 .egress = true,
1336 .ingress = true,
1337 };
1338 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1339 struct sja1105_mac_config_entry *mac;
1340 struct sja1105_table *table;
1341 int port;
1342
1343 table = &priv->static_config.tables[BLK_IDX_MAC_CONFIG];
1344
1345 table->entries = calloc(pdata->num_ports,
1346 table->ops->unpacked_entry_size);
1347 if (!table->entries)
1348 return -ENOMEM;
1349
1350 table->entry_count = pdata->num_ports;
1351
1352 mac = table->entries;
1353
1354 for (port = 0; port < pdata->num_ports; port++) {
1355 mac[port] = default_mac;
1356 /* Internal VLAN (pvid) to apply to untagged ingress */
1357 mac[port].vlanid = priv->pvid[port];
1358 }
1359
1360 return 0;
1361}
1362
1363static int sja1105_static_config_init(struct sja1105_private *priv)
1364{
1365 struct sja1105_static_config *config = &priv->static_config;
1366 const struct sja1105_table_ops *static_ops = priv->info->static_ops;
1367 u64 device_id = priv->info->device_id;
1368 enum sja1105_blk_idx i;
1369 int rc;
1370
1371 *config = (struct sja1105_static_config) {0};
1372
1373 /* Transfer static_ops array from priv into per-table ops
1374 * for handier access
1375 */
1376 for (i = 0; i < BLK_IDX_MAX; i++)
1377 config->tables[i].ops = &static_ops[i];
1378
1379 config->device_id = device_id;
1380
1381 /* Build initial static configuration, to be fixed up during runtime */
1382 rc = sja1105_init_vlan(priv);
1383 if (rc < 0)
1384 return rc;
1385 rc = sja1105_init_mac_settings(priv);
1386 if (rc < 0)
1387 return rc;
1388 rc = sja1105_init_mii_settings(priv);
1389 if (rc < 0)
1390 return rc;
1391 rc = sja1105_init_l2_forwarding(priv);
1392 if (rc < 0)
1393 return rc;
1394 rc = sja1105_init_l2_forwarding_params(priv);
1395 if (rc < 0)
1396 return rc;
1397 rc = sja1105_init_l2_policing(priv);
1398 if (rc < 0)
1399 return rc;
1400 rc = sja1105_init_general_params(priv);
1401 if (rc < 0)
1402 return rc;
1403
1404 return 0;
1405}
1406
1407static void sja1105_static_config_free(struct sja1105_static_config *config)
1408{
1409 enum sja1105_blk_idx i;
1410
1411 for (i = 0; i < BLK_IDX_MAX; i++) {
1412 if (config->tables[i].entry_count) {
1413 free(config->tables[i].entries);
1414 config->tables[i].entry_count = 0;
1415 }
1416 }
1417}
1418
1419static void sja1105_cgu_idiv_packing(void *buf, struct sja1105_cgu_idiv *idiv,
1420 enum packing_op op)
1421{
1422 const int size = 4;
1423
1424 sja1105_packing(buf, &idiv->clksrc, 28, 24, size, op);
1425 sja1105_packing(buf, &idiv->autoblock, 11, 11, size, op);
1426 sja1105_packing(buf, &idiv->idiv, 5, 2, size, op);
1427 sja1105_packing(buf, &idiv->pd, 0, 0, size, op);
1428}
1429
1430static int sja1105_cgu_idiv_config(struct sja1105_private *priv, int port,
1431 bool enabled, int factor)
1432{
1433 const struct sja1105_regs *regs = priv->info->regs;
1434 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1435 struct sja1105_cgu_idiv idiv;
1436
1437 if (regs->cgu_idiv[port] == SJA1105_RSV_ADDR)
1438 return 0;
1439
1440 if (enabled && factor != 1 && factor != 10)
1441 return -ERANGE;
1442
1443 /* Payload for packed_buf */
1444 idiv.clksrc = 0x0A; /* 25MHz */
1445 idiv.autoblock = 1; /* Block clk automatically */
1446 idiv.idiv = factor - 1; /* Divide by 1 or 10 */
1447 idiv.pd = enabled ? 0 : 1; /* Power down? */
1448 sja1105_cgu_idiv_packing(packed_buf, &idiv, PACK);
1449
1450 return sja1105_xfer_buf(priv, SPI_WRITE, regs->cgu_idiv[port],
1451 packed_buf, SJA1105_SIZE_CGU_CMD);
1452}
1453
1454static void
1455sja1105_cgu_mii_control_packing(void *buf, struct sja1105_cgu_mii_ctrl *cmd,
1456 enum packing_op op)
1457{
1458 const int size = 4;
1459
1460 sja1105_packing(buf, &cmd->clksrc, 28, 24, size, op);
1461 sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
1462 sja1105_packing(buf, &cmd->pd, 0, 0, size, op);
1463}
1464
1465static int sja1105_cgu_mii_tx_clk_config(struct sja1105_private *priv,
1466 int port, sja1105_mii_role_t role)
1467{
1468 const struct sja1105_regs *regs = priv->info->regs;
1469 struct sja1105_cgu_mii_ctrl mii_tx_clk;
1470 const int mac_clk_sources[] = {
1471 CLKSRC_MII0_TX_CLK,
1472 CLKSRC_MII1_TX_CLK,
1473 CLKSRC_MII2_TX_CLK,
1474 CLKSRC_MII3_TX_CLK,
1475 CLKSRC_MII4_TX_CLK,
1476 };
1477 const int phy_clk_sources[] = {
1478 CLKSRC_IDIV0,
1479 CLKSRC_IDIV1,
1480 CLKSRC_IDIV2,
1481 CLKSRC_IDIV3,
1482 CLKSRC_IDIV4,
1483 };
1484 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1485 int clksrc;
1486
1487 if (regs->mii_tx_clk[port] == SJA1105_RSV_ADDR)
1488 return 0;
1489
1490 if (role == XMII_MAC)
1491 clksrc = mac_clk_sources[port];
1492 else
1493 clksrc = phy_clk_sources[port];
1494
1495 /* Payload for packed_buf */
1496 mii_tx_clk.clksrc = clksrc;
1497 mii_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1498 mii_tx_clk.pd = 0; /* Power Down off => enabled */
1499 sja1105_cgu_mii_control_packing(packed_buf, &mii_tx_clk, PACK);
1500
1501 return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_tx_clk[port],
1502 packed_buf, SJA1105_SIZE_CGU_CMD);
1503}
1504
1505static int
1506sja1105_cgu_mii_rx_clk_config(struct sja1105_private *priv, int port)
1507{
1508 const struct sja1105_regs *regs = priv->info->regs;
1509 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1510 struct sja1105_cgu_mii_ctrl mii_rx_clk;
1511 const int clk_sources[] = {
1512 CLKSRC_MII0_RX_CLK,
1513 CLKSRC_MII1_RX_CLK,
1514 CLKSRC_MII2_RX_CLK,
1515 CLKSRC_MII3_RX_CLK,
1516 CLKSRC_MII4_RX_CLK,
1517 };
1518
1519 if (regs->mii_rx_clk[port] == SJA1105_RSV_ADDR)
1520 return 0;
1521
1522 /* Payload for packed_buf */
1523 mii_rx_clk.clksrc = clk_sources[port];
1524 mii_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1525 mii_rx_clk.pd = 0; /* Power Down off => enabled */
1526 sja1105_cgu_mii_control_packing(packed_buf, &mii_rx_clk, PACK);
1527
1528 return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_rx_clk[port],
1529 packed_buf, SJA1105_SIZE_CGU_CMD);
1530}
1531
1532static int
1533sja1105_cgu_mii_ext_tx_clk_config(struct sja1105_private *priv, int port)
1534{
1535 const struct sja1105_regs *regs = priv->info->regs;
1536 struct sja1105_cgu_mii_ctrl mii_ext_tx_clk;
1537 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1538 const int clk_sources[] = {
1539 CLKSRC_IDIV0,
1540 CLKSRC_IDIV1,
1541 CLKSRC_IDIV2,
1542 CLKSRC_IDIV3,
1543 CLKSRC_IDIV4,
1544 };
1545
1546 if (regs->mii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
1547 return 0;
1548
1549 /* Payload for packed_buf */
1550 mii_ext_tx_clk.clksrc = clk_sources[port];
1551 mii_ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1552 mii_ext_tx_clk.pd = 0; /* Power Down off => enabled */
1553 sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_tx_clk, PACK);
1554
1555 return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_ext_tx_clk[port],
1556 packed_buf, SJA1105_SIZE_CGU_CMD);
1557}
1558
1559static int
1560sja1105_cgu_mii_ext_rx_clk_config(struct sja1105_private *priv, int port)
1561{
1562 const struct sja1105_regs *regs = priv->info->regs;
1563 struct sja1105_cgu_mii_ctrl mii_ext_rx_clk;
1564 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1565 const int clk_sources[] = {
1566 CLKSRC_IDIV0,
1567 CLKSRC_IDIV1,
1568 CLKSRC_IDIV2,
1569 CLKSRC_IDIV3,
1570 CLKSRC_IDIV4,
1571 };
1572
1573 if (regs->mii_ext_rx_clk[port] == SJA1105_RSV_ADDR)
1574 return 0;
1575
1576 /* Payload for packed_buf */
1577 mii_ext_rx_clk.clksrc = clk_sources[port];
1578 mii_ext_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1579 mii_ext_rx_clk.pd = 0; /* Power Down off => enabled */
1580 sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_rx_clk, PACK);
1581
1582 return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_ext_rx_clk[port],
1583 packed_buf, SJA1105_SIZE_CGU_CMD);
1584}
1585
1586static int sja1105_mii_clocking_setup(struct sja1105_private *priv, int port,
1587 sja1105_mii_role_t role)
1588{
1589 int rc;
1590
1591 rc = sja1105_cgu_idiv_config(priv, port, (role == XMII_PHY), 1);
1592 if (rc < 0)
1593 return rc;
1594
1595 rc = sja1105_cgu_mii_tx_clk_config(priv, port, role);
1596 if (rc < 0)
1597 return rc;
1598
1599 rc = sja1105_cgu_mii_rx_clk_config(priv, port);
1600 if (rc < 0)
1601 return rc;
1602
1603 if (role == XMII_PHY) {
1604 rc = sja1105_cgu_mii_ext_tx_clk_config(priv, port);
1605 if (rc < 0)
1606 return rc;
1607
1608 rc = sja1105_cgu_mii_ext_rx_clk_config(priv, port);
1609 if (rc < 0)
1610 return rc;
1611 }
1612 return 0;
1613}
1614
1615static void
1616sja1105_cgu_pll_control_packing(void *buf, struct sja1105_cgu_pll_ctrl *cmd,
1617 enum packing_op op)
1618{
1619 const int size = 4;
1620
1621 sja1105_packing(buf, &cmd->pllclksrc, 28, 24, size, op);
1622 sja1105_packing(buf, &cmd->msel, 23, 16, size, op);
1623 sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
1624 sja1105_packing(buf, &cmd->psel, 9, 8, size, op);
1625 sja1105_packing(buf, &cmd->direct, 7, 7, size, op);
1626 sja1105_packing(buf, &cmd->fbsel, 6, 6, size, op);
1627 sja1105_packing(buf, &cmd->bypass, 1, 1, size, op);
1628 sja1105_packing(buf, &cmd->pd, 0, 0, size, op);
1629}
1630
1631static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
1632 int port, u64 speed)
1633{
1634 const struct sja1105_regs *regs = priv->info->regs;
1635 struct sja1105_cgu_mii_ctrl txc;
1636 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1637 int clksrc;
1638
1639 if (regs->rgmii_tx_clk[port] == SJA1105_RSV_ADDR)
1640 return 0;
1641
1642 if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
1643 clksrc = CLKSRC_PLL0;
1644 } else {
1645 int clk_sources[] = {CLKSRC_IDIV0, CLKSRC_IDIV1, CLKSRC_IDIV2,
1646 CLKSRC_IDIV3, CLKSRC_IDIV4};
1647 clksrc = clk_sources[port];
1648 }
1649
1650 /* RGMII: 125MHz for 1000, 25MHz for 100, 2.5MHz for 10 */
1651 txc.clksrc = clksrc;
1652 /* Autoblock clk while changing clksrc */
1653 txc.autoblock = 1;
1654 /* Power Down off => enabled */
1655 txc.pd = 0;
1656 sja1105_cgu_mii_control_packing(packed_buf, &txc, PACK);
1657
1658 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgmii_tx_clk[port],
1659 packed_buf, SJA1105_SIZE_CGU_CMD);
1660}
1661
1662/* AGU */
1663static void
1664sja1105_cfg_pad_mii_packing(void *buf, struct sja1105_cfg_pad_mii *cmd,
1665 enum packing_op op)
1666{
1667 const int size = 4;
1668
1669 sja1105_packing(buf, &cmd->d32_os, 28, 27, size, op);
1670 sja1105_packing(buf, &cmd->d32_ih, 26, 26, size, op);
1671 sja1105_packing(buf, &cmd->d32_ipud, 25, 24, size, op);
1672 sja1105_packing(buf, &cmd->d10_os, 20, 19, size, op);
1673 sja1105_packing(buf, &cmd->d10_ih, 18, 18, size, op);
1674 sja1105_packing(buf, &cmd->d10_ipud, 17, 16, size, op);
1675 sja1105_packing(buf, &cmd->ctrl_os, 12, 11, size, op);
1676 sja1105_packing(buf, &cmd->ctrl_ih, 10, 10, size, op);
1677 sja1105_packing(buf, &cmd->ctrl_ipud, 9, 8, size, op);
1678 sja1105_packing(buf, &cmd->clk_os, 4, 3, size, op);
1679 sja1105_packing(buf, &cmd->clk_ih, 2, 2, size, op);
1680 sja1105_packing(buf, &cmd->clk_ipud, 1, 0, size, op);
1681}
1682
1683static void
1684sja1110_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
1685 enum packing_op op)
1686{
1687 const int size = SJA1105_SIZE_CGU_CMD;
1688 u64 range = 4;
1689
1690 /* Fields RXC_RANGE and TXC_RANGE select the input frequency range:
1691 * 0 = 2.5MHz
1692 * 1 = 25MHz
1693 * 2 = 50MHz
1694 * 3 = 125MHz
1695 * 4 = Automatically determined by port speed.
1696 * There's no point in defining a structure different than the one for
1697 * SJA1105, so just hardcode the frequency range to automatic, just as
1698 * before.
1699 */
1700 sja1105_packing(buf, &cmd->rxc_stable_ovr, 26, 26, size, op);
1701 sja1105_packing(buf, &cmd->rxc_delay, 25, 21, size, op);
1702 sja1105_packing(buf, &range, 20, 18, size, op);
1703 sja1105_packing(buf, &cmd->rxc_bypass, 17, 17, size, op);
1704 sja1105_packing(buf, &cmd->rxc_pd, 16, 16, size, op);
1705 sja1105_packing(buf, &cmd->txc_stable_ovr, 10, 10, size, op);
1706 sja1105_packing(buf, &cmd->txc_delay, 9, 5, size, op);
1707 sja1105_packing(buf, &range, 4, 2, size, op);
1708 sja1105_packing(buf, &cmd->txc_bypass, 1, 1, size, op);
1709 sja1105_packing(buf, &cmd->txc_pd, 0, 0, size, op);
1710}
1711
1712static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv,
1713 int port)
1714{
1715 const struct sja1105_regs *regs = priv->info->regs;
1716 struct sja1105_cfg_pad_mii pad_mii_tx = {0};
1717 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1718
1719 if (regs->pad_mii_tx[port] == SJA1105_RSV_ADDR)
1720 return 0;
1721
1722 /* Payload */
1723 pad_mii_tx.d32_os = 3; /* TXD[3:2] output stage: */
1724 /* high noise/high speed */
1725 pad_mii_tx.d10_os = 3; /* TXD[1:0] output stage: */
1726 /* high noise/high speed */
1727 pad_mii_tx.d32_ipud = 2; /* TXD[3:2] input stage: */
1728 /* plain input (default) */
1729 pad_mii_tx.d10_ipud = 2; /* TXD[1:0] input stage: */
1730 /* plain input (default) */
1731 pad_mii_tx.ctrl_os = 3; /* TX_CTL / TX_ER output stage */
1732 pad_mii_tx.ctrl_ipud = 2; /* TX_CTL / TX_ER input stage (default) */
1733 pad_mii_tx.clk_os = 3; /* TX_CLK output stage */
1734 pad_mii_tx.clk_ih = 0; /* TX_CLK input hysteresis (default) */
1735 pad_mii_tx.clk_ipud = 2; /* TX_CLK input stage (default) */
1736 sja1105_cfg_pad_mii_packing(packed_buf, &pad_mii_tx, PACK);
1737
1738 return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_tx[port],
1739 packed_buf, SJA1105_SIZE_CGU_CMD);
1740}
1741
1742static int sja1105_cfg_pad_rx_config(struct sja1105_private *priv, int port)
1743{
1744 const struct sja1105_regs *regs = priv->info->regs;
1745 struct sja1105_cfg_pad_mii pad_mii_rx = {0};
1746 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1747
1748 if (regs->pad_mii_rx[port] == SJA1105_RSV_ADDR)
1749 return 0;
1750
1751 /* Payload */
1752 pad_mii_rx.d32_ih = 0; /* RXD[3:2] input stage hysteresis: */
1753 /* non-Schmitt (default) */
1754 pad_mii_rx.d32_ipud = 2; /* RXD[3:2] input weak pull-up/down */
1755 /* plain input (default) */
1756 pad_mii_rx.d10_ih = 0; /* RXD[1:0] input stage hysteresis: */
1757 /* non-Schmitt (default) */
1758 pad_mii_rx.d10_ipud = 2; /* RXD[1:0] input weak pull-up/down */
1759 /* plain input (default) */
1760 pad_mii_rx.ctrl_ih = 0; /* RX_DV/CRS_DV/RX_CTL and RX_ER */
1761 /* input stage hysteresis: */
1762 /* non-Schmitt (default) */
1763 pad_mii_rx.ctrl_ipud = 3; /* RX_DV/CRS_DV/RX_CTL and RX_ER */
1764 /* input stage weak pull-up/down: */
1765 /* pull-down */
1766 pad_mii_rx.clk_os = 2; /* RX_CLK/RXC output stage: */
1767 /* medium noise/fast speed (default) */
1768 pad_mii_rx.clk_ih = 0; /* RX_CLK/RXC input hysteresis: */
1769 /* non-Schmitt (default) */
1770 pad_mii_rx.clk_ipud = 2; /* RX_CLK/RXC input pull-up/down: */
1771 /* plain input (default) */
1772 sja1105_cfg_pad_mii_packing(packed_buf, &pad_mii_rx, PACK);
1773
1774 return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_rx[port],
1775 packed_buf, SJA1105_SIZE_CGU_CMD);
1776}
1777
1778static void
1779sja1105_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
1780 enum packing_op op)
1781{
1782 const int size = SJA1105_SIZE_CGU_CMD;
1783
1784 sja1105_packing(buf, &cmd->rxc_stable_ovr, 15, 15, size, op);
1785 sja1105_packing(buf, &cmd->rxc_delay, 14, 10, size, op);
1786 sja1105_packing(buf, &cmd->rxc_bypass, 9, 9, size, op);
1787 sja1105_packing(buf, &cmd->rxc_pd, 8, 8, size, op);
1788 sja1105_packing(buf, &cmd->txc_stable_ovr, 7, 7, size, op);
1789 sja1105_packing(buf, &cmd->txc_delay, 6, 2, size, op);
1790 sja1105_packing(buf, &cmd->txc_bypass, 1, 1, size, op);
1791 sja1105_packing(buf, &cmd->txc_pd, 0, 0, size, op);
1792}
1793
1794/* Valid range in degrees is an integer between 73.8 and 101.7 */
1795static u64 sja1105_rgmii_delay(u64 phase)
1796{
1797 /* UM11040.pdf: The delay in degree phase is 73.8 + delay_tune * 0.9.
1798 * To avoid floating point operations we'll multiply by 10
1799 * and get 1 decimal point precision.
1800 */
1801 phase *= 10;
1802 return (phase - 738) / 9;
1803}
1804
1805static int sja1105pqrs_setup_rgmii_delay(struct sja1105_private *priv, int port)
1806{
1807 const struct sja1105_regs *regs = priv->info->regs;
1808 struct sja1105_cfg_pad_mii_id pad_mii_id = {0};
1809 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1810 int rc;
1811
1812 if (priv->rgmii_rx_delay[port])
1813 pad_mii_id.rxc_delay = sja1105_rgmii_delay(90);
1814 if (priv->rgmii_tx_delay[port])
1815 pad_mii_id.txc_delay = sja1105_rgmii_delay(90);
1816
1817 /* Stage 1: Turn the RGMII delay lines off. */
1818 pad_mii_id.rxc_bypass = 1;
1819 pad_mii_id.rxc_pd = 1;
1820 pad_mii_id.txc_bypass = 1;
1821 pad_mii_id.txc_pd = 1;
1822 sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
1823
1824 rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
1825 packed_buf, SJA1105_SIZE_CGU_CMD);
1826 if (rc < 0)
1827 return rc;
1828
1829 /* Stage 2: Turn the RGMII delay lines on. */
1830 if (priv->rgmii_rx_delay[port]) {
1831 pad_mii_id.rxc_bypass = 0;
1832 pad_mii_id.rxc_pd = 0;
1833 }
1834 if (priv->rgmii_tx_delay[port]) {
1835 pad_mii_id.txc_bypass = 0;
1836 pad_mii_id.txc_pd = 0;
1837 }
1838 sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
1839
1840 return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
1841 packed_buf, SJA1105_SIZE_CGU_CMD);
1842}
1843
1844static int sja1110_setup_rgmii_delay(struct sja1105_private *priv, int port)
1845{
1846 const struct sja1105_regs *regs = priv->info->regs;
1847 struct sja1105_cfg_pad_mii_id pad_mii_id = {0};
1848 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1849
1850 pad_mii_id.rxc_pd = 1;
1851 pad_mii_id.txc_pd = 1;
1852
1853 if (priv->rgmii_rx_delay[port]) {
1854 pad_mii_id.rxc_delay = sja1105_rgmii_delay(90);
1855 /* The "BYPASS" bit in SJA1110 is actually a "don't bypass" */
1856 pad_mii_id.rxc_bypass = 1;
1857 pad_mii_id.rxc_pd = 0;
1858 }
1859
1860 if (priv->rgmii_tx_delay[port]) {
1861 pad_mii_id.txc_delay = sja1105_rgmii_delay(90);
1862 pad_mii_id.txc_bypass = 1;
1863 pad_mii_id.txc_pd = 0;
1864 }
1865
1866 sja1110_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
1867
1868 return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
1869 packed_buf, SJA1105_SIZE_CGU_CMD);
1870}
1871
1872static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port,
1873 sja1105_mii_role_t role)
1874{
1875 struct sja1105_mac_config_entry *mac;
1876 struct udevice *dev = priv->dev;
1877 u64 speed;
1878 int rc;
1879
1880 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
1881 speed = mac[port].speed;
1882
1883 if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
1884 /* 1000Mbps, IDIV disabled (125 MHz) */
1885 rc = sja1105_cgu_idiv_config(priv, port, false, 1);
1886 } else if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) {
1887 /* 100Mbps, IDIV enabled, divide by 1 (25 MHz) */
1888 rc = sja1105_cgu_idiv_config(priv, port, true, 1);
1889 } else if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) {
1890 /* 10Mbps, IDIV enabled, divide by 10 (2.5 MHz) */
1891 rc = sja1105_cgu_idiv_config(priv, port, true, 10);
1892 } else if (speed == priv->info->port_speed[SJA1105_SPEED_AUTO]) {
1893 /* Skip CGU configuration if there is no speed available
1894 * (e.g. link is not established yet)
1895 */
1896 dev_dbg(dev, "Speed not available, skipping CGU config\n");
1897 return 0;
1898 } else {
1899 rc = -EINVAL;
1900 }
1901
1902 if (rc < 0) {
1903 dev_err(dev, "Failed to configure idiv\n");
1904 return rc;
1905 }
1906 rc = sja1105_cgu_rgmii_tx_clk_config(priv, port, speed);
1907 if (rc < 0) {
1908 dev_err(dev, "Failed to configure RGMII Tx clock\n");
1909 return rc;
1910 }
1911 rc = sja1105_rgmii_cfg_pad_tx_config(priv, port);
1912 if (rc < 0) {
1913 dev_err(dev, "Failed to configure Tx pad registers\n");
1914 return rc;
1915 }
1916
1917 if (!priv->info->setup_rgmii_delay)
1918 return 0;
1919
1920 return priv->info->setup_rgmii_delay(priv, port);
1921}
1922
1923static int sja1105_cgu_rmii_ref_clk_config(struct sja1105_private *priv,
1924 int port)
1925{
1926 const struct sja1105_regs *regs = priv->info->regs;
1927 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1928 struct sja1105_cgu_mii_ctrl ref_clk;
1929 const int clk_sources[] = {
1930 CLKSRC_MII0_TX_CLK,
1931 CLKSRC_MII1_TX_CLK,
1932 CLKSRC_MII2_TX_CLK,
1933 CLKSRC_MII3_TX_CLK,
1934 CLKSRC_MII4_TX_CLK,
1935 };
1936
1937 if (regs->rmii_ref_clk[port] == SJA1105_RSV_ADDR)
1938 return 0;
1939
1940 /* Payload for packed_buf */
1941 ref_clk.clksrc = clk_sources[port];
1942 ref_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1943 ref_clk.pd = 0; /* Power Down off => enabled */
1944 sja1105_cgu_mii_control_packing(packed_buf, &ref_clk, PACK);
1945
1946 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_ref_clk[port],
1947 packed_buf, SJA1105_SIZE_CGU_CMD);
1948}
1949
1950static int
1951sja1105_cgu_rmii_ext_tx_clk_config(struct sja1105_private *priv, int port)
1952{
1953 const struct sja1105_regs *regs = priv->info->regs;
1954 struct sja1105_cgu_mii_ctrl ext_tx_clk;
1955 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1956
1957 if (regs->rmii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
1958 return 0;
1959
1960 /* Payload for packed_buf */
1961 ext_tx_clk.clksrc = CLKSRC_PLL1;
1962 ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1963 ext_tx_clk.pd = 0; /* Power Down off => enabled */
1964 sja1105_cgu_mii_control_packing(packed_buf, &ext_tx_clk, PACK);
1965
1966 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_ext_tx_clk[port],
1967 packed_buf, SJA1105_SIZE_CGU_CMD);
1968}
1969
1970static int sja1105_cgu_rmii_pll_config(struct sja1105_private *priv)
1971{
1972 const struct sja1105_regs *regs = priv->info->regs;
1973 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1974 struct sja1105_cgu_pll_ctrl pll = {0};
1975 int rc;
1976
1977 if (regs->rmii_pll1 == SJA1105_RSV_ADDR)
1978 return 0;
1979
1980 /* Step 1: PLL1 setup for 50Mhz */
1981 pll.pllclksrc = 0xA;
1982 pll.msel = 0x1;
1983 pll.autoblock = 0x1;
1984 pll.psel = 0x1;
1985 pll.direct = 0x0;
1986 pll.fbsel = 0x1;
1987 pll.bypass = 0x0;
1988 pll.pd = 0x1;
1989
1990 sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
1991 rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_pll1, packed_buf,
1992 SJA1105_SIZE_CGU_CMD);
1993 if (rc < 0)
1994 return rc;
1995
1996 /* Step 2: Enable PLL1 */
1997 pll.pd = 0x0;
1998
1999 sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
2000 rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_pll1, packed_buf,
2001 SJA1105_SIZE_CGU_CMD);
2002 return rc;
2003}
2004
2005static int sja1105_rmii_clocking_setup(struct sja1105_private *priv, int port,
2006 sja1105_mii_role_t role)
2007{
2008 int rc;
2009
2010 /* AH1601.pdf chapter 2.5.1. Sources */
2011 if (role == XMII_MAC) {
2012 /* Configure and enable PLL1 for 50Mhz output */
2013 rc = sja1105_cgu_rmii_pll_config(priv);
2014 if (rc < 0)
2015 return rc;
2016 }
2017 /* Disable IDIV for this port */
2018 rc = sja1105_cgu_idiv_config(priv, port, false, 1);
2019 if (rc < 0)
2020 return rc;
2021 /* Source to sink mappings */
2022 rc = sja1105_cgu_rmii_ref_clk_config(priv, port);
2023 if (rc < 0)
2024 return rc;
2025 if (role == XMII_MAC) {
2026 rc = sja1105_cgu_rmii_ext_tx_clk_config(priv, port);
2027 if (rc < 0)
2028 return rc;
2029 }
2030 return 0;
2031}
2032
2033static int sja1105_clocking_setup_port(struct sja1105_private *priv, int port)
2034{
2035 struct sja1105_xmii_params_entry *mii;
2036 sja1105_phy_interface_t phy_mode;
2037 sja1105_mii_role_t role;
2038 int rc;
2039
2040 mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
2041
2042 /* RGMII etc */
2043 phy_mode = mii->xmii_mode[port];
2044 /* MAC or PHY, for applicable types (not RGMII) */
2045 role = mii->phy_mac[port];
2046
2047 switch (phy_mode) {
2048 case XMII_MODE_MII:
2049 rc = sja1105_mii_clocking_setup(priv, port, role);
2050 break;
2051 case XMII_MODE_RMII:
2052 rc = sja1105_rmii_clocking_setup(priv, port, role);
2053 break;
2054 case XMII_MODE_RGMII:
2055 rc = sja1105_rgmii_clocking_setup(priv, port, role);
2056 break;
2057 default:
2058 return -EINVAL;
2059 }
2060 if (rc)
2061 return rc;
2062
2063 /* Internally pull down the RX_DV/CRS_DV/RX_CTL and RX_ER inputs */
2064 return sja1105_cfg_pad_rx_config(priv, port);
2065}
2066
2067static int sja1105_clocking_setup(struct sja1105_private *priv)
2068{
2069 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
2070 int port, rc;
2071
2072 for (port = 0; port < pdata->num_ports; port++) {
2073 rc = sja1105_clocking_setup_port(priv, port);
2074 if (rc < 0)
2075 return rc;
2076 }
2077 return 0;
2078}
2079
2080static const struct sja1105_regs sja1105et_regs = {
2081 .device_id = 0x0,
2082 .prod_id = 0x100BC3,
2083 .status = 0x1,
2084 .port_control = 0x11,
2085 .config = 0x020000,
2086 .rgu = 0x100440,
2087 /* UM10944.pdf, Table 86, ACU Register overview */
2088 .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
2089 .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
2090 .rmii_pll1 = 0x10000A,
2091 .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
2092 /* UM10944.pdf, Table 78, CGU Register overview */
2093 .mii_tx_clk = {0x100013, 0x10001A, 0x100021, 0x100028, 0x10002F},
2094 .mii_rx_clk = {0x100014, 0x10001B, 0x100022, 0x100029, 0x100030},
2095 .mii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
2096 .mii_ext_rx_clk = {0x100019, 0x100020, 0x100027, 0x10002E, 0x100035},
2097 .rgmii_tx_clk = {0x100016, 0x10001D, 0x100024, 0x10002B, 0x100032},
2098 .rmii_ref_clk = {0x100015, 0x10001C, 0x100023, 0x10002A, 0x100031},
2099 .rmii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
2100};
2101
2102static const struct sja1105_regs sja1105pqrs_regs = {
2103 .device_id = 0x0,
2104 .prod_id = 0x100BC3,
2105 .status = 0x1,
2106 .port_control = 0x12,
2107 .config = 0x020000,
2108 .rgu = 0x100440,
2109 /* UM10944.pdf, Table 86, ACU Register overview */
2110 .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
2111 .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
2112 .pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814},
2113 .rmii_pll1 = 0x10000A,
2114 .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
2115 /* UM11040.pdf, Table 114 */
2116 .mii_tx_clk = {0x100013, 0x100019, 0x10001F, 0x100025, 0x10002B},
2117 .mii_rx_clk = {0x100014, 0x10001A, 0x100020, 0x100026, 0x10002C},
2118 .mii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
2119 .mii_ext_rx_clk = {0x100018, 0x10001E, 0x100024, 0x10002A, 0x100030},
2120 .rgmii_tx_clk = {0x100016, 0x10001C, 0x100022, 0x100028, 0x10002E},
2121 .rmii_ref_clk = {0x100015, 0x10001B, 0x100021, 0x100027, 0x10002D},
2122 .rmii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
2123};
2124
2125static const struct sja1105_regs sja1110_regs = {
2126 .device_id = SJA1110_SPI_ADDR(0x0),
2127 .prod_id = SJA1110_ACU_ADDR(0xf00),
2128 .status = SJA1110_SPI_ADDR(0x4),
2129 .port_control = SJA1110_SPI_ADDR(0x50), /* actually INHIB_TX */
2130 .config = 0x020000,
2131 .rgu = SJA1110_RGU_ADDR(0x100), /* Reset Control Register 0 */
2132 /* Ports 2 and 3 are capable of xMII, but there isn't anything to
2133 * configure in the CGU/ACU for them.
2134 */
2135 .pad_mii_tx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2136 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2137 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2138 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2139 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2140 SJA1105_RSV_ADDR},
2141 .pad_mii_rx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2142 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2143 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2144 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2145 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2146 SJA1105_RSV_ADDR},
2147 .pad_mii_id = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2148 SJA1110_ACU_ADDR(0x18), SJA1110_ACU_ADDR(0x28),
2149 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2150 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2151 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2152 SJA1105_RSV_ADDR},
2153 .rmii_pll1 = SJA1105_RSV_ADDR,
2154 .cgu_idiv = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2155 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2156 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2157 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2158 .mii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2159 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2160 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2161 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2162 .mii_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2163 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2164 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2165 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2166 .mii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2167 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2168 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2169 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2170 .mii_ext_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2171 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2172 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2173 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2174 .rgmii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2175 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2176 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2177 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2178 .rmii_ref_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2179 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2180 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2181 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2182 .rmii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2183 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2184 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2185 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2186 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2187 SJA1105_RSV_ADDR},
2188};
2189
2190enum sja1105_switch_id {
2191 SJA1105E = 0,
2192 SJA1105T,
2193 SJA1105P,
2194 SJA1105Q,
2195 SJA1105R,
2196 SJA1105S,
2197 SJA1110A,
2198 SJA1110B,
2199 SJA1110C,
2200 SJA1110D,
2201 SJA1105_MAX_SWITCH_ID,
2202};
2203
2204static const struct sja1105_info sja1105_info[] = {
2205 [SJA1105E] = {
2206 .device_id = SJA1105E_DEVICE_ID,
2207 .part_no = SJA1105ET_PART_NO,
2208 .static_ops = sja1105et_table_ops,
2209 .reset_cmd = sja1105et_reset_cmd,
2210 .regs = &sja1105et_regs,
2211 .port_speed = {
2212 [SJA1105_SPEED_AUTO] = 0,
2213 [SJA1105_SPEED_10MBPS] = 3,
2214 [SJA1105_SPEED_100MBPS] = 2,
2215 [SJA1105_SPEED_1000MBPS] = 1,
2216 },
2217 .supports_mii = {true, true, true, true, true},
2218 .supports_rmii = {true, true, true, true, true},
2219 .supports_rgmii = {true, true, true, true, true},
2220 .name = "SJA1105E",
2221 },
2222 [SJA1105T] = {
2223 .device_id = SJA1105T_DEVICE_ID,
2224 .part_no = SJA1105ET_PART_NO,
2225 .static_ops = sja1105et_table_ops,
2226 .reset_cmd = sja1105et_reset_cmd,
2227 .regs = &sja1105et_regs,
2228 .port_speed = {
2229 [SJA1105_SPEED_AUTO] = 0,
2230 [SJA1105_SPEED_10MBPS] = 3,
2231 [SJA1105_SPEED_100MBPS] = 2,
2232 [SJA1105_SPEED_1000MBPS] = 1,
2233 },
2234 .supports_mii = {true, true, true, true, true},
2235 .supports_rmii = {true, true, true, true, true},
2236 .supports_rgmii = {true, true, true, true, true},
2237 .name = "SJA1105T",
2238 },
2239 [SJA1105P] = {
2240 .device_id = SJA1105PR_DEVICE_ID,
2241 .part_no = SJA1105P_PART_NO,
2242 .static_ops = sja1105pqrs_table_ops,
2243 .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
2244 .reset_cmd = sja1105pqrs_reset_cmd,
2245 .regs = &sja1105pqrs_regs,
2246 .port_speed = {
2247 [SJA1105_SPEED_AUTO] = 0,
2248 [SJA1105_SPEED_10MBPS] = 3,
2249 [SJA1105_SPEED_100MBPS] = 2,
2250 [SJA1105_SPEED_1000MBPS] = 1,
2251 },
2252 .supports_mii = {true, true, true, true, true},
2253 .supports_rmii = {true, true, true, true, true},
2254 .supports_rgmii = {true, true, true, true, true},
2255 .name = "SJA1105P",
2256 },
2257 [SJA1105Q] = {
2258 .device_id = SJA1105QS_DEVICE_ID,
2259 .part_no = SJA1105Q_PART_NO,
2260 .static_ops = sja1105pqrs_table_ops,
2261 .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
2262 .reset_cmd = sja1105pqrs_reset_cmd,
2263 .regs = &sja1105pqrs_regs,
2264 .port_speed = {
2265 [SJA1105_SPEED_AUTO] = 0,
2266 [SJA1105_SPEED_10MBPS] = 3,
2267 [SJA1105_SPEED_100MBPS] = 2,
2268 [SJA1105_SPEED_1000MBPS] = 1,
2269 },
2270 .supports_mii = {true, true, true, true, true},
2271 .supports_rmii = {true, true, true, true, true},
2272 .supports_rgmii = {true, true, true, true, true},
2273 .name = "SJA1105Q",
2274 },
2275 [SJA1105R] = {
2276 .device_id = SJA1105PR_DEVICE_ID,
2277 .part_no = SJA1105R_PART_NO,
2278 .static_ops = sja1105pqrs_table_ops,
2279 .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
2280 .reset_cmd = sja1105pqrs_reset_cmd,
2281 .regs = &sja1105pqrs_regs,
2282 .port_speed = {
2283 [SJA1105_SPEED_AUTO] = 0,
2284 [SJA1105_SPEED_10MBPS] = 3,
2285 [SJA1105_SPEED_100MBPS] = 2,
2286 [SJA1105_SPEED_1000MBPS] = 1,
2287 },
2288 .supports_mii = {true, true, true, true, true},
2289 .supports_rmii = {true, true, true, true, true},
2290 .supports_rgmii = {true, true, true, true, true},
2291 .name = "SJA1105R",
2292 },
2293 [SJA1105S] = {
2294 .device_id = SJA1105QS_DEVICE_ID,
2295 .part_no = SJA1105S_PART_NO,
2296 .static_ops = sja1105pqrs_table_ops,
2297 .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
2298 .reset_cmd = sja1105pqrs_reset_cmd,
2299 .regs = &sja1105pqrs_regs,
2300 .port_speed = {
2301 [SJA1105_SPEED_AUTO] = 0,
2302 [SJA1105_SPEED_10MBPS] = 3,
2303 [SJA1105_SPEED_100MBPS] = 2,
2304 [SJA1105_SPEED_1000MBPS] = 1,
2305 },
2306 .supports_mii = {true, true, true, true, true},
2307 .supports_rmii = {true, true, true, true, true},
2308 .supports_rgmii = {true, true, true, true, true},
2309 .name = "SJA1105S",
2310 },
2311 [SJA1110A] = {
2312 .device_id = SJA1110_DEVICE_ID,
2313 .part_no = SJA1110A_PART_NO,
2314 .static_ops = sja1110_table_ops,
2315 .setup_rgmii_delay = sja1110_setup_rgmii_delay,
2316 .reset_cmd = sja1110_reset_cmd,
2317 .regs = &sja1110_regs,
2318 .port_speed = {
2319 [SJA1105_SPEED_AUTO] = 0,
2320 [SJA1105_SPEED_10MBPS] = 4,
2321 [SJA1105_SPEED_100MBPS] = 3,
2322 [SJA1105_SPEED_1000MBPS] = 2,
2323 },
2324 .supports_mii = {true, true, true, true, false,
2325 true, true, true, true, true, true},
2326 .supports_rmii = {false, false, true, true, false,
2327 false, false, false, false, false, false},
2328 .supports_rgmii = {false, false, true, true, false,
2329 false, false, false, false, false, false},
2330 .name = "SJA1110A",
2331 },
2332 [SJA1110B] = {
2333 .device_id = SJA1110_DEVICE_ID,
2334 .part_no = SJA1110B_PART_NO,
2335 .static_ops = sja1110_table_ops,
2336 .setup_rgmii_delay = sja1110_setup_rgmii_delay,
2337 .reset_cmd = sja1110_reset_cmd,
2338 .regs = &sja1110_regs,
2339 .port_speed = {
2340 [SJA1105_SPEED_AUTO] = 0,
2341 [SJA1105_SPEED_10MBPS] = 4,
2342 [SJA1105_SPEED_100MBPS] = 3,
2343 [SJA1105_SPEED_1000MBPS] = 2,
2344 },
2345 .supports_mii = {true, true, true, true, false,
2346 true, true, true, true, true, false},
2347 .supports_rmii = {false, false, true, true, false,
2348 false, false, false, false, false, false},
2349 .supports_rgmii = {false, false, true, true, false,
2350 false, false, false, false, false, false},
2351 .name = "SJA1110B",
2352 },
2353 [SJA1110C] = {
2354 .device_id = SJA1110_DEVICE_ID,
2355 .part_no = SJA1110C_PART_NO,
2356 .static_ops = sja1110_table_ops,
2357 .setup_rgmii_delay = sja1110_setup_rgmii_delay,
2358 .reset_cmd = sja1110_reset_cmd,
2359 .regs = &sja1110_regs,
2360 .port_speed = {
2361 [SJA1105_SPEED_AUTO] = 0,
2362 [SJA1105_SPEED_10MBPS] = 4,
2363 [SJA1105_SPEED_100MBPS] = 3,
2364 [SJA1105_SPEED_1000MBPS] = 2,
2365 },
2366 .supports_mii = {true, true, true, true, false,
2367 true, true, true, false, false, false},
2368 .supports_rmii = {false, false, true, true, false,
2369 false, false, false, false, false, false},
2370 .supports_rgmii = {false, false, true, true, false,
2371 false, false, false, false, false, false},
2372 .name = "SJA1110C",
2373 },
2374 [SJA1110D] = {
2375 .device_id = SJA1110_DEVICE_ID,
2376 .part_no = SJA1110D_PART_NO,
2377 .static_ops = sja1110_table_ops,
2378 .setup_rgmii_delay = sja1110_setup_rgmii_delay,
2379 .reset_cmd = sja1110_reset_cmd,
2380 .regs = &sja1110_regs,
2381 .port_speed = {
2382 [SJA1105_SPEED_AUTO] = 0,
2383 [SJA1105_SPEED_10MBPS] = 4,
2384 [SJA1105_SPEED_100MBPS] = 3,
2385 [SJA1105_SPEED_1000MBPS] = 2,
2386 },
2387 .supports_mii = {true, false, true, false, false,
2388 true, true, true, false, false, false},
2389 .supports_rmii = {false, false, true, false, false,
2390 false, false, false, false, false, false},
2391 .supports_rgmii = {false, false, true, false, false,
2392 false, false, false, false, false, false},
2393 .name = "SJA1110D",
2394 },
2395};
2396
2397struct sja1105_status {
2398 u64 configs;
2399 u64 crcchkl;
2400 u64 ids;
2401 u64 crcchkg;
2402};
2403
2404static void sja1105_status_unpack(void *buf, struct sja1105_status *status)
2405{
2406 sja1105_packing(buf, &status->configs, 31, 31, 4, UNPACK);
2407 sja1105_packing(buf, &status->crcchkl, 30, 30, 4, UNPACK);
2408 sja1105_packing(buf, &status->ids, 29, 29, 4, UNPACK);
2409 sja1105_packing(buf, &status->crcchkg, 28, 28, 4, UNPACK);
2410}
2411
2412static int sja1105_status_get(struct sja1105_private *priv,
2413 struct sja1105_status *status)
2414{
2415 const struct sja1105_regs *regs = priv->info->regs;
2416 u8 packed_buf[4];
2417 int rc;
2418
2419 rc = sja1105_xfer_buf(priv, SPI_READ, regs->status, packed_buf, 4);
2420 if (rc < 0)
2421 return rc;
2422
2423 sja1105_status_unpack(packed_buf, status);
2424
2425 return 0;
2426}
2427
2428/* Not const because unpacking priv->static_config into buffers and preparing
2429 * for upload requires the recalculation of table CRCs and updating the
2430 * structures with these.
2431 */
2432static int
2433static_config_buf_prepare_for_upload(struct sja1105_private *priv,
2434 void *config_buf, int buf_len)
2435{
2436 struct sja1105_static_config *config = &priv->static_config;
2437 struct sja1105_table_header final_header;
2438 char *final_header_ptr;
2439 int crc_len;
2440
2441 /* Write Device ID and config tables to config_buf */
2442 sja1105_static_config_pack(config_buf, config);
2443 /* Recalculate CRC of the last header (right now 0xDEADBEEF).
2444 * Don't include the CRC field itself.
2445 */
2446 crc_len = buf_len - 4;
2447 /* Read the whole table header */
2448 final_header_ptr = config_buf + buf_len - SJA1105_SIZE_TABLE_HEADER;
2449 sja1105_table_header_packing(final_header_ptr, &final_header, UNPACK);
2450 /* Modify */
2451 final_header.crc = sja1105_crc32(config_buf, crc_len);
2452 /* Rewrite */
2453 sja1105_table_header_packing(final_header_ptr, &final_header, PACK);
2454
2455 return 0;
2456}
2457
2458static int sja1105_static_config_upload(struct sja1105_private *priv)
2459{
2460 struct sja1105_static_config *config = &priv->static_config;
2461 const struct sja1105_regs *regs = priv->info->regs;
2462 struct sja1105_status status;
2463 u8 *config_buf;
2464 int buf_len;
2465 int rc;
2466
2467 buf_len = sja1105_static_config_get_length(config);
2468 config_buf = calloc(buf_len, sizeof(char));
2469 if (!config_buf)
2470 return -ENOMEM;
2471
2472 rc = static_config_buf_prepare_for_upload(priv, config_buf, buf_len);
2473 if (rc < 0) {
2474 printf("Invalid config, cannot upload\n");
2475 rc = -EINVAL;
2476 goto out;
2477 }
2478 /* Put the SJA1105 in programming mode */
2479 rc = priv->info->reset_cmd(priv);
2480 if (rc < 0) {
2481 printf("Failed to reset switch\n");
2482 goto out;
2483 }
2484 /* Wait for the switch to come out of reset */
2485 udelay(1000);
2486 /* Upload the static config to the device */
2487 rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->config,
2488 config_buf, buf_len);
2489 if (rc < 0) {
2490 printf("Failed to upload config\n");
2491 goto out;
2492 }
2493 /* Check that SJA1105 responded well to the config upload */
2494 rc = sja1105_status_get(priv, &status);
2495 if (rc < 0)
2496 goto out;
2497
2498 if (status.ids == 1) {
2499 printf("Mismatch between hardware and static config device id. "
2500 "Wrote 0x%llx, wants 0x%llx\n",
2501 config->device_id, priv->info->device_id);
2502 rc = -EIO;
2503 goto out;
2504 }
2505 if (status.crcchkl == 1 || status.crcchkg == 1) {
2506 printf("Switch reported invalid CRC on static config\n");
2507 rc = -EIO;
2508 goto out;
2509 }
2510 if (status.configs == 0) {
2511 printf("Switch reported that config is invalid\n");
2512 rc = -EIO;
2513 goto out;
2514 }
2515
2516out:
2517 free(config_buf);
2518 return rc;
2519}
2520
2521static int sja1105_static_config_reload(struct sja1105_private *priv)
2522{
2523 int rc;
2524
2525 rc = sja1105_static_config_upload(priv);
2526 if (rc < 0) {
2527 printf("Failed to load static config: %d\n", rc);
2528 return rc;
2529 }
2530
2531 /* Configure the CGU (PHY link modes and speeds) */
2532 rc = sja1105_clocking_setup(priv);
2533 if (rc < 0) {
2534 printf("Failed to configure MII clocking: %d\n", rc);
2535 return rc;
2536 }
2537
2538 return 0;
2539}
2540
2541static int sja1105_port_probe(struct udevice *dev, int port,
2542 struct phy_device *phy)
2543{
2544 phy_interface_t phy_mode = phy->interface;
2545
2546 if (phy_mode == PHY_INTERFACE_MODE_MII ||
2547 phy_mode == PHY_INTERFACE_MODE_RMII) {
2548 phy->supported &= PHY_BASIC_FEATURES;
2549 phy->advertising &= PHY_BASIC_FEATURES;
2550 } else {
2551 phy->supported &= PHY_GBIT_FEATURES;
2552 phy->advertising &= PHY_GBIT_FEATURES;
2553 }
2554
2555 return phy_config(phy);
2556}
2557
2558static int sja1105_port_enable(struct udevice *dev, int port,
2559 struct phy_device *phy)
2560{
2561 struct sja1105_private *priv = dev_get_priv(dev);
2562 phy_interface_t phy_mode = phy->interface;
2563 struct sja1105_xmii_params_entry *mii;
2564 struct sja1105_mac_config_entry *mac;
2565 int rc;
2566
2567 rc = phy_startup(phy);
2568 if (rc)
2569 return rc;
2570
2571 mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
2572 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
2573
2574 switch (phy_mode) {
2575 case PHY_INTERFACE_MODE_MII:
2576 if (!priv->info->supports_mii[port])
2577 goto unsupported;
2578
2579 mii->xmii_mode[port] = XMII_MODE_MII;
2580 break;
2581 case PHY_INTERFACE_MODE_RMII:
2582 if (!priv->info->supports_rmii[port])
2583 goto unsupported;
2584
2585 mii->xmii_mode[port] = XMII_MODE_RMII;
2586 break;
2587 case PHY_INTERFACE_MODE_RGMII:
2588 case PHY_INTERFACE_MODE_RGMII_ID:
2589 case PHY_INTERFACE_MODE_RGMII_RXID:
2590 case PHY_INTERFACE_MODE_RGMII_TXID:
2591 if (!priv->info->supports_rgmii[port])
2592 goto unsupported;
2593
2594 mii->xmii_mode[port] = XMII_MODE_RGMII;
2595 break;
2596unsupported:
2597 default:
2598 dev_err(dev, "Unsupported PHY mode %d on port %d!\n",
2599 phy_mode, port);
2600 return -EINVAL;
2601 }
2602
2603 /* RevMII, RevRMII not supported */
2604 mii->phy_mac[port] = XMII_MAC;
2605
2606 /* Let the PHY handle the RGMII delays, if present. */
2607 if (phy->phy_id == PHY_FIXED_ID) {
2608 if (phy_mode == PHY_INTERFACE_MODE_RGMII_RXID ||
2609 phy_mode == PHY_INTERFACE_MODE_RGMII_ID)
2610 priv->rgmii_rx_delay[port] = true;
2611
2612 if (phy_mode == PHY_INTERFACE_MODE_RGMII_TXID ||
2613 phy_mode == PHY_INTERFACE_MODE_RGMII_ID)
2614 priv->rgmii_tx_delay[port] = true;
2615
2616 if ((priv->rgmii_rx_delay[port] ||
2617 priv->rgmii_tx_delay[port]) &&
2618 !priv->info->setup_rgmii_delay) {
2619 printf("Chip does not support internal RGMII delays\n");
2620 return -EINVAL;
2621 }
2622 }
2623
2624 if (phy->speed == SPEED_1000) {
2625 mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
2626 } else if (phy->speed == SPEED_100) {
2627 mac[port].speed = priv->info->port_speed[SJA1105_SPEED_100MBPS];
2628 } else if (phy->speed == SPEED_10) {
2629 mac[port].speed = priv->info->port_speed[SJA1105_SPEED_10MBPS];
2630 } else {
2631 printf("Invalid PHY speed %d on port %d\n", phy->speed, port);
2632 return -EINVAL;
2633 }
2634
2635 return sja1105_static_config_reload(priv);
2636}
2637
2638static void sja1105_port_disable(struct udevice *dev, int port,
2639 struct phy_device *phy)
2640{
2641 phy_shutdown(phy);
2642}
2643
2644static int sja1105_xmit(struct udevice *dev, int port, void *packet, int length)
2645{
2646 struct sja1105_private *priv = dev_get_priv(dev);
2647 u8 *from = (u8 *)packet + VLAN_HLEN;
2648 struct vlan_ethhdr *hdr = packet;
2649 u8 *dest = (u8 *)packet;
2650
2651 memmove(dest, from, 2 * ETH_ALEN);
2652 hdr->h_vlan_proto = htons(ETH_P_SJA1105);
2653 hdr->h_vlan_TCI = htons(priv->pvid[port]);
2654
2655 return 0;
2656}
2657
2658static int sja1105_rcv(struct udevice *dev, int *port, void *packet, int length)
2659{
2660 struct vlan_ethhdr *hdr = packet;
2661 u8 *dest = packet + VLAN_HLEN;
2662 u8 *from = packet;
2663
2664 if (ntohs(hdr->h_vlan_proto) != ETH_P_SJA1105)
2665 return -EINVAL;
2666
2667 *port = ntohs(hdr->h_vlan_TCI) & DSA_8021Q_PORT_MASK;
2668 memmove(dest, from, 2 * ETH_ALEN);
2669
2670 return 0;
2671}
2672
2673static const struct dsa_ops sja1105_dsa_ops = {
2674 .port_probe = sja1105_port_probe,
2675 .port_enable = sja1105_port_enable,
2676 .port_disable = sja1105_port_disable,
2677 .xmit = sja1105_xmit,
2678 .rcv = sja1105_rcv,
2679};
2680
2681static int sja1105_init(struct sja1105_private *priv)
2682{
2683 int rc;
2684
2685 rc = sja1105_static_config_init(priv);
2686 if (rc) {
2687 printf("Failed to initialize static config: %d\n", rc);
2688 return rc;
2689 }
2690
2691 return 0;
2692}
2693
2694static int sja1105_check_device_id(struct sja1105_private *priv)
2695{
2696 const struct sja1105_regs *regs = priv->info->regs;
2697 u8 packed_buf[SJA1105_SIZE_DEVICE_ID] = {0};
2698 enum sja1105_switch_id id;
2699 u64 device_id;
2700 u64 part_no;
2701 int rc;
2702
2703 rc = sja1105_xfer_buf(priv, SPI_READ, regs->device_id, packed_buf,
2704 SJA1105_SIZE_DEVICE_ID);
2705 if (rc < 0)
2706 return rc;
2707
2708 sja1105_packing(packed_buf, &device_id, 31, 0, SJA1105_SIZE_DEVICE_ID,
2709 UNPACK);
2710
2711 if (device_id != priv->info->device_id) {
2712 printf("Expected device ID 0x%llx but read 0x%llx\n",
2713 priv->info->device_id, device_id);
2714 return -ENODEV;
2715 }
2716
2717 rc = sja1105_xfer_buf(priv, SPI_READ, regs->prod_id, packed_buf,
2718 SJA1105_SIZE_DEVICE_ID);
2719 if (rc < 0)
2720 return rc;
2721
2722 sja1105_packing(packed_buf, &part_no, 19, 4, SJA1105_SIZE_DEVICE_ID,
2723 UNPACK);
2724
2725 for (id = 0; id < SJA1105_MAX_SWITCH_ID; id++) {
2726 const struct sja1105_info *info = &sja1105_info[id];
2727
2728 /* Is what's been probed in our match table at all? */
2729 if (info->device_id != device_id || info->part_no != part_no)
2730 continue;
2731
2732 /* But is it what's in the device tree? */
2733 if (priv->info->device_id != device_id ||
2734 priv->info->part_no != part_no) {
2735 printf("Device tree specifies chip %s but found %s, please fix it!\n",
2736 priv->info->name, info->name);
2737 /* It isn't. No problem, pick that up. */
2738 priv->info = info;
2739 }
2740
2741 return 0;
2742 }
2743
2744 printf("Unexpected {device ID, part number}: 0x%llx 0x%llx\n",
2745 device_id, part_no);
2746
2747 return -ENODEV;
2748}
2749
2750static int sja1105_probe(struct udevice *dev)
2751{
2752 enum sja1105_switch_id id = dev_get_driver_data(dev);
2753 struct sja1105_private *priv = dev_get_priv(dev);
2754 int rc;
2755
2756 if (ofnode_valid(dev_ofnode(dev)) &&
2757 !ofnode_is_available(dev_ofnode(dev))) {
2758 dev_dbg(dev, "switch disabled\n");
2759 return -ENODEV;
2760 }
2761
2762 priv->info = &sja1105_info[id];
2763 priv->dev = dev;
2764
2765 rc = sja1105_check_device_id(priv);
2766 if (rc < 0) {
2767 dev_err(dev, "Device ID check failed: %d\n", rc);
2768 return rc;
2769 }
2770
2771 dsa_set_tagging(dev, VLAN_HLEN, 0);
2772
2773 return sja1105_init(priv);
2774}
2775
2776static int sja1105_remove(struct udevice *dev)
2777{
2778 struct sja1105_private *priv = dev_get_priv(dev);
2779
2780 sja1105_static_config_free(&priv->static_config);
2781
2782 return 0;
2783}
2784
2785static const struct udevice_id sja1105_ids[] = {
2786 { .compatible = "nxp,sja1105e", .data = SJA1105E },
2787 { .compatible = "nxp,sja1105t", .data = SJA1105T },
2788 { .compatible = "nxp,sja1105p", .data = SJA1105P },
2789 { .compatible = "nxp,sja1105q", .data = SJA1105Q },
2790 { .compatible = "nxp,sja1105r", .data = SJA1105R },
2791 { .compatible = "nxp,sja1105s", .data = SJA1105S },
2792 { .compatible = "nxp,sja1110a", .data = SJA1110A },
2793 { .compatible = "nxp,sja1110b", .data = SJA1110B },
2794 { .compatible = "nxp,sja1110c", .data = SJA1110C },
2795 { .compatible = "nxp,sja1110d", .data = SJA1110D },
2796 { }
2797};
2798
2799U_BOOT_DRIVER(sja1105) = {
2800 .name = "sja1105",
2801 .id = UCLASS_DSA,
2802 .of_match = sja1105_ids,
2803 .probe = sja1105_probe,
2804 .remove = sja1105_remove,
2805 .ops = &sja1105_dsa_ops,
2806 .priv_auto = sizeof(struct sja1105_private),
2807};