• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
20 
ocelot_parse_ifh(u32 * _ifh,struct frame_info * info)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 
ocelot_rx_frame_word(struct ocelot * ocelot,u8 grp,bool ifh,u32 * rval)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 
ocelot_xtr_irq_handler(int irq,void * arg)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 		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 		}
126 		buf_len = info.len - ETH_FCS_LEN;
127 		buf = (u32 *)skb_put(skb, buf_len);
128 
129 		len = 0;
130 		do {
131 			sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
132 			*buf++ = val;
133 			len += sz;
134 		} while (len < buf_len);
135 
136 		/* Read the FCS */
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;
140 
141 		if (unlikely(dev->features & NETIF_F_RXFCS)) {
142 			buf = (u32 *)skb_put(skb, ETH_FCS_LEN);
143 			*buf = val;
144 		}
145 
146 		if (sz < 0) {
147 			err = sz;
148 			break;
149 		}
150 
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 
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 
ocelot_ptp_rdy_irq_handler(int irq,void * arg)186 static 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 
246 static const struct of_device_id mscc_ocelot_match[] = {
247 	{ .compatible = "mscc,vsc7514-switch" },
248 	{ }
249 };
250 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
251 
mscc_ocelot_probe(struct platform_device * pdev)252 static int mscc_ocelot_probe(struct platform_device *pdev)
253 {
254 	struct device_node *np = pdev->dev.of_node;
255 	struct device_node *ports, *portnp;
256 	int err, irq_xtr, irq_ptp_rdy;
257 	struct ocelot *ocelot;
258 	struct regmap *hsio;
259 	unsigned int i;
260 	u32 val;
261 
262 	struct {
263 		enum ocelot_target id;
264 		char *name;
265 		u8 optional:1;
266 	} res[] = {
267 		{ SYS, "sys" },
268 		{ REW, "rew" },
269 		{ QSYS, "qsys" },
270 		{ ANA, "ana" },
271 		{ QS, "qs" },
272 		{ S2, "s2" },
273 		{ PTP, "ptp", 1 },
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);
290 		if (IS_ERR(target)) {
291 			if (res[i].optional) {
292 				ocelot->targets[res[i].id] = NULL;
293 				continue;
294 			}
295 
296 			return PTR_ERR(target);
297 		}
298 
299 		ocelot->targets[res[i].id] = target;
300 	}
301 
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 
310 	err = ocelot_chip_init(ocelot);
311 	if (err)
312 		return err;
313 
314 	irq_xtr = platform_get_irq_byname(pdev, "xtr");
315 	if (irq_xtr < 0)
316 		return -ENODEV;
317 
318 	err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
319 					ocelot_xtr_irq_handler, IRQF_ONESHOT,
320 					"frame extraction", ocelot);
321 	if (err)
322 		return err;
323 
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 
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 
365 	for_each_available_child_of_node(ports, portnp) {
366 		struct device_node *phy_node;
367 		struct phy_device *phy;
368 		struct resource *res;
369 		struct phy *serdes;
370 		void __iomem *regs;
371 		char res_name[8];
372 		int phy_mode;
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);
391 		of_node_put(phy_node);
392 		if (!phy)
393 			continue;
394 
395 		err = ocelot_probe_port(ocelot, port, regs, phy);
396 		if (err) {
397 			of_node_put(portnp);
398 			goto out_put_ports;
399 		}
400 
401 		phy_mode = of_get_phy_mode(portnp);
402 		if (phy_mode < 0)
403 			ocelot->ports[port]->phy_mode = PHY_INTERFACE_MODE_NA;
404 		else
405 			ocelot->ports[port]->phy_mode = phy_mode;
406 
407 		switch (ocelot->ports[port]->phy_mode) {
408 		case PHY_INTERFACE_MODE_NA:
409 			continue;
410 		case PHY_INTERFACE_MODE_SGMII:
411 			break;
412 		case PHY_INTERFACE_MODE_QSGMII:
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);
420 			break;
421 		default:
422 			dev_err(ocelot->dev,
423 				"invalid phy mode for port%d, (Q)SGMII only\n",
424 				port);
425 			of_node_put(portnp);
426 			err = -EINVAL;
427 			goto out_put_ports;
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 
440 			of_node_put(portnp);
441 			goto out_put_ports;
442 		}
443 
444 		ocelot->ports[port]->serdes = serdes;
445 	}
446 
447 	register_netdevice_notifier(&ocelot_netdevice_nb);
448 	register_switchdev_notifier(&ocelot_switchdev_nb);
449 	register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
450 
451 	dev_info(&pdev->dev, "Ocelot switch probed\n");
452 
453 out_put_ports:
454 	of_node_put(ports);
455 	return err;
456 }
457 
mscc_ocelot_remove(struct platform_device * pdev)458 static int mscc_ocelot_remove(struct platform_device *pdev)
459 {
460 	struct ocelot *ocelot = platform_get_drvdata(pdev);
461 
462 	ocelot_deinit(ocelot);
463 	unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
464 	unregister_switchdev_notifier(&ocelot_switchdev_nb);
465 	unregister_netdevice_notifier(&ocelot_netdevice_nb);
466 
467 	return 0;
468 }
469 
470 static 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 
479 module_platform_driver(mscc_ocelot_driver);
480 
481 MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
482 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
483 MODULE_LICENSE("Dual MIT/GPL");
484