GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / net / ethernet / mscc / ocelot_vsc7514.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/dsa/ocelot.h>
8 #include <linux/interrupt.h>
9 #include <linux/module.h>
10 #include <linux/of_net.h>
11 #include <linux/netdevice.h>
12 #include <linux/phylink.h>
13 #include <linux/of.h>
14 #include <linux/of_mdio.h>
15 #include <linux/platform_device.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/skbuff.h>
18 #include <net/switchdev.h>
19
20 #include <soc/mscc/ocelot.h>
21 #include <soc/mscc/ocelot_vcap.h>
22 #include <soc/mscc/vsc7514_regs.h>
23 #include "ocelot_fdma.h"
24 #include "ocelot.h"
25
26 #define VSC7514_VCAP_POLICER_BASE                       128
27 #define VSC7514_VCAP_POLICER_MAX                        191
28
29 static int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops)
30 {
31         int ret;
32
33         ocelot->map = vsc7514_regmap;
34         ocelot->num_mact_rows = 1024;
35         ocelot->ops = ops;
36
37         ret = ocelot_regfields_init(ocelot, vsc7514_regfields);
38         if (ret)
39                 return ret;
40
41         ocelot_pll5_init(ocelot);
42
43         eth_random_addr(ocelot->base_mac);
44         ocelot->base_mac[5] &= 0xf0;
45
46         return 0;
47 }
48
49 static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
50 {
51         struct ocelot *ocelot = arg;
52         int grp = 0, err;
53
54         while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)) {
55                 struct sk_buff *skb;
56
57                 err = ocelot_xtr_poll_frame(ocelot, grp, &skb);
58                 if (err)
59                         goto out;
60
61                 skb->dev->stats.rx_bytes += skb->len;
62                 skb->dev->stats.rx_packets++;
63
64                 if (!skb_defer_rx_timestamp(skb))
65                         netif_rx(skb);
66         }
67
68 out:
69         if (err < 0)
70                 ocelot_drain_cpu_queue(ocelot, 0);
71
72         return IRQ_HANDLED;
73 }
74
75 static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
76 {
77         struct ocelot *ocelot = arg;
78
79         ocelot_get_txtstamp(ocelot);
80
81         return IRQ_HANDLED;
82 }
83
84 static const struct of_device_id mscc_ocelot_match[] = {
85         { .compatible = "mscc,vsc7514-switch" },
86         { }
87 };
88 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
89
90 static const struct ocelot_ops ocelot_ops = {
91         .reset                  = ocelot_reset,
92         .wm_enc                 = ocelot_wm_enc,
93         .wm_dec                 = ocelot_wm_dec,
94         .wm_stat                = ocelot_wm_stat,
95         .port_to_netdev         = ocelot_port_to_netdev,
96         .netdev_to_port         = ocelot_netdev_to_port,
97 };
98
99 static struct ptp_clock_info ocelot_ptp_clock_info = {
100         .owner          = THIS_MODULE,
101         .name           = "ocelot ptp",
102         .max_adj        = 0x7fffffff,
103         .n_alarm        = 0,
104         .n_ext_ts       = 0,
105         .n_per_out      = OCELOT_PTP_PINS_NUM,
106         .n_pins         = OCELOT_PTP_PINS_NUM,
107         .pps            = 0,
108         .gettime64      = ocelot_ptp_gettime64,
109         .settime64      = ocelot_ptp_settime64,
110         .adjtime        = ocelot_ptp_adjtime,
111         .adjfine        = ocelot_ptp_adjfine,
112         .verify         = ocelot_ptp_verify,
113         .enable         = ocelot_ptp_enable,
114 };
115
116 static void mscc_ocelot_teardown_devlink_ports(struct ocelot *ocelot)
117 {
118         int port;
119
120         for (port = 0; port < ocelot->num_phys_ports; port++)
121                 ocelot_port_devlink_teardown(ocelot, port);
122 }
123
124 static void mscc_ocelot_release_ports(struct ocelot *ocelot)
125 {
126         int port;
127
128         for (port = 0; port < ocelot->num_phys_ports; port++) {
129                 struct ocelot_port *ocelot_port;
130
131                 ocelot_port = ocelot->ports[port];
132                 if (!ocelot_port)
133                         continue;
134
135                 ocelot_deinit_port(ocelot, port);
136                 ocelot_release_port(ocelot_port);
137         }
138 }
139
140 static int mscc_ocelot_init_ports(struct platform_device *pdev,
141                                   struct device_node *ports)
142 {
143         struct ocelot *ocelot = platform_get_drvdata(pdev);
144         u32 devlink_ports_registered = 0;
145         struct device_node *portnp;
146         int port, err;
147         u32 reg;
148
149         ocelot->ports = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
150                                      sizeof(struct ocelot_port *), GFP_KERNEL);
151         if (!ocelot->ports)
152                 return -ENOMEM;
153
154         ocelot->devlink_ports = devm_kcalloc(ocelot->dev,
155                                              ocelot->num_phys_ports,
156                                              sizeof(*ocelot->devlink_ports),
157                                              GFP_KERNEL);
158         if (!ocelot->devlink_ports)
159                 return -ENOMEM;
160
161         for_each_available_child_of_node(ports, portnp) {
162                 struct regmap *target;
163                 struct resource *res;
164                 char res_name[8];
165
166                 if (of_property_read_u32(portnp, "reg", &reg))
167                         continue;
168
169                 port = reg;
170                 if (port < 0 || port >= ocelot->num_phys_ports) {
171                         dev_err(ocelot->dev,
172                                 "invalid port number: %d >= %d\n", port,
173                                 ocelot->num_phys_ports);
174                         continue;
175                 }
176
177                 snprintf(res_name, sizeof(res_name), "port%d", port);
178
179                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
180                                                    res_name);
181                 target = ocelot_regmap_init(ocelot, res);
182                 if (IS_ERR(target)) {
183                         err = PTR_ERR(target);
184                         of_node_put(portnp);
185                         goto out_teardown;
186                 }
187
188                 err = ocelot_port_devlink_init(ocelot, port,
189                                                DEVLINK_PORT_FLAVOUR_PHYSICAL);
190                 if (err) {
191                         of_node_put(portnp);
192                         goto out_teardown;
193                 }
194
195                 err = ocelot_probe_port(ocelot, port, target, portnp);
196                 if (err) {
197                         ocelot_port_devlink_teardown(ocelot, port);
198                         continue;
199                 }
200
201                 devlink_ports_registered |= BIT(port);
202         }
203
204         /* Initialize unused devlink ports at the end */
205         for (port = 0; port < ocelot->num_phys_ports; port++) {
206                 if (devlink_ports_registered & BIT(port))
207                         continue;
208
209                 err = ocelot_port_devlink_init(ocelot, port,
210                                                DEVLINK_PORT_FLAVOUR_UNUSED);
211                 if (err)
212                         goto out_teardown;
213
214                 devlink_ports_registered |= BIT(port);
215         }
216
217         return 0;
218
219 out_teardown:
220         /* Unregister the network interfaces */
221         mscc_ocelot_release_ports(ocelot);
222         /* Tear down devlink ports for the registered network interfaces */
223         for (port = 0; port < ocelot->num_phys_ports; port++) {
224                 if (devlink_ports_registered & BIT(port))
225                         ocelot_port_devlink_teardown(ocelot, port);
226         }
227         return err;
228 }
229
230 static int mscc_ocelot_probe(struct platform_device *pdev)
231 {
232         struct device_node *np = pdev->dev.of_node;
233         int err, irq_xtr, irq_ptp_rdy;
234         struct device_node *ports;
235         struct devlink *devlink;
236         struct ocelot *ocelot;
237         struct regmap *hsio;
238         unsigned int i;
239
240         struct {
241                 enum ocelot_target id;
242                 char *name;
243                 u8 optional:1;
244         } io_target[] = {
245                 { SYS, "sys" },
246                 { REW, "rew" },
247                 { QSYS, "qsys" },
248                 { ANA, "ana" },
249                 { QS, "qs" },
250                 { S0, "s0" },
251                 { S1, "s1" },
252                 { S2, "s2" },
253                 { PTP, "ptp", 1 },
254                 { FDMA, "fdma", 1 },
255         };
256
257         if (!np && !pdev->dev.platform_data)
258                 return -ENODEV;
259
260         devlink =
261                 devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot), &pdev->dev);
262         if (!devlink)
263                 return -ENOMEM;
264
265         ocelot = devlink_priv(devlink);
266         ocelot->devlink = priv_to_devlink(ocelot);
267         platform_set_drvdata(pdev, ocelot);
268         ocelot->dev = &pdev->dev;
269
270         for (i = 0; i < ARRAY_SIZE(io_target); i++) {
271                 struct regmap *target;
272                 struct resource *res;
273
274                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
275                                                    io_target[i].name);
276
277                 target = ocelot_regmap_init(ocelot, res);
278                 if (IS_ERR(target)) {
279                         if (io_target[i].optional) {
280                                 ocelot->targets[io_target[i].id] = NULL;
281                                 continue;
282                         }
283                         err = PTR_ERR(target);
284                         goto out_free_devlink;
285                 }
286
287                 ocelot->targets[io_target[i].id] = target;
288         }
289
290         if (ocelot->targets[FDMA])
291                 ocelot_fdma_init(pdev, ocelot);
292
293         hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
294         if (IS_ERR(hsio)) {
295                 dev_err(&pdev->dev, "missing hsio syscon\n");
296                 err = PTR_ERR(hsio);
297                 goto out_free_devlink;
298         }
299
300         ocelot->targets[HSIO] = hsio;
301
302         err = ocelot_chip_init(ocelot, &ocelot_ops);
303         if (err)
304                 goto out_free_devlink;
305
306         irq_xtr = platform_get_irq_byname(pdev, "xtr");
307         if (irq_xtr < 0) {
308                 err = irq_xtr;
309                 goto out_free_devlink;
310         }
311
312         err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
313                                         ocelot_xtr_irq_handler, IRQF_ONESHOT,
314                                         "frame extraction", ocelot);
315         if (err)
316                 goto out_free_devlink;
317
318         irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
319         if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) {
320                 err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
321                                                 ocelot_ptp_rdy_irq_handler,
322                                                 IRQF_ONESHOT, "ptp ready",
323                                                 ocelot);
324                 if (err)
325                         goto out_free_devlink;
326
327                 /* Both the PTP interrupt and the PTP bank are available */
328                 ocelot->ptp = 1;
329         }
330
331         ports = of_get_child_by_name(np, "ethernet-ports");
332         if (!ports) {
333                 dev_err(ocelot->dev, "no ethernet-ports child node found\n");
334                 err = -ENODEV;
335                 goto out_free_devlink;
336         }
337
338         ocelot->num_phys_ports = of_get_child_count(ports);
339         ocelot->num_flooding_pgids = 1;
340
341         ocelot->vcap = vsc7514_vcap_props;
342
343         ocelot->vcap_pol.base = VSC7514_VCAP_POLICER_BASE;
344         ocelot->vcap_pol.max = VSC7514_VCAP_POLICER_MAX;
345
346         ocelot->npi = -1;
347
348         err = ocelot_init(ocelot);
349         if (err)
350                 goto out_put_ports;
351
352         err = mscc_ocelot_init_ports(pdev, ports);
353         if (err)
354                 goto out_ocelot_devlink_unregister;
355
356         if (ocelot->fdma)
357                 ocelot_fdma_start(ocelot);
358
359         err = ocelot_devlink_sb_register(ocelot);
360         if (err)
361                 goto out_ocelot_release_ports;
362
363         if (ocelot->ptp) {
364                 err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info);
365                 if (err) {
366                         dev_err(ocelot->dev,
367                                 "Timestamp initialization failed\n");
368                         ocelot->ptp = 0;
369                 }
370         }
371
372         register_netdevice_notifier(&ocelot_netdevice_nb);
373         register_switchdev_notifier(&ocelot_switchdev_nb);
374         register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
375
376         of_node_put(ports);
377         devlink_register(devlink);
378
379         dev_info(&pdev->dev, "Ocelot switch probed\n");
380
381         return 0;
382
383 out_ocelot_release_ports:
384         mscc_ocelot_release_ports(ocelot);
385         mscc_ocelot_teardown_devlink_ports(ocelot);
386 out_ocelot_devlink_unregister:
387         ocelot_deinit(ocelot);
388 out_put_ports:
389         of_node_put(ports);
390 out_free_devlink:
391         devlink_free(devlink);
392         return err;
393 }
394
395 static void mscc_ocelot_remove(struct platform_device *pdev)
396 {
397         struct ocelot *ocelot = platform_get_drvdata(pdev);
398
399         if (ocelot->fdma)
400                 ocelot_fdma_deinit(ocelot);
401         devlink_unregister(ocelot->devlink);
402         ocelot_deinit_timestamp(ocelot);
403         ocelot_devlink_sb_unregister(ocelot);
404         mscc_ocelot_release_ports(ocelot);
405         mscc_ocelot_teardown_devlink_ports(ocelot);
406         ocelot_deinit(ocelot);
407         unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
408         unregister_switchdev_notifier(&ocelot_switchdev_nb);
409         unregister_netdevice_notifier(&ocelot_netdevice_nb);
410         devlink_free(ocelot->devlink);
411 }
412
413 static struct platform_driver mscc_ocelot_driver = {
414         .probe = mscc_ocelot_probe,
415         .remove_new = mscc_ocelot_remove,
416         .driver = {
417                 .name = "ocelot-switch",
418                 .of_match_table = mscc_ocelot_match,
419         },
420 };
421
422 module_platform_driver(mscc_ocelot_driver);
423
424 MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
425 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
426 MODULE_LICENSE("Dual MIT/GPL");