1
2
3
4
5
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#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)
22{
23 u8 llen, wlen;
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]);
28
29 wlen = IFH_EXTRACT_BITFIELD64(ifh[0], 7, 8);
30 llen = IFH_EXTRACT_BITFIELD64(ifh[0], 15, 6);
31
32 info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80;
33
34 info->timestamp = IFH_EXTRACT_BITFIELD64(ifh[0], 21, 32);
35
36 info->port = IFH_EXTRACT_BITFIELD64(ifh[1], 43, 4);
37
38 info->tag_type = IFH_EXTRACT_BITFIELD64(ifh[1], 16, 1);
39 info->vid = IFH_EXTRACT_BITFIELD64(ifh[1], 0, 12);
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 {
97 struct skb_shared_hwtstamps *shhwtstamps;
98 struct ocelot_port_private *priv;
99 struct ocelot_port *ocelot_port;
100 u64 tod_in_ns, full_ts_in_ns;
101 struct frame_info info = {};
102 struct net_device *dev;
103 u32 ifh[4], val, *buf;
104 struct timespec64 ts;
105 int sz, len, buf_len;
106 struct sk_buff *skb;
107
108 for (i = 0; i < OCELOT_TAG_LEN / 4; i++) {
109 err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]);
110 if (err != 4)
111 break;
112 }
113
114 if (err != 4)
115 break;
116
117
118
119
120
121
122
123 err = 0;
124
125 ocelot_parse_ifh(ifh, &info);
126
127 ocelot_port = ocelot->ports[info.port];
128 priv = container_of(ocelot_port, struct ocelot_port_private,
129 port);
130 dev = priv->dev;
131
132 skb = netdev_alloc_skb(dev, info.len);
133
134 if (unlikely(!skb)) {
135 netdev_err(dev, "Unable to allocate sk_buff\n");
136 err = -ENOMEM;
137 break;
138 }
139 buf_len = info.len - ETH_FCS_LEN;
140 buf = (u32 *)skb_put(skb, buf_len);
141
142 len = 0;
143 do {
144 sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
145 *buf++ = val;
146 len += sz;
147 } while (len < buf_len);
148
149
150 sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
151
152 len -= ETH_FCS_LEN - sz;
153
154 if (unlikely(dev->features & NETIF_F_RXFCS)) {
155 buf = (u32 *)skb_put(skb, ETH_FCS_LEN);
156 *buf = val;
157 }
158
159 if (sz < 0) {
160 err = sz;
161 break;
162 }
163
164 if (ocelot->ptp) {
165 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
166
167 tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec);
168 if ((tod_in_ns & 0xffffffff) < info.timestamp)
169 full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) |
170 info.timestamp;
171 else
172 full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) |
173 info.timestamp;
174
175 shhwtstamps = skb_hwtstamps(skb);
176 memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
177 shhwtstamps->hwtstamp = full_ts_in_ns;
178 }
179
180
181
182
183 if (ocelot->bridge_mask & BIT(info.port))
184 skb->offload_fwd_mark = 1;
185
186 skb->protocol = eth_type_trans(skb, dev);
187 netif_rx(skb);
188 dev->stats.rx_bytes += len;
189 dev->stats.rx_packets++;
190 } while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp));
191
192 if (err)
193 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp))
194 ocelot_read_rix(ocelot, QS_XTR_RD, grp);
195
196 return IRQ_HANDLED;
197}
198
199static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
200{
201 struct ocelot *ocelot = arg;
202
203 ocelot_get_txtstamp(ocelot);
204
205 return IRQ_HANDLED;
206}
207
208static const struct of_device_id mscc_ocelot_match[] = {
209 { .compatible = "mscc,vsc7514-switch" },
210 { }
211};
212MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
213
214static void ocelot_port_pcs_init(struct ocelot *ocelot, int port)
215{
216 struct ocelot_port *ocelot_port = ocelot->ports[port];
217
218
219 ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS,
220 DEV_PORT_MISC);
221
222
223 ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA,
224 PCS1G_MODE_CFG);
225 ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG);
226
227
228 ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG);
229
230
231 ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG);
232
233
234 ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG);
235}
236
237static int ocelot_reset(struct ocelot *ocelot)
238{
239 int retries = 100;
240 u32 val;
241
242 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
243 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
244
245 do {
246 msleep(1);
247 regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
248 &val);
249 } while (val && --retries);
250
251 if (!retries)
252 return -ETIMEDOUT;
253
254 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
255 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
256
257 return 0;
258}
259
260static const struct ocelot_ops ocelot_ops = {
261 .pcs_init = ocelot_port_pcs_init,
262 .reset = ocelot_reset,
263};
264
265static int mscc_ocelot_probe(struct platform_device *pdev)
266{
267 struct device_node *np = pdev->dev.of_node;
268 struct device_node *ports, *portnp;
269 int err, irq_xtr, irq_ptp_rdy;
270 struct ocelot *ocelot;
271 struct regmap *hsio;
272 unsigned int i;
273
274 struct {
275 enum ocelot_target id;
276 char *name;
277 u8 optional:1;
278 } io_target[] = {
279 { SYS, "sys" },
280 { REW, "rew" },
281 { QSYS, "qsys" },
282 { ANA, "ana" },
283 { QS, "qs" },
284 { S2, "s2" },
285 { PTP, "ptp", 1 },
286 };
287
288 if (!np && !pdev->dev.platform_data)
289 return -ENODEV;
290
291 ocelot = devm_kzalloc(&pdev->dev, sizeof(*ocelot), GFP_KERNEL);
292 if (!ocelot)
293 return -ENOMEM;
294
295 platform_set_drvdata(pdev, ocelot);
296 ocelot->dev = &pdev->dev;
297
298 for (i = 0; i < ARRAY_SIZE(io_target); i++) {
299 struct regmap *target;
300 struct resource *res;
301
302 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
303 io_target[i].name);
304
305 target = ocelot_regmap_init(ocelot, res);
306 if (IS_ERR(target)) {
307 if (io_target[i].optional) {
308 ocelot->targets[io_target[i].id] = NULL;
309 continue;
310 }
311 return PTR_ERR(target);
312 }
313
314 ocelot->targets[io_target[i].id] = target;
315 }
316
317 hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
318 if (IS_ERR(hsio)) {
319 dev_err(&pdev->dev, "missing hsio syscon\n");
320 return PTR_ERR(hsio);
321 }
322
323 ocelot->targets[HSIO] = hsio;
324
325 err = ocelot_chip_init(ocelot, &ocelot_ops);
326 if (err)
327 return err;
328
329 irq_xtr = platform_get_irq_byname(pdev, "xtr");
330 if (irq_xtr < 0)
331 return -ENODEV;
332
333 err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
334 ocelot_xtr_irq_handler, IRQF_ONESHOT,
335 "frame extraction", ocelot);
336 if (err)
337 return err;
338
339 irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
340 if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) {
341 err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
342 ocelot_ptp_rdy_irq_handler,
343 IRQF_ONESHOT, "ptp ready",
344 ocelot);
345 if (err)
346 return err;
347
348
349 ocelot->ptp = 1;
350 }
351
352 ocelot->num_cpu_ports = 1;
353
354 ports = of_get_child_by_name(np, "ethernet-ports");
355 if (!ports) {
356 dev_err(&pdev->dev, "no ethernet-ports child node found\n");
357 return -ENODEV;
358 }
359
360 ocelot->num_phys_ports = of_get_child_count(ports);
361
362 ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
363 sizeof(struct ocelot_port *), GFP_KERNEL);
364
365 ocelot_init(ocelot);
366 ocelot_set_cpu_port(ocelot, ocelot->num_phys_ports,
367 OCELOT_TAG_PREFIX_NONE, OCELOT_TAG_PREFIX_NONE);
368
369 for_each_available_child_of_node(ports, portnp) {
370 struct ocelot_port_private *priv;
371 struct ocelot_port *ocelot_port;
372 struct device_node *phy_node;
373 phy_interface_t phy_mode;
374 struct phy_device *phy;
375 struct resource *res;
376 struct phy *serdes;
377 void __iomem *regs;
378 char res_name[8];
379 u32 port;
380
381 if (of_property_read_u32(portnp, "reg", &port))
382 continue;
383
384 snprintf(res_name, sizeof(res_name), "port%d", port);
385
386 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
387 res_name);
388 regs = devm_ioremap_resource(&pdev->dev, res);
389 if (IS_ERR(regs))
390 continue;
391
392 phy_node = of_parse_phandle(portnp, "phy-handle", 0);
393 if (!phy_node)
394 continue;
395
396 phy = of_phy_find_device(phy_node);
397 of_node_put(phy_node);
398 if (!phy)
399 continue;
400
401 err = ocelot_probe_port(ocelot, port, regs, phy);
402 if (err) {
403 of_node_put(portnp);
404 goto out_put_ports;
405 }
406
407 ocelot_port = ocelot->ports[port];
408 priv = container_of(ocelot_port, struct ocelot_port_private,
409 port);
410
411 of_get_phy_mode(portnp, &phy_mode);
412
413 ocelot_port->phy_mode = phy_mode;
414
415 switch (ocelot_port->phy_mode) {
416 case PHY_INTERFACE_MODE_NA:
417 continue;
418 case PHY_INTERFACE_MODE_SGMII:
419 break;
420 case PHY_INTERFACE_MODE_QSGMII:
421
422
423
424 ocelot_port_writel(ocelot_port,
425 DEV_CLOCK_CFG_LINK_SPEED
426 (OCELOT_SPEED_1000),
427 DEV_CLOCK_CFG);
428 break;
429 default:
430 dev_err(ocelot->dev,
431 "invalid phy mode for port%d, (Q)SGMII only\n",
432 port);
433 of_node_put(portnp);
434 err = -EINVAL;
435 goto out_put_ports;
436 }
437
438 serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
439 if (IS_ERR(serdes)) {
440 err = PTR_ERR(serdes);
441 if (err == -EPROBE_DEFER)
442 dev_dbg(ocelot->dev, "deferring probe\n");
443 else
444 dev_err(ocelot->dev,
445 "missing SerDes phys for port%d\n",
446 port);
447
448 of_node_put(portnp);
449 goto out_put_ports;
450 }
451
452 priv->serdes = serdes;
453 }
454
455 register_netdevice_notifier(&ocelot_netdevice_nb);
456 register_switchdev_notifier(&ocelot_switchdev_nb);
457 register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
458
459 dev_info(&pdev->dev, "Ocelot switch probed\n");
460
461out_put_ports:
462 of_node_put(ports);
463 return err;
464}
465
466static int mscc_ocelot_remove(struct platform_device *pdev)
467{
468 struct ocelot *ocelot = platform_get_drvdata(pdev);
469
470 ocelot_deinit(ocelot);
471 unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
472 unregister_switchdev_notifier(&ocelot_switchdev_nb);
473 unregister_netdevice_notifier(&ocelot_netdevice_nb);
474
475 return 0;
476}
477
478static struct platform_driver mscc_ocelot_driver = {
479 .probe = mscc_ocelot_probe,
480 .remove = mscc_ocelot_remove,
481 .driver = {
482 .name = "ocelot-switch",
483 .of_match_table = mscc_ocelot_match,
484 },
485};
486
487module_platform_driver(mscc_ocelot_driver);
488
489MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
490MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
491MODULE_LICENSE("Dual MIT/GPL");
492