9fed26cd94b726233b0724a3a3d7148d1e9db1b1
[platform/kernel/u-boot.git] / drivers / net / ocelot_switch.c
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2018 Microsemi Corporation
4  */
5
6 #include <common.h>
7 #include <config.h>
8 #include <dm.h>
9 #include <dm/of_access.h>
10 #include <dm/of_addr.h>
11 #include <fdt_support.h>
12 #include <linux/io.h>
13 #include <linux/ioport.h>
14 #include <miiphy.h>
15 #include <net.h>
16 #include <wait_bit.h>
17
18 #define MIIM_STATUS                     0x0
19 #define         MIIM_STAT_BUSY                  BIT(3)
20 #define MIIM_CMD                        0x8
21 #define         MIIM_CMD_SCAN           BIT(0)
22 #define         MIIM_CMD_OPR_WRITE      BIT(1)
23 #define         MIIM_CMD_OPR_READ       BIT(2)
24 #define         MIIM_CMD_SINGLE_SCAN    BIT(3)
25 #define         MIIM_CMD_WRDATA(x)      ((x) << 4)
26 #define         MIIM_CMD_REGAD(x)       ((x) << 20)
27 #define         MIIM_CMD_PHYAD(x)       ((x) << 25)
28 #define         MIIM_CMD_VLD            BIT(31)
29 #define MIIM_DATA                       0xC
30 #define         MIIM_DATA_ERROR         (0x2 << 16)
31
32 #define PHY_CFG                         0x0
33 #define PHY_CFG_ENA                             0xF
34 #define PHY_CFG_COMMON_RST                      BIT(4)
35 #define PHY_CFG_RST                             (0xF << 5)
36 #define PHY_STAT                        0x4
37 #define PHY_STAT_SUPERVISOR_COMPLETE            BIT(0)
38
39 #define ANA_PORT_VLAN_CFG(x)            (0x7000 + 0x100 * (x))
40 #define         ANA_PORT_VLAN_CFG_AWARE_ENA     BIT(20)
41 #define         ANA_PORT_VLAN_CFG_POP_CNT(x)    ((x) << 18)
42 #define ANA_PORT_PORT_CFG(x)            (0x7070 + 0x100 * (x))
43 #define         ANA_PORT_PORT_CFG_RECV_ENA      BIT(6)
44 #define ANA_TABLES_MACHDATA             0x8b34
45 #define ANA_TABLES_MACLDATA             0x8b38
46 #define ANA_TABLES_MACACCESS            0x8b3c
47 #define         ANA_TABLES_MACACCESS_VALID      BIT(11)
48 #define         ANA_TABLES_MACACCESS_ENTRYTYPE(x)   ((x) << 9)
49 #define         ANA_TABLES_MACACCESS_DEST_IDX(x)    ((x) << 3)
50 #define         ANA_TABLES_MACACCESS_MAC_TABLE_CMD(x)   (x)
51 #define         ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M    GENMASK(2, 0)
52 #define         MACACCESS_CMD_IDLE                     0
53 #define         MACACCESS_CMD_LEARN                    1
54 #define         MACACCESS_CMD_GET_NEXT                 4
55 #define ANA_PGID(x)                     (0x8c00 + 4 * (x))
56
57 #define SYS_FRM_AGING                   0x574
58 #define         SYS_FRM_AGING_ENA               BIT(20)
59
60 #define SYS_SYSTEM_RST_CFG              0x508
61 #define         SYS_SYSTEM_RST_MEM_INIT         BIT(0)
62 #define         SYS_SYSTEM_RST_MEM_ENA          BIT(1)
63 #define         SYS_SYSTEM_RST_CORE_ENA         BIT(2)
64 #define SYS_PORT_MODE(x)                (0x514 + 0x4 * (x))
65 #define         SYS_PORT_MODE_INCL_INJ_HDR(x)   ((x) << 3)
66 #define         SYS_PORT_MODE_INCL_INJ_HDR_M    GENMASK(4, 3)
67 #define         SYS_PORT_MODE_INCL_XTR_HDR(x)   ((x) << 1)
68 #define         SYS_PORT_MODE_INCL_XTR_HDR_M    GENMASK(2, 1)
69 #define SYS_PAUSE_CFG(x)                (0x608 + 0x4 * (x))
70 #define         SYS_PAUSE_CFG_PAUSE_ENA         BIT(0)
71
72 #define QSYS_SWITCH_PORT_MODE(x)        (0x11234 + 0x4 * (x))
73 #define         QSYS_SWITCH_PORT_MODE_PORT_ENA  BIT(14)
74 #define QSYS_QMAP                       0x112d8
75 #define QSYS_EGR_NO_SHARING             0x1129c
76
77 /* Port registers */
78 #define DEV_CLOCK_CFG                   0x0
79 #define DEV_CLOCK_CFG_LINK_SPEED_1000           1
80 #define DEV_MAC_ENA_CFG                 0x1c
81 #define         DEV_MAC_ENA_CFG_RX_ENA          BIT(4)
82 #define         DEV_MAC_ENA_CFG_TX_ENA          BIT(0)
83
84 #define DEV_MAC_IFG_CFG                 0x30
85 #define         DEV_MAC_IFG_CFG_TX_IFG(x)       ((x) << 8)
86 #define         DEV_MAC_IFG_CFG_RX_IFG2(x)      ((x) << 4)
87 #define         DEV_MAC_IFG_CFG_RX_IFG1(x)      (x)
88
89 #define PCS1G_CFG                       0x48
90 #define         PCS1G_MODE_CFG_SGMII_MODE_ENA   BIT(0)
91 #define PCS1G_MODE_CFG                  0x4c
92 #define         PCS1G_MODE_CFG_UNIDIR_MODE_ENA  BIT(4)
93 #define         PCS1G_MODE_CFG_SGMII_MODE_ENA   BIT(0)
94 #define PCS1G_SD_CFG                    0x50
95 #define PCS1G_ANEG_CFG                  0x54
96 #define         PCS1G_ANEG_CFG_ADV_ABILITY(x)   ((x) << 16)
97
98 #define QS_XTR_GRP_CFG(x)               (4 * (x))
99 #define QS_XTR_GRP_CFG_MODE(x)                  ((x) << 2)
100 #define         QS_XTR_GRP_CFG_STATUS_WORD_POS  BIT(1)
101 #define         QS_XTR_GRP_CFG_BYTE_SWAP        BIT(0)
102 #define QS_XTR_RD(x)                    (0x8 + 4 * (x))
103 #define QS_XTR_FLUSH                    0x18
104 #define         QS_XTR_FLUSH_FLUSH              GENMASK(1, 0)
105 #define QS_XTR_DATA_PRESENT             0x1c
106 #define QS_INJ_GRP_CFG(x)               (0x24 + (x) * 4)
107 #define         QS_INJ_GRP_CFG_MODE(x)          ((x) << 2)
108 #define         QS_INJ_GRP_CFG_BYTE_SWAP        BIT(0)
109 #define QS_INJ_WR(x)                    (0x2c + 4 * (x))
110 #define QS_INJ_CTRL(x)                  (0x34 + 4 * (x))
111 #define         QS_INJ_CTRL_GAP_SIZE(x)         ((x) << 21)
112 #define         QS_INJ_CTRL_EOF                 BIT(19)
113 #define         QS_INJ_CTRL_SOF                 BIT(18)
114 #define         QS_INJ_CTRL_VLD_BYTES(x)        ((x) << 16)
115
116 #define XTR_EOF_0     ntohl(0x80000000u)
117 #define XTR_EOF_1     ntohl(0x80000001u)
118 #define XTR_EOF_2     ntohl(0x80000002u)
119 #define XTR_EOF_3     ntohl(0x80000003u)
120 #define XTR_PRUNED    ntohl(0x80000004u)
121 #define XTR_ABORT     ntohl(0x80000005u)
122 #define XTR_ESCAPE    ntohl(0x80000006u)
123 #define XTR_NOT_READY ntohl(0x80000007u)
124
125 #define IFH_INJ_BYPASS          BIT(31)
126 #define IFH_TAG_TYPE_C          0
127 #define XTR_VALID_BYTES(x)      (4 - ((x) & 3))
128 #define MAC_VID                 1
129 #define CPU_PORT                11
130 #define INTERNAL_PORT_MSK       0xF
131 #define IFH_LEN                 4
132 #define OCELOT_BUF_CELL_SZ      60
133 #define ETH_ALEN                6
134 #define PGID_BROADCAST          13
135 #define PGID_UNICAST            14
136 #define PGID_SRC                80
137
138 enum ocelot_target {
139         ANA,
140         QS,
141         QSYS,
142         REW,
143         SYS,
144         HSIO,
145         PORT0,
146         PORT1,
147         PORT2,
148         PORT3,
149         TARGET_MAX,
150 };
151
152 #define MAX_PORT (PORT3 - PORT0)
153
154 /* MAC table entry types.
155  * ENTRYTYPE_NORMAL is subject to aging.
156  * ENTRYTYPE_LOCKED is not subject to aging.
157  * ENTRYTYPE_MACv4 is not subject to aging. For IPv4 multicast.
158  * ENTRYTYPE_MACv6 is not subject to aging. For IPv6 multicast.
159  */
160 enum macaccess_entry_type {
161         ENTRYTYPE_NORMAL = 0,
162         ENTRYTYPE_LOCKED,
163         ENTRYTYPE_MACv4,
164         ENTRYTYPE_MACv6,
165 };
166
167 enum ocelot_mdio_target {
168         MIIM,
169         PHY,
170         TARGET_MDIO_MAX,
171 };
172
173 enum ocelot_phy_id {
174         INTERNAL,
175         EXTERNAL,
176         NUM_PHY,
177 };
178
179 struct ocelot_private {
180         void __iomem *regs[TARGET_MAX];
181
182         struct mii_dev *bus[NUM_PHY];
183         struct phy_device *phydev;
184         int phy_mode;
185         int max_speed;
186
187         int rx_pos;
188         int rx_siz;
189         int rx_off;
190         int tx_num;
191
192         u8 tx_adj_packetbuf[PKTSIZE_ALIGN + PKTALIGN];
193         void *tx_adj_buf;
194 };
195
196 struct mscc_miim_dev {
197         void __iomem *regs;
198         void __iomem *phy_regs;
199 };
200
201 struct mscc_miim_dev miim[NUM_PHY];
202
203 static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
204 {
205         return wait_for_bit_le32(miim->regs + MIIM_STATUS, MIIM_STAT_BUSY,
206                                  false, 250, false);
207 }
208
209 static int mscc_miim_reset(struct mii_dev *bus)
210 {
211         struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
212
213         if (miim->phy_regs) {
214                 writel(0, miim->phy_regs + PHY_CFG);
215                 writel(PHY_CFG_RST | PHY_CFG_COMMON_RST
216                        | PHY_CFG_ENA, miim->phy_regs + PHY_CFG);
217                 mdelay(500);
218         }
219
220         return 0;
221 }
222
223 static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
224 {
225         struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
226         u32 val;
227         int ret;
228
229         ret = mscc_miim_wait_ready(miim);
230         if (ret)
231                 goto out;
232
233         writel(MIIM_CMD_VLD | MIIM_CMD_PHYAD(addr) |
234                MIIM_CMD_REGAD(reg) | MIIM_CMD_OPR_READ,
235                miim->regs + MIIM_CMD);
236
237         ret = mscc_miim_wait_ready(miim);
238         if (ret)
239                 goto out;
240
241         val = readl(miim->regs + MIIM_DATA);
242         if (val & MIIM_DATA_ERROR) {
243                 ret = -EIO;
244                 goto out;
245         }
246
247         ret = val & 0xFFFF;
248  out:
249         return ret;
250 }
251
252 static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
253                            u16 val)
254 {
255         struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
256         int ret;
257
258         ret = mscc_miim_wait_ready(miim);
259         if (ret < 0)
260                 goto out;
261
262         writel(MIIM_CMD_VLD | MIIM_CMD_PHYAD(addr) |
263                MIIM_CMD_REGAD(reg) | MIIM_CMD_WRDATA(val) |
264                MIIM_CMD_OPR_WRITE, miim->regs + MIIM_CMD);
265  out:
266         return ret;
267 }
268
269 /* For now only setup the internal mdio bus */
270 static struct mii_dev *ocelot_mdiobus_init(struct udevice *dev)
271 {
272         unsigned long phy_size[TARGET_MAX];
273         phys_addr_t phy_base[TARGET_MAX];
274         struct ofnode_phandle_args phandle;
275         ofnode eth_node, node, mdio_node;
276         struct resource res;
277         struct mii_dev *bus;
278         fdt32_t faddr;
279         int i;
280
281         bus = mdio_alloc();
282
283         if (!bus)
284                 return NULL;
285
286         /* gathered only the first mdio bus */
287         eth_node = dev_read_first_subnode(dev);
288         node = ofnode_first_subnode(eth_node);
289         ofnode_parse_phandle_with_args(node, "phy-handle", NULL, 0, 0,
290                                        &phandle);
291         mdio_node = ofnode_get_parent(phandle.node);
292
293         for (i = 0; i < TARGET_MDIO_MAX; i++) {
294                 if (ofnode_read_resource(mdio_node, i, &res)) {
295                         pr_err("%s: get OF resource failed\n", __func__);
296                         return NULL;
297                 }
298                 faddr = cpu_to_fdt32(res.start);
299                 phy_base[i] = ofnode_translate_address(mdio_node, &faddr);
300                 phy_size[i] = res.end - res.start;
301         }
302
303         strcpy(bus->name, "miim-internal");
304         miim[INTERNAL].phy_regs = ioremap(phy_base[PHY], phy_size[PHY]);
305         miim[INTERNAL].regs = ioremap(phy_base[MIIM], phy_size[MIIM]);
306         bus->priv = &miim[INTERNAL];
307         bus->reset = mscc_miim_reset;
308         bus->read = mscc_miim_read;
309         bus->write = mscc_miim_write;
310
311         if (mdio_register(bus))
312                 return NULL;
313         else
314                 return bus;
315 }
316
317 __weak void mscc_switch_reset(void)
318 {
319 }
320
321 static void ocelot_stop(struct udevice *dev)
322 {
323         struct ocelot_private *priv = dev_get_priv(dev);
324         int i;
325
326         mscc_switch_reset();
327         for (i = 0; i < NUM_PHY; i++)
328                 if (priv->bus[i])
329                         mscc_miim_reset(priv->bus[i]);
330 }
331
332 static void ocelot_cpu_capture_setup(struct ocelot_private *priv)
333 {
334         int i;
335
336         /* map the 8 CPU extraction queues to CPU port 11 */
337         writel(0, priv->regs[QSYS] + QSYS_QMAP);
338
339         for (i = 0; i <= 1; i++) {
340                 /*
341                  * Do byte-swap and expect status after last data word
342                  * Extraction: Mode: manual extraction) | Byte_swap
343                  */
344                 writel(QS_XTR_GRP_CFG_MODE(1) | QS_XTR_GRP_CFG_BYTE_SWAP,
345                        priv->regs[QS] + QS_XTR_GRP_CFG(i));
346                 /*
347                  * Injection: Mode: manual extraction | Byte_swap
348                  */
349                 writel(QS_INJ_GRP_CFG_MODE(1) | QS_INJ_GRP_CFG_BYTE_SWAP,
350                        priv->regs[QS] + QS_INJ_GRP_CFG(i));
351         }
352
353         for (i = 0; i <= 1; i++)
354                 /* Enable IFH insertion/parsing on CPU ports */
355                 writel(SYS_PORT_MODE_INCL_INJ_HDR(1) |
356                        SYS_PORT_MODE_INCL_XTR_HDR(1),
357                        priv->regs[SYS] + SYS_PORT_MODE(CPU_PORT + i));
358         /*
359          * Setup the CPU port as VLAN aware to support switching frames
360          * based on tags
361          */
362         writel(ANA_PORT_VLAN_CFG_AWARE_ENA | ANA_PORT_VLAN_CFG_POP_CNT(1) |
363                MAC_VID, priv->regs[ANA] + ANA_PORT_VLAN_CFG(CPU_PORT));
364
365         /* Disable learning (only RECV_ENA must be set) */
366         writel(ANA_PORT_PORT_CFG_RECV_ENA,
367                priv->regs[ANA] + ANA_PORT_PORT_CFG(CPU_PORT));
368
369         /* Enable switching to/from cpu port */
370         setbits_le32(priv->regs[QSYS] + QSYS_SWITCH_PORT_MODE(CPU_PORT),
371                      QSYS_SWITCH_PORT_MODE_PORT_ENA);
372
373         /* No pause on CPU port - not needed (off by default) */
374         clrbits_le32(priv->regs[SYS] + SYS_PAUSE_CFG(CPU_PORT),
375                      SYS_PAUSE_CFG_PAUSE_ENA);
376
377         setbits_le32(priv->regs[QSYS] + QSYS_EGR_NO_SHARING, BIT(CPU_PORT));
378 }
379
380 static void ocelot_port_init(struct ocelot_private *priv, int port)
381 {
382         void __iomem *regs = priv->regs[port];
383
384         /* Enable PCS */
385         writel(PCS1G_MODE_CFG_SGMII_MODE_ENA, regs + PCS1G_CFG);
386
387         /* Disable Signal Detect */
388         writel(0, regs + PCS1G_SD_CFG);
389
390         /* Enable MAC RX and TX */
391         writel(DEV_MAC_ENA_CFG_RX_ENA | DEV_MAC_ENA_CFG_TX_ENA,
392                regs + DEV_MAC_ENA_CFG);
393
394         /* Clear sgmii_mode_ena */
395         writel(0, regs + PCS1G_MODE_CFG);
396
397         /*
398          * Clear sw_resolve_ena(bit 0) and set adv_ability to
399          * something meaningful just in case
400          */
401         writel(PCS1G_ANEG_CFG_ADV_ABILITY(0x20), regs + PCS1G_ANEG_CFG);
402
403         /* Set MAC IFG Gaps */
404         writel(DEV_MAC_IFG_CFG_TX_IFG(5) | DEV_MAC_IFG_CFG_RX_IFG1(5) |
405                DEV_MAC_IFG_CFG_RX_IFG2(1), regs + DEV_MAC_IFG_CFG);
406
407         /* Set link speed and release all resets */
408         writel(DEV_CLOCK_CFG_LINK_SPEED_1000, regs + DEV_CLOCK_CFG);
409
410         /* Make VLAN aware for CPU traffic */
411         writel(ANA_PORT_VLAN_CFG_AWARE_ENA | ANA_PORT_VLAN_CFG_POP_CNT(1) |
412                MAC_VID, priv->regs[ANA] + ANA_PORT_VLAN_CFG(port - PORT0));
413
414         /* Enable the port in the core */
415         setbits_le32(priv->regs[QSYS] + QSYS_SWITCH_PORT_MODE(port - PORT0),
416                      QSYS_SWITCH_PORT_MODE_PORT_ENA);
417 }
418
419 static int ocelot_switch_init(struct ocelot_private *priv)
420 {
421         /* Reset switch & memories */
422         writel(SYS_SYSTEM_RST_MEM_ENA | SYS_SYSTEM_RST_MEM_INIT,
423                priv->regs[SYS] + SYS_SYSTEM_RST_CFG);
424
425         /* Wait to complete */
426         if (wait_for_bit_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG,
427                               SYS_SYSTEM_RST_MEM_INIT, false, 2000, false)) {
428                 pr_err("Timeout in memory reset\n");
429                 return -EIO;
430         }
431
432         /* Enable switch core */
433         setbits_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG,
434                      SYS_SYSTEM_RST_CORE_ENA);
435
436         return 0;
437 }
438
439 static void ocelot_switch_flush(struct ocelot_private *priv)
440 {
441         /* All Queues flush */
442         setbits_le32(priv->regs[QS] + QS_XTR_FLUSH, QS_XTR_FLUSH_FLUSH);
443         /* Allow to drain */
444         mdelay(1);
445         /* All Queues normal */
446         clrbits_le32(priv->regs[QS] + QS_XTR_FLUSH, QS_XTR_FLUSH_FLUSH);
447 }
448
449 static int ocelot_initialize(struct ocelot_private *priv)
450 {
451         int ret, i;
452
453         /* Initialize switch memories, enable core */
454         ret = ocelot_switch_init(priv);
455         if (ret)
456                 return ret;
457         /*
458          * Disable port-to-port by switching
459          * Put fron ports in "port isolation modes" - i.e. they cant send
460          * to other ports - via the PGID sorce masks.
461          */
462         for (i = 0; i <= MAX_PORT; i++)
463                 writel(0, priv->regs[ANA] + ANA_PGID(PGID_SRC + i));
464
465         /* Flush queues */
466         ocelot_switch_flush(priv);
467
468         /* Setup frame ageing - "2 sec" - The unit is 6.5us on Ocelot */
469         writel(SYS_FRM_AGING_ENA | (20000000 / 65),
470                priv->regs[SYS] + SYS_FRM_AGING);
471
472         for (i = PORT0; i <= PORT3; i++)
473                 ocelot_port_init(priv, i);
474
475         ocelot_cpu_capture_setup(priv);
476
477         debug("Ports enabled\n");
478
479         return 0;
480 }
481
482 static inline int ocelot_vlant_wait_for_completion(struct ocelot_private *priv)
483 {
484         unsigned int val, timeout = 10;
485
486         /* Wait for the issued mac table command to be completed, or timeout.
487          * When the command read from ANA_TABLES_MACACCESS is
488          * MACACCESS_CMD_IDLE, the issued command completed successfully.
489          */
490         do {
491                 val = readl(priv->regs[ANA] + ANA_TABLES_MACACCESS);
492                 val &= ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M;
493         } while (val != MACACCESS_CMD_IDLE && timeout--);
494
495         if (!timeout)
496                 return -ETIMEDOUT;
497
498         return 0;
499 }
500
501 static int ocelot_mac_table_add(struct ocelot_private *priv,
502                                 const unsigned char mac[ETH_ALEN], int pgid)
503 {
504         u32 macl = 0, mach = 0;
505         int ret;
506
507         /* Set the MAC address to handle and the vlan associated in a format
508          * understood by the hardware.
509          */
510         mach |= MAC_VID << 16;
511         mach |= ((u32)mac[0]) << 8;
512         mach |= ((u32)mac[1]) << 0;
513         macl |= ((u32)mac[2]) << 24;
514         macl |= ((u32)mac[3]) << 16;
515         macl |= ((u32)mac[4]) << 8;
516         macl |= ((u32)mac[5]) << 0;
517
518         writel(macl, priv->regs[ANA] + ANA_TABLES_MACLDATA);
519         writel(mach, priv->regs[ANA] + ANA_TABLES_MACHDATA);
520
521         writel(ANA_TABLES_MACACCESS_VALID |
522                ANA_TABLES_MACACCESS_DEST_IDX(pgid) |
523                ANA_TABLES_MACACCESS_ENTRYTYPE(ENTRYTYPE_LOCKED) |
524                ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN),
525                priv->regs[ANA] + ANA_TABLES_MACACCESS);
526
527         ret = ocelot_vlant_wait_for_completion(priv);
528
529         return ret;
530 }
531
532 static int ocelot_write_hwaddr(struct udevice *dev)
533 {
534         struct ocelot_private *priv = dev_get_priv(dev);
535         struct eth_pdata *pdata = dev_get_platdata(dev);
536
537         ocelot_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
538
539         writel(BIT(CPU_PORT), priv->regs[ANA] + ANA_PGID(PGID_UNICAST));
540
541         return 0;
542 }
543
544 static int ocelot_start(struct udevice *dev)
545 {
546         struct ocelot_private *priv = dev_get_priv(dev);
547         struct eth_pdata *pdata = dev_get_platdata(dev);
548         const unsigned char mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff,
549                                               0xff };
550         int ret;
551
552         ret = ocelot_initialize(priv);
553         if (ret)
554                 return ret;
555
556         /* Set MAC address tables entries for CPU redirection */
557         ocelot_mac_table_add(priv, mac, PGID_BROADCAST);
558
559         writel(BIT(CPU_PORT) | INTERNAL_PORT_MSK,
560                priv->regs[ANA] + ANA_PGID(PGID_BROADCAST));
561
562         /* It should be setup latter in ocelot_write_hwaddr */
563         ocelot_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
564
565         writel(BIT(CPU_PORT), priv->regs[ANA] + ANA_PGID(PGID_UNICAST));
566
567         return 0;
568 }
569
570 static int ocelot_send(struct udevice *dev, void *packet, int length)
571 {
572         struct ocelot_private *priv = dev_get_priv(dev);
573         u32 ifh[IFH_LEN];
574         int port = BIT(0);      /* use port 0 */
575         u8 grp = 0;             /* Send everything on CPU group 0 */
576         int i, count = (length + 3) / 4, last = length % 4;
577         u32 *buf = packet;
578
579         writel(QS_INJ_CTRL_GAP_SIZE(1) | QS_INJ_CTRL_SOF,
580                priv->regs[QS] + QS_INJ_CTRL(grp));
581
582         /*
583          * Generate the IFH for frame injection
584          *
585          * The IFH is a 128bit-value
586          * bit 127: bypass the analyzer processing
587          * bit 56-67: destination mask
588          * bit 28-29: pop_cnt: 3 disables all rewriting of the frame
589          * bit 20-27: cpu extraction queue mask
590          * bit 16: tag type 0: C-tag, 1: S-tag
591          * bit 0-11: VID
592          */
593         ifh[0] = IFH_INJ_BYPASS;
594         ifh[1] = (0xf00 & port) >> 8;
595         ifh[2] = (0xff & port) << 24;
596         ifh[3] = (IFH_TAG_TYPE_C << 16);
597
598         for (i = 0; i < IFH_LEN; i++)
599                 writel(ifh[i], priv->regs[QS] + QS_INJ_WR(grp));
600
601         for (i = 0; i < count; i++)
602                 writel(buf[i], priv->regs[QS] + QS_INJ_WR(grp));
603
604         /* Add padding */
605         while (i < (OCELOT_BUF_CELL_SZ / 4)) {
606                 writel(0, priv->regs[QS] + QS_INJ_WR(grp));
607                 i++;
608         }
609
610         /* Indicate EOF and valid bytes in last word */
611         writel(QS_INJ_CTRL_GAP_SIZE(1) |
612                QS_INJ_CTRL_VLD_BYTES(length < OCELOT_BUF_CELL_SZ ? 0 : last) |
613                QS_INJ_CTRL_EOF, priv->regs[QS] + QS_INJ_CTRL(grp));
614
615         /* Add dummy CRC */
616         writel(0, priv->regs[QS] + QS_INJ_WR(grp));
617
618         return 0;
619 }
620
621 static int ocelot_recv(struct udevice *dev, int flags, uchar **packetp)
622 {
623         struct ocelot_private *priv = dev_get_priv(dev);
624         u8 grp = 0;             /* Send everything on CPU group 0 */
625         u32 *rxbuf = (u32 *)net_rx_packets[0];
626         int i, byte_cnt = 0;
627         bool eof_flag = false, pruned_flag = false, abort_flag = false;
628
629         if (!(readl(priv->regs[QS] + QS_XTR_DATA_PRESENT) & BIT(grp)))
630                 return -EAGAIN;
631
632         /* skip IFH */
633         for (i = 0; i < IFH_LEN; i++)
634                 readl(priv->regs[QS] + QS_XTR_RD(grp));
635
636         while (!eof_flag) {
637                 u32 val = readl(priv->regs[QS] + QS_XTR_RD(grp));
638
639                 switch (val) {
640                 case XTR_NOT_READY:
641                         debug("%d NOT_READY...?\n", byte_cnt);
642                         break;
643                 case XTR_ABORT:
644                         /* really nedeed?? not done in linux */
645                         *rxbuf = readl(priv->regs[QS] + QS_XTR_RD(grp));
646                         abort_flag = true;
647                         eof_flag = true;
648                         debug("XTR_ABORT\n");
649                         break;
650                 case XTR_EOF_0:
651                 case XTR_EOF_1:
652                 case XTR_EOF_2:
653                 case XTR_EOF_3:
654                         byte_cnt += XTR_VALID_BYTES(val);
655                         *rxbuf = readl(priv->regs[QS] + QS_XTR_RD(grp));
656                         eof_flag = true;
657                         debug("EOF\n");
658                         break;
659                 case XTR_PRUNED:
660                         /* But get the last 4 bytes as well */
661                         eof_flag = true;
662                         pruned_flag = true;
663                         debug("PRUNED\n");
664                         /* fallthrough */
665                 case XTR_ESCAPE:
666                         *rxbuf = readl(priv->regs[QS] + QS_XTR_RD(grp));
667                         byte_cnt += 4;
668                         rxbuf++;
669                         debug("ESCAPED\n");
670                         break;
671                 default:
672                         *rxbuf = val;
673                         byte_cnt += 4;
674                         rxbuf++;
675                 }
676         }
677
678         if (abort_flag || pruned_flag || !eof_flag) {
679                 debug("Discarded frame: abort:%d pruned:%d eof:%d\n",
680                       abort_flag, pruned_flag, eof_flag);
681                 return -EAGAIN;
682         }
683
684         *packetp = net_rx_packets[0];
685
686         return byte_cnt;
687 }
688
689 static int ocelot_probe(struct udevice *dev)
690 {
691         struct ocelot_private *priv = dev_get_priv(dev);
692         int ret, i;
693
694         struct {
695                 enum ocelot_target id;
696                 char *name;
697         } reg[] = {
698                 { SYS, "sys" },
699                 { REW, "rew" },
700                 { QSYS, "qsys" },
701                 { ANA, "ana" },
702                 { QS, "qs" },
703                 { HSIO, "hsio" },
704                 { PORT0, "port0" },
705                 { PORT1, "port1" },
706                 { PORT2, "port2" },
707                 { PORT3, "port3" },
708         };
709
710         for (i = 0; i < ARRAY_SIZE(reg); i++) {
711                 priv->regs[reg[i].id] = dev_remap_addr_name(dev, reg[i].name);
712                 if (!priv->regs[reg[i].id]) {
713                         pr_err
714                             ("Error %d: can't get regs base addresses for %s\n",
715                              ret, reg[i].name);
716                         return -ENOMEM;
717                 }
718         }
719
720         priv->bus[INTERNAL] = ocelot_mdiobus_init(dev);
721
722         for (i = 0; i < 4; i++) {
723                 phy_connect(priv->bus[INTERNAL], i, dev,
724                             PHY_INTERFACE_MODE_NONE);
725         }
726
727         return 0;
728 }
729
730 static int ocelot_remove(struct udevice *dev)
731 {
732         struct ocelot_private *priv = dev_get_priv(dev);
733         int i;
734
735         for (i = 0; i < NUM_PHY; i++) {
736                 mdio_unregister(priv->bus[i]);
737                 mdio_free(priv->bus[i]);
738         }
739
740         return 0;
741 }
742
743 static const struct eth_ops ocelot_ops = {
744         .start        = ocelot_start,
745         .stop         = ocelot_stop,
746         .send         = ocelot_send,
747         .recv         = ocelot_recv,
748         .write_hwaddr = ocelot_write_hwaddr,
749 };
750
751 static const struct udevice_id mscc_ocelot_ids[] = {
752         {.compatible = "mscc,vsc7514-switch"},
753         { /* Sentinel */ }
754 };
755
756 U_BOOT_DRIVER(ocelot) = {
757         .name     = "ocelot-switch",
758         .id       = UCLASS_ETH,
759         .of_match = mscc_ocelot_ids,
760         .probe    = ocelot_probe,
761         .remove   = ocelot_remove,
762         .ops      = &ocelot_ops,
763         .priv_auto_alloc_size = sizeof(struct ocelot_private),
764         .platdata_auto_alloc_size = sizeof(struct eth_pdata),
765 };