2451d4a96490b718d7cfd0a5b634b11227cd6bff
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / mscc / ocelot_board.c
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /*
3  * Microsemi Ocelot Switch driver
4  *
5  * Copyright (c) 2017 Microsemi Corporation
6  */
7 #include <linux/interrupt.h>
8 #include <linux/module.h>
9 #include <linux/of_net.h>
10 #include <linux/netdevice.h>
11 #include <linux/of_mdio.h>
12 #include <linux/of_platform.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/skbuff.h>
15 #include <net/switchdev.h>
16
17 #include "ocelot.h"
18
19 static int ocelot_parse_ifh(u32 *ifh, struct frame_info *info)
20 {
21         int i;
22         u8 llen, wlen;
23
24         /* The IFH is in network order, switch to CPU order */
25         for (i = 0; i < IFH_LEN; i++)
26                 ifh[i] = ntohl((__force __be32)ifh[i]);
27
28         wlen = (ifh[1] >> 7) & 0xff;
29         llen = (ifh[1] >> 15) & 0x3f;
30         info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80;
31
32         info->port = (ifh[2] & GENMASK(14, 11)) >> 11;
33
34         info->cpuq = (ifh[3] & GENMASK(27, 20)) >> 20;
35         info->tag_type = (ifh[3] & BIT(16)) >> 16;
36         info->vid = ifh[3] & GENMASK(11, 0);
37
38         return 0;
39 }
40
41 static int ocelot_rx_frame_word(struct ocelot *ocelot, u8 grp, bool ifh,
42                                 u32 *rval)
43 {
44         u32 val;
45         u32 bytes_valid;
46
47         val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
48         if (val == XTR_NOT_READY) {
49                 if (ifh)
50                         return -EIO;
51
52                 do {
53                         val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
54                 } while (val == XTR_NOT_READY);
55         }
56
57         switch (val) {
58         case XTR_ABORT:
59                 return -EIO;
60         case XTR_EOF_0:
61         case XTR_EOF_1:
62         case XTR_EOF_2:
63         case XTR_EOF_3:
64         case XTR_PRUNED:
65                 bytes_valid = XTR_VALID_BYTES(val);
66                 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
67                 if (val == XTR_ESCAPE)
68                         *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
69                 else
70                         *rval = val;
71
72                 return bytes_valid;
73         case XTR_ESCAPE:
74                 *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
75
76                 return 4;
77         default:
78                 *rval = val;
79
80                 return 4;
81         }
82 }
83
84 static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
85 {
86         struct ocelot *ocelot = arg;
87         int i = 0, grp = 0;
88         int err = 0;
89
90         if (!(ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)))
91                 return IRQ_NONE;
92
93         do {
94                 struct sk_buff *skb;
95                 struct net_device *dev;
96                 u32 *buf;
97                 int sz, len, buf_len;
98                 u32 ifh[4];
99                 u32 val;
100                 struct frame_info info;
101
102                 for (i = 0; i < IFH_LEN; i++) {
103                         err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]);
104                         if (err != 4)
105                                 break;
106                 }
107
108                 if (err != 4)
109                         break;
110
111                 ocelot_parse_ifh(ifh, &info);
112
113                 dev = ocelot->ports[info.port]->dev;
114
115                 skb = netdev_alloc_skb(dev, info.len);
116
117                 if (unlikely(!skb)) {
118                         netdev_err(dev, "Unable to allocate sk_buff\n");
119                         err = -ENOMEM;
120                         break;
121                 }
122                 buf_len = info.len - ETH_FCS_LEN;
123                 buf = (u32 *)skb_put(skb, buf_len);
124
125                 len = 0;
126                 do {
127                         sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
128                         *buf++ = val;
129                         len += sz;
130                 } while (len < buf_len);
131
132                 /* Read the FCS */
133                 sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
134                 /* Update the statistics if part of the FCS was read before */
135                 len -= ETH_FCS_LEN - sz;
136
137                 if (unlikely(dev->features & NETIF_F_RXFCS)) {
138                         buf = (u32 *)skb_put(skb, ETH_FCS_LEN);
139                         *buf = val;
140                 }
141
142                 if (sz < 0) {
143                         err = sz;
144                         break;
145                 }
146
147                 /* Everything we see on an interface that is in the HW bridge
148                  * has already been forwarded.
149                  */
150                 if (ocelot->bridge_mask & BIT(info.port))
151                         skb->offload_fwd_mark = 1;
152
153                 skb->protocol = eth_type_trans(skb, dev);
154                 netif_rx(skb);
155                 dev->stats.rx_bytes += len;
156                 dev->stats.rx_packets++;
157         } while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp));
158
159         if (err)
160                 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp))
161                         ocelot_read_rix(ocelot, QS_XTR_RD, grp);
162
163         return IRQ_HANDLED;
164 }
165
166 static const struct of_device_id mscc_ocelot_match[] = {
167         { .compatible = "mscc,vsc7514-switch" },
168         { }
169 };
170 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
171
172 static int mscc_ocelot_probe(struct platform_device *pdev)
173 {
174         int err, irq;
175         unsigned int i;
176         struct device_node *np = pdev->dev.of_node;
177         struct device_node *ports, *portnp;
178         struct ocelot *ocelot;
179         struct regmap *hsio;
180         u32 val;
181
182         struct {
183                 enum ocelot_target id;
184                 char *name;
185         } res[] = {
186                 { SYS, "sys" },
187                 { REW, "rew" },
188                 { QSYS, "qsys" },
189                 { ANA, "ana" },
190                 { QS, "qs" },
191                 { S2, "s2" },
192         };
193
194         if (!np && !pdev->dev.platform_data)
195                 return -ENODEV;
196
197         ocelot = devm_kzalloc(&pdev->dev, sizeof(*ocelot), GFP_KERNEL);
198         if (!ocelot)
199                 return -ENOMEM;
200
201         platform_set_drvdata(pdev, ocelot);
202         ocelot->dev = &pdev->dev;
203
204         for (i = 0; i < ARRAY_SIZE(res); i++) {
205                 struct regmap *target;
206
207                 target = ocelot_io_platform_init(ocelot, pdev, res[i].name);
208                 if (IS_ERR(target))
209                         return PTR_ERR(target);
210
211                 ocelot->targets[res[i].id] = target;
212         }
213
214         hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
215         if (IS_ERR(hsio)) {
216                 dev_err(&pdev->dev, "missing hsio syscon\n");
217                 return PTR_ERR(hsio);
218         }
219
220         ocelot->targets[HSIO] = hsio;
221
222         err = ocelot_chip_init(ocelot);
223         if (err)
224                 return err;
225
226         irq = platform_get_irq_byname(pdev, "xtr");
227         if (irq < 0)
228                 return -ENODEV;
229
230         err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
231                                         ocelot_xtr_irq_handler, IRQF_ONESHOT,
232                                         "frame extraction", ocelot);
233         if (err)
234                 return err;
235
236         regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
237         regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
238
239         do {
240                 msleep(1);
241                 regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
242                                   &val);
243         } while (val);
244
245         regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
246         regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
247
248         ocelot->num_cpu_ports = 1; /* 1 port on the switch, two groups */
249
250         ports = of_get_child_by_name(np, "ethernet-ports");
251         if (!ports) {
252                 dev_err(&pdev->dev, "no ethernet-ports child node found\n");
253                 return -ENODEV;
254         }
255
256         ocelot->num_phys_ports = of_get_child_count(ports);
257
258         ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
259                                      sizeof(struct ocelot_port *), GFP_KERNEL);
260
261         INIT_LIST_HEAD(&ocelot->multicast);
262         ocelot_init(ocelot);
263
264         for_each_available_child_of_node(ports, portnp) {
265                 struct device_node *phy_node;
266                 struct phy_device *phy;
267                 struct resource *res;
268                 struct phy *serdes;
269                 void __iomem *regs;
270                 char res_name[8];
271                 int phy_mode;
272                 u32 port;
273
274                 if (of_property_read_u32(portnp, "reg", &port))
275                         continue;
276
277                 snprintf(res_name, sizeof(res_name), "port%d", port);
278
279                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
280                                                    res_name);
281                 regs = devm_ioremap_resource(&pdev->dev, res);
282                 if (IS_ERR(regs))
283                         continue;
284
285                 phy_node = of_parse_phandle(portnp, "phy-handle", 0);
286                 if (!phy_node)
287                         continue;
288
289                 phy = of_phy_find_device(phy_node);
290                 if (!phy)
291                         continue;
292
293                 err = ocelot_probe_port(ocelot, port, regs, phy);
294                 if (err) {
295                         of_node_put(portnp);
296                         return err;
297                 }
298
299                 phy_mode = of_get_phy_mode(portnp);
300                 if (phy_mode < 0)
301                         ocelot->ports[port]->phy_mode = PHY_INTERFACE_MODE_NA;
302                 else
303                         ocelot->ports[port]->phy_mode = phy_mode;
304
305                 switch (ocelot->ports[port]->phy_mode) {
306                 case PHY_INTERFACE_MODE_NA:
307                         continue;
308                 case PHY_INTERFACE_MODE_SGMII:
309                         break;
310                 case PHY_INTERFACE_MODE_QSGMII:
311                         /* Ensure clock signals and speed is set on all
312                          * QSGMII links
313                          */
314                         ocelot_port_writel(ocelot->ports[port],
315                                            DEV_CLOCK_CFG_LINK_SPEED
316                                            (OCELOT_SPEED_1000),
317                                            DEV_CLOCK_CFG);
318                         break;
319                 default:
320                         dev_err(ocelot->dev,
321                                 "invalid phy mode for port%d, (Q)SGMII only\n",
322                                 port);
323                         of_node_put(portnp);
324                         return -EINVAL;
325                 }
326
327                 serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
328                 if (IS_ERR(serdes)) {
329                         err = PTR_ERR(serdes);
330                         if (err == -EPROBE_DEFER)
331                                 dev_dbg(ocelot->dev, "deferring probe\n");
332                         else
333                                 dev_err(ocelot->dev,
334                                         "missing SerDes phys for port%d\n",
335                                         port);
336
337                         goto err_probe_ports;
338                 }
339
340                 ocelot->ports[port]->serdes = serdes;
341         }
342
343         register_netdevice_notifier(&ocelot_netdevice_nb);
344         register_switchdev_notifier(&ocelot_switchdev_nb);
345         register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
346
347         dev_info(&pdev->dev, "Ocelot switch probed\n");
348
349         return 0;
350
351 err_probe_ports:
352         return err;
353 }
354
355 static int mscc_ocelot_remove(struct platform_device *pdev)
356 {
357         struct ocelot *ocelot = platform_get_drvdata(pdev);
358
359         ocelot_deinit(ocelot);
360         unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
361         unregister_switchdev_notifier(&ocelot_switchdev_nb);
362         unregister_netdevice_notifier(&ocelot_netdevice_nb);
363
364         return 0;
365 }
366
367 static struct platform_driver mscc_ocelot_driver = {
368         .probe = mscc_ocelot_probe,
369         .remove = mscc_ocelot_remove,
370         .driver = {
371                 .name = "ocelot-switch",
372                 .of_match_table = mscc_ocelot_match,
373         },
374 };
375
376 module_platform_driver(mscc_ocelot_driver);
377
378 MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
379 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
380 MODULE_LICENSE("Dual MIT/GPL");