net: mscc: ocelot: add missing of_node_put after calling of_get_child_by_name
[linux-2.6-block.git] / drivers / net / ethernet / mscc / ocelot_board.c
CommitLineData
a556c76a
AB
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>
71e32a20 9#include <linux/of_net.h>
a556c76a
AB
10#include <linux/netdevice.h>
11#include <linux/of_mdio.h>
12#include <linux/of_platform.h>
19aedfbe 13#include <linux/mfd/syscon.h>
a556c76a 14#include <linux/skbuff.h>
0e332c85 15#include <net/switchdev.h>
a556c76a
AB
16
17#include "ocelot.h"
18
d8c964dc
AT
19#define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
20
21static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info)
a556c76a 22{
a556c76a 23 u8 llen, wlen;
d8c964dc
AT
24 u64 ifh[2];
25
26 ifh[0] = be64_to_cpu(((__force __be64 *)_ifh)[0]);
27 ifh[1] = be64_to_cpu(((__force __be64 *)_ifh)[1]);
a556c76a 28
d8c964dc
AT
29 wlen = IFH_EXTRACT_BITFIELD64(ifh[0], 7, 8);
30 llen = IFH_EXTRACT_BITFIELD64(ifh[0], 15, 6);
a556c76a 31
a556c76a
AB
32 info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80;
33
4e3b0468
AT
34 info->timestamp = IFH_EXTRACT_BITFIELD64(ifh[0], 21, 32);
35
d8c964dc 36 info->port = IFH_EXTRACT_BITFIELD64(ifh[1], 43, 4);
a556c76a 37
d8c964dc
AT
38 info->tag_type = IFH_EXTRACT_BITFIELD64(ifh[1], 16, 1);
39 info->vid = IFH_EXTRACT_BITFIELD64(ifh[1], 0, 12);
a556c76a
AB
40
41 return 0;
42}
43
44static int ocelot_rx_frame_word(struct ocelot *ocelot, u8 grp, bool ifh,
45 u32 *rval)
46{
47 u32 val;
48 u32 bytes_valid;
49
50 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
51 if (val == XTR_NOT_READY) {
52 if (ifh)
53 return -EIO;
54
55 do {
56 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
57 } while (val == XTR_NOT_READY);
58 }
59
60 switch (val) {
61 case XTR_ABORT:
62 return -EIO;
63 case XTR_EOF_0:
64 case XTR_EOF_1:
65 case XTR_EOF_2:
66 case XTR_EOF_3:
67 case XTR_PRUNED:
68 bytes_valid = XTR_VALID_BYTES(val);
69 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
70 if (val == XTR_ESCAPE)
71 *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
72 else
73 *rval = val;
74
75 return bytes_valid;
76 case XTR_ESCAPE:
77 *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
78
79 return 4;
80 default:
81 *rval = val;
82
83 return 4;
84 }
85}
86
87static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
88{
89 struct ocelot *ocelot = arg;
90 int i = 0, grp = 0;
91 int err = 0;
92
93 if (!(ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)))
94 return IRQ_NONE;
95
96 do {
4e3b0468
AT
97 struct skb_shared_hwtstamps *shhwtstamps;
98 u64 tod_in_ns, full_ts_in_ns;
99 struct frame_info info = {};
a556c76a 100 struct net_device *dev;
4e3b0468
AT
101 u32 ifh[4], val, *buf;
102 struct timespec64 ts;
652ef42c 103 int sz, len, buf_len;
4e3b0468 104 struct sk_buff *skb;
a556c76a
AB
105
106 for (i = 0; i < IFH_LEN; i++) {
107 err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]);
108 if (err != 4)
109 break;
110 }
111
112 if (err != 4)
113 break;
114
115 ocelot_parse_ifh(ifh, &info);
116
117 dev = ocelot->ports[info.port]->dev;
118
119 skb = netdev_alloc_skb(dev, info.len);
120
121 if (unlikely(!skb)) {
122 netdev_err(dev, "Unable to allocate sk_buff\n");
123 err = -ENOMEM;
124 break;
125 }
652ef42c
AT
126 buf_len = info.len - ETH_FCS_LEN;
127 buf = (u32 *)skb_put(skb, buf_len);
a556c76a
AB
128
129 len = 0;
130 do {
131 sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
132 *buf++ = val;
133 len += sz;
652ef42c
AT
134 } while (len < buf_len);
135
60f8e67d 136 /* Read the FCS */
652ef42c
AT
137 sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
138 /* Update the statistics if part of the FCS was read before */
139 len -= ETH_FCS_LEN - sz;
a556c76a 140
60f8e67d
AT
141 if (unlikely(dev->features & NETIF_F_RXFCS)) {
142 buf = (u32 *)skb_put(skb, ETH_FCS_LEN);
143 *buf = val;
144 }
145
a556c76a
AB
146 if (sz < 0) {
147 err = sz;
148 break;
149 }
150
4e3b0468
AT
151 if (ocelot->ptp) {
152 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
153
154 tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec);
155 if ((tod_in_ns & 0xffffffff) < info.timestamp)
156 full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) |
157 info.timestamp;
158 else
159 full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) |
160 info.timestamp;
161
162 shhwtstamps = skb_hwtstamps(skb);
163 memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
164 shhwtstamps->hwtstamp = full_ts_in_ns;
165 }
166
a556c76a
AB
167 /* Everything we see on an interface that is in the HW bridge
168 * has already been forwarded.
169 */
170 if (ocelot->bridge_mask & BIT(info.port))
171 skb->offload_fwd_mark = 1;
172
173 skb->protocol = eth_type_trans(skb, dev);
174 netif_rx(skb);
175 dev->stats.rx_bytes += len;
176 dev->stats.rx_packets++;
177 } while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp));
178
179 if (err)
180 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp))
181 ocelot_read_rix(ocelot, QS_XTR_RD, grp);
182
183 return IRQ_HANDLED;
184}
185
4e3b0468
AT
186static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
187{
188 int budget = OCELOT_PTP_QUEUE_SZ;
189 struct ocelot *ocelot = arg;
190
191 while (budget--) {
192 struct skb_shared_hwtstamps shhwtstamps;
193 struct list_head *pos, *tmp;
194 struct sk_buff *skb = NULL;
195 struct ocelot_skb *entry;
196 struct ocelot_port *port;
197 struct timespec64 ts;
198 u32 val, id, txport;
199
200 val = ocelot_read(ocelot, SYS_PTP_STATUS);
201
202 /* Check if a timestamp can be retrieved */
203 if (!(val & SYS_PTP_STATUS_PTP_MESS_VLD))
204 break;
205
206 WARN_ON(val & SYS_PTP_STATUS_PTP_OVFL);
207
208 /* Retrieve the ts ID and Tx port */
209 id = SYS_PTP_STATUS_PTP_MESS_ID_X(val);
210 txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);
211
212 /* Retrieve its associated skb */
213 port = ocelot->ports[txport];
214
215 list_for_each_safe(pos, tmp, &port->skbs) {
216 entry = list_entry(pos, struct ocelot_skb, head);
217 if (entry->id != id)
218 continue;
219
220 skb = entry->skb;
221
222 list_del(pos);
223 kfree(entry);
224 }
225
226 /* Next ts */
227 ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
228
229 if (unlikely(!skb))
230 continue;
231
232 /* Get the h/w timestamp */
233 ocelot_get_hwtimestamp(ocelot, &ts);
234
235 /* Set the timestamp into the skb */
236 memset(&shhwtstamps, 0, sizeof(shhwtstamps));
237 shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
238 skb_tstamp_tx(skb, &shhwtstamps);
239
240 dev_kfree_skb_any(skb);
241 }
242
243 return IRQ_HANDLED;
244}
245
a556c76a
AB
246static const struct of_device_id mscc_ocelot_match[] = {
247 { .compatible = "mscc,vsc7514-switch" },
248 { }
249};
250MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
251
252static int mscc_ocelot_probe(struct platform_device *pdev)
253{
a556c76a
AB
254 struct device_node *np = pdev->dev.of_node;
255 struct device_node *ports, *portnp;
4e3b0468 256 int err, irq_xtr, irq_ptp_rdy;
a556c76a 257 struct ocelot *ocelot;
19aedfbe 258 struct regmap *hsio;
4e3b0468 259 unsigned int i;
a556c76a
AB
260 u32 val;
261
262 struct {
263 enum ocelot_target id;
264 char *name;
45bce171 265 u8 optional:1;
a556c76a
AB
266 } res[] = {
267 { SYS, "sys" },
268 { REW, "rew" },
269 { QSYS, "qsys" },
270 { ANA, "ana" },
271 { QS, "qs" },
b5962294 272 { S2, "s2" },
45bce171 273 { PTP, "ptp", 1 },
a556c76a
AB
274 };
275
276 if (!np && !pdev->dev.platform_data)
277 return -ENODEV;
278
279 ocelot = devm_kzalloc(&pdev->dev, sizeof(*ocelot), GFP_KERNEL);
280 if (!ocelot)
281 return -ENOMEM;
282
283 platform_set_drvdata(pdev, ocelot);
284 ocelot->dev = &pdev->dev;
285
286 for (i = 0; i < ARRAY_SIZE(res); i++) {
287 struct regmap *target;
288
289 target = ocelot_io_platform_init(ocelot, pdev, res[i].name);
45bce171
AT
290 if (IS_ERR(target)) {
291 if (res[i].optional) {
292 ocelot->targets[res[i].id] = NULL;
293 continue;
294 }
295
a556c76a 296 return PTR_ERR(target);
45bce171 297 }
a556c76a
AB
298
299 ocelot->targets[res[i].id] = target;
300 }
301
19aedfbe
QS
302 hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
303 if (IS_ERR(hsio)) {
304 dev_err(&pdev->dev, "missing hsio syscon\n");
305 return PTR_ERR(hsio);
306 }
307
308 ocelot->targets[HSIO] = hsio;
309
a556c76a
AB
310 err = ocelot_chip_init(ocelot);
311 if (err)
312 return err;
313
4e3b0468
AT
314 irq_xtr = platform_get_irq_byname(pdev, "xtr");
315 if (irq_xtr < 0)
a556c76a
AB
316 return -ENODEV;
317
4e3b0468 318 err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
a556c76a
AB
319 ocelot_xtr_irq_handler, IRQF_ONESHOT,
320 "frame extraction", ocelot);
321 if (err)
322 return err;
323
4e3b0468
AT
324 irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
325 if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) {
326 err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
327 ocelot_ptp_rdy_irq_handler,
328 IRQF_ONESHOT, "ptp ready",
329 ocelot);
330 if (err)
331 return err;
332
333 /* Both the PTP interrupt and the PTP bank are available */
334 ocelot->ptp = 1;
335 }
336
a556c76a
AB
337 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
338 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
339
340 do {
341 msleep(1);
342 regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
343 &val);
344 } while (val);
345
346 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
347 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
348
349 ocelot->num_cpu_ports = 1; /* 1 port on the switch, two groups */
350
351 ports = of_get_child_by_name(np, "ethernet-ports");
352 if (!ports) {
353 dev_err(&pdev->dev, "no ethernet-ports child node found\n");
354 return -ENODEV;
355 }
356
357 ocelot->num_phys_ports = of_get_child_count(ports);
358
359 ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
360 sizeof(struct ocelot_port *), GFP_KERNEL);
361
362 INIT_LIST_HEAD(&ocelot->multicast);
363 ocelot_init(ocelot);
364
a556c76a
AB
365 for_each_available_child_of_node(ports, portnp) {
366 struct device_node *phy_node;
367 struct phy_device *phy;
368 struct resource *res;
71e32a20 369 struct phy *serdes;
a556c76a
AB
370 void __iomem *regs;
371 char res_name[8];
084e5bb1 372 int phy_mode;
a556c76a
AB
373 u32 port;
374
375 if (of_property_read_u32(portnp, "reg", &port))
376 continue;
377
378 snprintf(res_name, sizeof(res_name), "port%d", port);
379
380 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
381 res_name);
382 regs = devm_ioremap_resource(&pdev->dev, res);
383 if (IS_ERR(regs))
384 continue;
385
386 phy_node = of_parse_phandle(portnp, "phy-handle", 0);
387 if (!phy_node)
388 continue;
389
390 phy = of_phy_find_device(phy_node);
d2c50b1c 391 of_node_put(phy_node);
a556c76a
AB
392 if (!phy)
393 continue;
394
395 err = ocelot_probe_port(ocelot, port, regs, phy);
64fc973d
ND
396 if (err) {
397 of_node_put(portnp);
d2c50b1c 398 goto out_put_ports;
64fc973d 399 }
71e32a20 400
084e5bb1
KSK
401 phy_mode = of_get_phy_mode(portnp);
402 if (phy_mode < 0)
71e32a20
QS
403 ocelot->ports[port]->phy_mode = PHY_INTERFACE_MODE_NA;
404 else
084e5bb1 405 ocelot->ports[port]->phy_mode = phy_mode;
71e32a20
QS
406
407 switch (ocelot->ports[port]->phy_mode) {
408 case PHY_INTERFACE_MODE_NA:
409 continue;
410 case PHY_INTERFACE_MODE_SGMII:
71e32a20
QS
411 break;
412 case PHY_INTERFACE_MODE_QSGMII:
084e5bb1
KSK
413 /* Ensure clock signals and speed is set on all
414 * QSGMII links
415 */
416 ocelot_port_writel(ocelot->ports[port],
417 DEV_CLOCK_CFG_LINK_SPEED
418 (OCELOT_SPEED_1000),
419 DEV_CLOCK_CFG);
71e32a20
QS
420 break;
421 default:
422 dev_err(ocelot->dev,
423 "invalid phy mode for port%d, (Q)SGMII only\n",
424 port);
64fc973d 425 of_node_put(portnp);
d2c50b1c
WY
426 err = -EINVAL;
427 goto out_put_ports;
71e32a20
QS
428 }
429
430 serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
431 if (IS_ERR(serdes)) {
432 err = PTR_ERR(serdes);
433 if (err == -EPROBE_DEFER)
434 dev_dbg(ocelot->dev, "deferring probe\n");
435 else
436 dev_err(ocelot->dev,
437 "missing SerDes phys for port%d\n",
438 port);
439
d2c50b1c
WY
440 of_node_put(portnp);
441 goto out_put_ports;
a556c76a 442 }
71e32a20
QS
443
444 ocelot->ports[port]->serdes = serdes;
a556c76a
AB
445 }
446
447 register_netdevice_notifier(&ocelot_netdevice_nb);
56da64bc 448 register_switchdev_notifier(&ocelot_switchdev_nb);
0e332c85 449 register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
a556c76a
AB
450
451 dev_info(&pdev->dev, "Ocelot switch probed\n");
452
d2c50b1c
WY
453out_put_ports:
454 of_node_put(ports);
a556c76a
AB
455 return err;
456}
457
458static int mscc_ocelot_remove(struct platform_device *pdev)
459{
460 struct ocelot *ocelot = platform_get_drvdata(pdev);
461
462 ocelot_deinit(ocelot);
0e332c85 463 unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
56da64bc 464 unregister_switchdev_notifier(&ocelot_switchdev_nb);
a556c76a
AB
465 unregister_netdevice_notifier(&ocelot_netdevice_nb);
466
467 return 0;
468}
469
470static struct platform_driver mscc_ocelot_driver = {
471 .probe = mscc_ocelot_probe,
472 .remove = mscc_ocelot_remove,
473 .driver = {
474 .name = "ocelot-switch",
475 .of_match_table = mscc_ocelot_match,
476 },
477};
478
479module_platform_driver(mscc_ocelot_driver);
480
481MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
482MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
483MODULE_LICENSE("Dual MIT/GPL");