This source file includes following definitions.
- ocelot_parse_ifh
- ocelot_rx_frame_word
- ocelot_xtr_irq_handler
- ocelot_ptp_rdy_irq_handler
- mscc_ocelot_probe
- mscc_ocelot_remove
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
21 static 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
44 static 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
87 static 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 u64 tod_in_ns, full_ts_in_ns;
99 struct frame_info info = {};
100 struct net_device *dev;
101 u32 ifh[4], val, *buf;
102 struct timespec64 ts;
103 int sz, len, buf_len;
104 struct sk_buff *skb;
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
116
117
118
119
120
121 err = 0;
122
123 ocelot_parse_ifh(ifh, &info);
124
125 dev = ocelot->ports[info.port]->dev;
126
127 skb = netdev_alloc_skb(dev, info.len);
128
129 if (unlikely(!skb)) {
130 netdev_err(dev, "Unable to allocate sk_buff\n");
131 err = -ENOMEM;
132 break;
133 }
134 buf_len = info.len - ETH_FCS_LEN;
135 buf = (u32 *)skb_put(skb, buf_len);
136
137 len = 0;
138 do {
139 sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
140 *buf++ = val;
141 len += sz;
142 } while (len < buf_len);
143
144
145 sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
146
147 len -= ETH_FCS_LEN - sz;
148
149 if (unlikely(dev->features & NETIF_F_RXFCS)) {
150 buf = (u32 *)skb_put(skb, ETH_FCS_LEN);
151 *buf = val;
152 }
153
154 if (sz < 0) {
155 err = sz;
156 break;
157 }
158
159 if (ocelot->ptp) {
160 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
161
162 tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec);
163 if ((tod_in_ns & 0xffffffff) < info.timestamp)
164 full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) |
165 info.timestamp;
166 else
167 full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) |
168 info.timestamp;
169
170 shhwtstamps = skb_hwtstamps(skb);
171 memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
172 shhwtstamps->hwtstamp = full_ts_in_ns;
173 }
174
175
176
177
178 if (ocelot->bridge_mask & BIT(info.port))
179 skb->offload_fwd_mark = 1;
180
181 skb->protocol = eth_type_trans(skb, dev);
182 netif_rx(skb);
183 dev->stats.rx_bytes += len;
184 dev->stats.rx_packets++;
185 } while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp));
186
187 if (err)
188 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp))
189 ocelot_read_rix(ocelot, QS_XTR_RD, grp);
190
191 return IRQ_HANDLED;
192 }
193
194 static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
195 {
196 int budget = OCELOT_PTP_QUEUE_SZ;
197 struct ocelot *ocelot = arg;
198
199 while (budget--) {
200 struct skb_shared_hwtstamps shhwtstamps;
201 struct list_head *pos, *tmp;
202 struct sk_buff *skb = NULL;
203 struct ocelot_skb *entry;
204 struct ocelot_port *port;
205 struct timespec64 ts;
206 u32 val, id, txport;
207
208 val = ocelot_read(ocelot, SYS_PTP_STATUS);
209
210
211 if (!(val & SYS_PTP_STATUS_PTP_MESS_VLD))
212 break;
213
214 WARN_ON(val & SYS_PTP_STATUS_PTP_OVFL);
215
216
217 id = SYS_PTP_STATUS_PTP_MESS_ID_X(val);
218 txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);
219
220
221 port = ocelot->ports[txport];
222
223 list_for_each_safe(pos, tmp, &port->skbs) {
224 entry = list_entry(pos, struct ocelot_skb, head);
225 if (entry->id != id)
226 continue;
227
228 skb = entry->skb;
229
230 list_del(pos);
231 kfree(entry);
232 }
233
234
235 ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
236
237 if (unlikely(!skb))
238 continue;
239
240
241 ocelot_get_hwtimestamp(ocelot, &ts);
242
243
244 memset(&shhwtstamps, 0, sizeof(shhwtstamps));
245 shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
246 skb_tstamp_tx(skb, &shhwtstamps);
247
248 dev_kfree_skb_any(skb);
249 }
250
251 return IRQ_HANDLED;
252 }
253
254 static const struct of_device_id mscc_ocelot_match[] = {
255 { .compatible = "mscc,vsc7514-switch" },
256 { }
257 };
258 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
259
260 static int mscc_ocelot_probe(struct platform_device *pdev)
261 {
262 struct device_node *np = pdev->dev.of_node;
263 struct device_node *ports, *portnp;
264 int err, irq_xtr, irq_ptp_rdy;
265 struct ocelot *ocelot;
266 struct regmap *hsio;
267 unsigned int i;
268 u32 val;
269
270 struct {
271 enum ocelot_target id;
272 char *name;
273 u8 optional:1;
274 } res[] = {
275 { SYS, "sys" },
276 { REW, "rew" },
277 { QSYS, "qsys" },
278 { ANA, "ana" },
279 { QS, "qs" },
280 { S2, "s2" },
281 { PTP, "ptp", 1 },
282 };
283
284 if (!np && !pdev->dev.platform_data)
285 return -ENODEV;
286
287 ocelot = devm_kzalloc(&pdev->dev, sizeof(*ocelot), GFP_KERNEL);
288 if (!ocelot)
289 return -ENOMEM;
290
291 platform_set_drvdata(pdev, ocelot);
292 ocelot->dev = &pdev->dev;
293
294 for (i = 0; i < ARRAY_SIZE(res); i++) {
295 struct regmap *target;
296
297 target = ocelot_io_platform_init(ocelot, pdev, res[i].name);
298 if (IS_ERR(target)) {
299 if (res[i].optional) {
300 ocelot->targets[res[i].id] = NULL;
301 continue;
302 }
303
304 return PTR_ERR(target);
305 }
306
307 ocelot->targets[res[i].id] = target;
308 }
309
310 hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
311 if (IS_ERR(hsio)) {
312 dev_err(&pdev->dev, "missing hsio syscon\n");
313 return PTR_ERR(hsio);
314 }
315
316 ocelot->targets[HSIO] = hsio;
317
318 err = ocelot_chip_init(ocelot);
319 if (err)
320 return err;
321
322 irq_xtr = platform_get_irq_byname(pdev, "xtr");
323 if (irq_xtr < 0)
324 return -ENODEV;
325
326 err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
327 ocelot_xtr_irq_handler, IRQF_ONESHOT,
328 "frame extraction", ocelot);
329 if (err)
330 return err;
331
332 irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
333 if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) {
334 err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
335 ocelot_ptp_rdy_irq_handler,
336 IRQF_ONESHOT, "ptp ready",
337 ocelot);
338 if (err)
339 return err;
340
341
342 ocelot->ptp = 1;
343 }
344
345 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
346 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
347
348 do {
349 msleep(1);
350 regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
351 &val);
352 } while (val);
353
354 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
355 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
356
357 ocelot->num_cpu_ports = 1;
358
359 ports = of_get_child_by_name(np, "ethernet-ports");
360 if (!ports) {
361 dev_err(&pdev->dev, "no ethernet-ports child node found\n");
362 return -ENODEV;
363 }
364
365 ocelot->num_phys_ports = of_get_child_count(ports);
366
367 ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
368 sizeof(struct ocelot_port *), GFP_KERNEL);
369
370 INIT_LIST_HEAD(&ocelot->multicast);
371 ocelot_init(ocelot);
372
373 for_each_available_child_of_node(ports, portnp) {
374 struct device_node *phy_node;
375 struct phy_device *phy;
376 struct resource *res;
377 struct phy *serdes;
378 void __iomem *regs;
379 char res_name[8];
380 int phy_mode;
381 u32 port;
382
383 if (of_property_read_u32(portnp, "reg", &port))
384 continue;
385
386 snprintf(res_name, sizeof(res_name), "port%d", port);
387
388 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
389 res_name);
390 regs = devm_ioremap_resource(&pdev->dev, res);
391 if (IS_ERR(regs))
392 continue;
393
394 phy_node = of_parse_phandle(portnp, "phy-handle", 0);
395 if (!phy_node)
396 continue;
397
398 phy = of_phy_find_device(phy_node);
399 of_node_put(phy_node);
400 if (!phy)
401 continue;
402
403 err = ocelot_probe_port(ocelot, port, regs, phy);
404 if (err) {
405 of_node_put(portnp);
406 goto out_put_ports;
407 }
408
409 phy_mode = of_get_phy_mode(portnp);
410 if (phy_mode < 0)
411 ocelot->ports[port]->phy_mode = PHY_INTERFACE_MODE_NA;
412 else
413 ocelot->ports[port]->phy_mode = phy_mode;
414
415 switch (ocelot->ports[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->ports[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 ocelot->ports[port]->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
461 out_put_ports:
462 of_node_put(ports);
463 return err;
464 }
465
466 static 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
478 static 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
487 module_platform_driver(mscc_ocelot_driver);
488
489 MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
490 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
491 MODULE_LICENSE("Dual MIT/GPL");