gpio: rcar: Fix runtime PM imbalance on error
[linux/fpc-iii.git] / drivers / net / ethernet / mscc / ocelot_board.c
blob0ac9fbf77a01da0816d60043a4bd0e9f798c5b35
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /*
3 * Microsemi Ocelot Switch driver
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>
17 #include <soc/mscc/ocelot_vcap.h>
18 #include "ocelot.h"
20 #define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
21 #define VSC7514_VCAP_IS2_CNT 64
22 #define VSC7514_VCAP_IS2_ENTRY_WIDTH 376
23 #define VSC7514_VCAP_IS2_ACTION_WIDTH 99
24 #define VSC7514_VCAP_PORT_CNT 11
26 static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info)
28 u8 llen, wlen;
29 u64 ifh[2];
31 ifh[0] = be64_to_cpu(((__force __be64 *)_ifh)[0]);
32 ifh[1] = be64_to_cpu(((__force __be64 *)_ifh)[1]);
34 wlen = IFH_EXTRACT_BITFIELD64(ifh[0], 7, 8);
35 llen = IFH_EXTRACT_BITFIELD64(ifh[0], 15, 6);
37 info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80;
39 info->timestamp = IFH_EXTRACT_BITFIELD64(ifh[0], 21, 32);
41 info->port = IFH_EXTRACT_BITFIELD64(ifh[1], 43, 4);
43 info->tag_type = IFH_EXTRACT_BITFIELD64(ifh[1], 16, 1);
44 info->vid = IFH_EXTRACT_BITFIELD64(ifh[1], 0, 12);
46 return 0;
49 static int ocelot_rx_frame_word(struct ocelot *ocelot, u8 grp, bool ifh,
50 u32 *rval)
52 u32 val;
53 u32 bytes_valid;
55 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
56 if (val == XTR_NOT_READY) {
57 if (ifh)
58 return -EIO;
60 do {
61 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
62 } while (val == XTR_NOT_READY);
65 switch (val) {
66 case XTR_ABORT:
67 return -EIO;
68 case XTR_EOF_0:
69 case XTR_EOF_1:
70 case XTR_EOF_2:
71 case XTR_EOF_3:
72 case XTR_PRUNED:
73 bytes_valid = XTR_VALID_BYTES(val);
74 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
75 if (val == XTR_ESCAPE)
76 *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
77 else
78 *rval = val;
80 return bytes_valid;
81 case XTR_ESCAPE:
82 *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
84 return 4;
85 default:
86 *rval = val;
88 return 4;
92 static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
94 struct ocelot *ocelot = arg;
95 int i = 0, grp = 0;
96 int err = 0;
98 if (!(ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)))
99 return IRQ_NONE;
101 do {
102 struct skb_shared_hwtstamps *shhwtstamps;
103 struct ocelot_port_private *priv;
104 struct ocelot_port *ocelot_port;
105 u64 tod_in_ns, full_ts_in_ns;
106 struct frame_info info = {};
107 struct net_device *dev;
108 u32 ifh[4], val, *buf;
109 struct timespec64 ts;
110 int sz, len, buf_len;
111 struct sk_buff *skb;
113 for (i = 0; i < OCELOT_TAG_LEN / 4; i++) {
114 err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]);
115 if (err != 4)
116 break;
119 if (err != 4)
120 break;
122 /* At this point the IFH was read correctly, so it is safe to
123 * presume that there is no error. The err needs to be reset
124 * otherwise a frame could come in CPU queue between the while
125 * condition and the check for error later on. And in that case
126 * the new frame is just removed and not processed.
128 err = 0;
130 ocelot_parse_ifh(ifh, &info);
132 ocelot_port = ocelot->ports[info.port];
133 priv = container_of(ocelot_port, struct ocelot_port_private,
134 port);
135 dev = priv->dev;
137 skb = netdev_alloc_skb(dev, info.len);
139 if (unlikely(!skb)) {
140 netdev_err(dev, "Unable to allocate sk_buff\n");
141 err = -ENOMEM;
142 break;
144 buf_len = info.len - ETH_FCS_LEN;
145 buf = (u32 *)skb_put(skb, buf_len);
147 len = 0;
148 do {
149 sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
150 *buf++ = val;
151 len += sz;
152 } while (len < buf_len);
154 /* Read the FCS */
155 sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
156 /* Update the statistics if part of the FCS was read before */
157 len -= ETH_FCS_LEN - sz;
159 if (unlikely(dev->features & NETIF_F_RXFCS)) {
160 buf = (u32 *)skb_put(skb, ETH_FCS_LEN);
161 *buf = val;
164 if (sz < 0) {
165 err = sz;
166 break;
169 if (ocelot->ptp) {
170 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
172 tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec);
173 if ((tod_in_ns & 0xffffffff) < info.timestamp)
174 full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) |
175 info.timestamp;
176 else
177 full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) |
178 info.timestamp;
180 shhwtstamps = skb_hwtstamps(skb);
181 memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
182 shhwtstamps->hwtstamp = full_ts_in_ns;
185 /* Everything we see on an interface that is in the HW bridge
186 * has already been forwarded.
188 if (ocelot->bridge_mask & BIT(info.port))
189 skb->offload_fwd_mark = 1;
191 skb->protocol = eth_type_trans(skb, dev);
192 netif_rx(skb);
193 dev->stats.rx_bytes += len;
194 dev->stats.rx_packets++;
195 } while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp));
197 if (err)
198 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp))
199 ocelot_read_rix(ocelot, QS_XTR_RD, grp);
201 return IRQ_HANDLED;
204 static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
206 struct ocelot *ocelot = arg;
208 ocelot_get_txtstamp(ocelot);
210 return IRQ_HANDLED;
213 static const struct of_device_id mscc_ocelot_match[] = {
214 { .compatible = "mscc,vsc7514-switch" },
217 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
219 static int ocelot_reset(struct ocelot *ocelot)
221 int retries = 100;
222 u32 val;
224 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
225 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
227 do {
228 msleep(1);
229 regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
230 &val);
231 } while (val && --retries);
233 if (!retries)
234 return -ETIMEDOUT;
236 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
237 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
239 return 0;
242 static const struct ocelot_ops ocelot_ops = {
243 .reset = ocelot_reset,
246 static const struct vcap_field vsc7514_vcap_is2_keys[] = {
247 /* Common: 46 bits */
248 [VCAP_IS2_TYPE] = { 0, 4},
249 [VCAP_IS2_HK_FIRST] = { 4, 1},
250 [VCAP_IS2_HK_PAG] = { 5, 8},
251 [VCAP_IS2_HK_IGR_PORT_MASK] = { 13, 12},
252 [VCAP_IS2_HK_RSV2] = { 25, 1},
253 [VCAP_IS2_HK_HOST_MATCH] = { 26, 1},
254 [VCAP_IS2_HK_L2_MC] = { 27, 1},
255 [VCAP_IS2_HK_L2_BC] = { 28, 1},
256 [VCAP_IS2_HK_VLAN_TAGGED] = { 29, 1},
257 [VCAP_IS2_HK_VID] = { 30, 12},
258 [VCAP_IS2_HK_DEI] = { 42, 1},
259 [VCAP_IS2_HK_PCP] = { 43, 3},
260 /* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
261 [VCAP_IS2_HK_L2_DMAC] = { 46, 48},
262 [VCAP_IS2_HK_L2_SMAC] = { 94, 48},
263 /* MAC_ETYPE (TYPE=000) */
264 [VCAP_IS2_HK_MAC_ETYPE_ETYPE] = {142, 16},
265 [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0] = {158, 16},
266 [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1] = {174, 8},
267 [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2] = {182, 3},
268 /* MAC_LLC (TYPE=001) */
269 [VCAP_IS2_HK_MAC_LLC_L2_LLC] = {142, 40},
270 /* MAC_SNAP (TYPE=010) */
271 [VCAP_IS2_HK_MAC_SNAP_L2_SNAP] = {142, 40},
272 /* MAC_ARP (TYPE=011) */
273 [VCAP_IS2_HK_MAC_ARP_SMAC] = { 46, 48},
274 [VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK] = { 94, 1},
275 [VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK] = { 95, 1},
276 [VCAP_IS2_HK_MAC_ARP_LEN_OK] = { 96, 1},
277 [VCAP_IS2_HK_MAC_ARP_TARGET_MATCH] = { 97, 1},
278 [VCAP_IS2_HK_MAC_ARP_SENDER_MATCH] = { 98, 1},
279 [VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN] = { 99, 1},
280 [VCAP_IS2_HK_MAC_ARP_OPCODE] = {100, 2},
281 [VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP] = {102, 32},
282 [VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP] = {134, 32},
283 [VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP] = {166, 1},
284 /* IP4_TCP_UDP / IP4_OTHER common */
285 [VCAP_IS2_HK_IP4] = { 46, 1},
286 [VCAP_IS2_HK_L3_FRAGMENT] = { 47, 1},
287 [VCAP_IS2_HK_L3_FRAG_OFS_GT0] = { 48, 1},
288 [VCAP_IS2_HK_L3_OPTIONS] = { 49, 1},
289 [VCAP_IS2_HK_IP4_L3_TTL_GT0] = { 50, 1},
290 [VCAP_IS2_HK_L3_TOS] = { 51, 8},
291 [VCAP_IS2_HK_L3_IP4_DIP] = { 59, 32},
292 [VCAP_IS2_HK_L3_IP4_SIP] = { 91, 32},
293 [VCAP_IS2_HK_DIP_EQ_SIP] = {123, 1},
294 /* IP4_TCP_UDP (TYPE=100) */
295 [VCAP_IS2_HK_TCP] = {124, 1},
296 [VCAP_IS2_HK_L4_SPORT] = {125, 16},
297 [VCAP_IS2_HK_L4_DPORT] = {141, 16},
298 [VCAP_IS2_HK_L4_RNG] = {157, 8},
299 [VCAP_IS2_HK_L4_SPORT_EQ_DPORT] = {165, 1},
300 [VCAP_IS2_HK_L4_SEQUENCE_EQ0] = {166, 1},
301 [VCAP_IS2_HK_L4_URG] = {167, 1},
302 [VCAP_IS2_HK_L4_ACK] = {168, 1},
303 [VCAP_IS2_HK_L4_PSH] = {169, 1},
304 [VCAP_IS2_HK_L4_RST] = {170, 1},
305 [VCAP_IS2_HK_L4_SYN] = {171, 1},
306 [VCAP_IS2_HK_L4_FIN] = {172, 1},
307 [VCAP_IS2_HK_L4_1588_DOM] = {173, 8},
308 [VCAP_IS2_HK_L4_1588_VER] = {181, 4},
309 /* IP4_OTHER (TYPE=101) */
310 [VCAP_IS2_HK_IP4_L3_PROTO] = {124, 8},
311 [VCAP_IS2_HK_L3_PAYLOAD] = {132, 56},
312 /* IP6_STD (TYPE=110) */
313 [VCAP_IS2_HK_IP6_L3_TTL_GT0] = { 46, 1},
314 [VCAP_IS2_HK_L3_IP6_SIP] = { 47, 128},
315 [VCAP_IS2_HK_IP6_L3_PROTO] = {175, 8},
316 /* OAM (TYPE=111) */
317 [VCAP_IS2_HK_OAM_MEL_FLAGS] = {142, 7},
318 [VCAP_IS2_HK_OAM_VER] = {149, 5},
319 [VCAP_IS2_HK_OAM_OPCODE] = {154, 8},
320 [VCAP_IS2_HK_OAM_FLAGS] = {162, 8},
321 [VCAP_IS2_HK_OAM_MEPID] = {170, 16},
322 [VCAP_IS2_HK_OAM_CCM_CNTS_EQ0] = {186, 1},
323 [VCAP_IS2_HK_OAM_IS_Y1731] = {187, 1},
326 static const struct vcap_field vsc7514_vcap_is2_actions[] = {
327 [VCAP_IS2_ACT_HIT_ME_ONCE] = { 0, 1},
328 [VCAP_IS2_ACT_CPU_COPY_ENA] = { 1, 1},
329 [VCAP_IS2_ACT_CPU_QU_NUM] = { 2, 3},
330 [VCAP_IS2_ACT_MASK_MODE] = { 5, 2},
331 [VCAP_IS2_ACT_MIRROR_ENA] = { 7, 1},
332 [VCAP_IS2_ACT_LRN_DIS] = { 8, 1},
333 [VCAP_IS2_ACT_POLICE_ENA] = { 9, 1},
334 [VCAP_IS2_ACT_POLICE_IDX] = { 10, 9},
335 [VCAP_IS2_ACT_POLICE_VCAP_ONLY] = { 19, 1},
336 [VCAP_IS2_ACT_PORT_MASK] = { 20, 11},
337 [VCAP_IS2_ACT_REW_OP] = { 31, 9},
338 [VCAP_IS2_ACT_SMAC_REPLACE_ENA] = { 40, 1},
339 [VCAP_IS2_ACT_RSV] = { 41, 2},
340 [VCAP_IS2_ACT_ACL_ID] = { 43, 6},
341 [VCAP_IS2_ACT_HIT_CNT] = { 49, 32},
344 static const struct vcap_props vsc7514_vcap_props[] = {
345 [VCAP_IS2] = {
346 .tg_width = 2,
347 .sw_count = 4,
348 .entry_count = VSC7514_VCAP_IS2_CNT,
349 .entry_width = VSC7514_VCAP_IS2_ENTRY_WIDTH,
350 .action_count = VSC7514_VCAP_IS2_CNT +
351 VSC7514_VCAP_PORT_CNT + 2,
352 .action_width = 99,
353 .action_type_width = 1,
354 .action_table = {
355 [IS2_ACTION_TYPE_NORMAL] = {
356 .width = 49,
357 .count = 2
359 [IS2_ACTION_TYPE_SMAC_SIP] = {
360 .width = 6,
361 .count = 4
364 .counter_words = 4,
365 .counter_width = 32,
369 static int mscc_ocelot_probe(struct platform_device *pdev)
371 struct device_node *np = pdev->dev.of_node;
372 struct device_node *ports, *portnp;
373 int err, irq_xtr, irq_ptp_rdy;
374 struct ocelot *ocelot;
375 struct regmap *hsio;
376 unsigned int i;
378 struct {
379 enum ocelot_target id;
380 char *name;
381 u8 optional:1;
382 } io_target[] = {
383 { SYS, "sys" },
384 { REW, "rew" },
385 { QSYS, "qsys" },
386 { ANA, "ana" },
387 { QS, "qs" },
388 { S2, "s2" },
389 { PTP, "ptp", 1 },
392 if (!np && !pdev->dev.platform_data)
393 return -ENODEV;
395 ocelot = devm_kzalloc(&pdev->dev, sizeof(*ocelot), GFP_KERNEL);
396 if (!ocelot)
397 return -ENOMEM;
399 platform_set_drvdata(pdev, ocelot);
400 ocelot->dev = &pdev->dev;
402 for (i = 0; i < ARRAY_SIZE(io_target); i++) {
403 struct regmap *target;
404 struct resource *res;
406 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
407 io_target[i].name);
409 target = ocelot_regmap_init(ocelot, res);
410 if (IS_ERR(target)) {
411 if (io_target[i].optional) {
412 ocelot->targets[io_target[i].id] = NULL;
413 continue;
415 return PTR_ERR(target);
418 ocelot->targets[io_target[i].id] = target;
421 hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
422 if (IS_ERR(hsio)) {
423 dev_err(&pdev->dev, "missing hsio syscon\n");
424 return PTR_ERR(hsio);
427 ocelot->targets[HSIO] = hsio;
429 err = ocelot_chip_init(ocelot, &ocelot_ops);
430 if (err)
431 return err;
433 irq_xtr = platform_get_irq_byname(pdev, "xtr");
434 if (irq_xtr < 0)
435 return -ENODEV;
437 err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
438 ocelot_xtr_irq_handler, IRQF_ONESHOT,
439 "frame extraction", ocelot);
440 if (err)
441 return err;
443 irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
444 if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) {
445 err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
446 ocelot_ptp_rdy_irq_handler,
447 IRQF_ONESHOT, "ptp ready",
448 ocelot);
449 if (err)
450 return err;
452 /* Both the PTP interrupt and the PTP bank are available */
453 ocelot->ptp = 1;
456 ports = of_get_child_by_name(np, "ethernet-ports");
457 if (!ports) {
458 dev_err(&pdev->dev, "no ethernet-ports child node found\n");
459 return -ENODEV;
462 ocelot->num_phys_ports = of_get_child_count(ports);
464 ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
465 sizeof(struct ocelot_port *), GFP_KERNEL);
467 ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
468 ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
469 ocelot->vcap = vsc7514_vcap_props;
471 ocelot_init(ocelot);
472 /* No NPI port */
473 ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
474 OCELOT_TAG_PREFIX_NONE);
476 for_each_available_child_of_node(ports, portnp) {
477 struct ocelot_port_private *priv;
478 struct ocelot_port *ocelot_port;
479 struct device_node *phy_node;
480 phy_interface_t phy_mode;
481 struct phy_device *phy;
482 struct resource *res;
483 struct phy *serdes;
484 void __iomem *regs;
485 char res_name[8];
486 u32 port;
488 if (of_property_read_u32(portnp, "reg", &port))
489 continue;
491 snprintf(res_name, sizeof(res_name), "port%d", port);
493 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
494 res_name);
495 regs = devm_ioremap_resource(&pdev->dev, res);
496 if (IS_ERR(regs))
497 continue;
499 phy_node = of_parse_phandle(portnp, "phy-handle", 0);
500 if (!phy_node)
501 continue;
503 phy = of_phy_find_device(phy_node);
504 of_node_put(phy_node);
505 if (!phy)
506 continue;
508 err = ocelot_probe_port(ocelot, port, regs, phy);
509 if (err) {
510 of_node_put(portnp);
511 goto out_put_ports;
514 ocelot_port = ocelot->ports[port];
515 priv = container_of(ocelot_port, struct ocelot_port_private,
516 port);
518 of_get_phy_mode(portnp, &phy_mode);
520 ocelot_port->phy_mode = phy_mode;
522 switch (ocelot_port->phy_mode) {
523 case PHY_INTERFACE_MODE_NA:
524 continue;
525 case PHY_INTERFACE_MODE_SGMII:
526 break;
527 case PHY_INTERFACE_MODE_QSGMII:
528 /* Ensure clock signals and speed is set on all
529 * QSGMII links
531 ocelot_port_writel(ocelot_port,
532 DEV_CLOCK_CFG_LINK_SPEED
533 (OCELOT_SPEED_1000),
534 DEV_CLOCK_CFG);
535 break;
536 default:
537 dev_err(ocelot->dev,
538 "invalid phy mode for port%d, (Q)SGMII only\n",
539 port);
540 of_node_put(portnp);
541 err = -EINVAL;
542 goto out_put_ports;
545 serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
546 if (IS_ERR(serdes)) {
547 err = PTR_ERR(serdes);
548 if (err == -EPROBE_DEFER)
549 dev_dbg(ocelot->dev, "deferring probe\n");
550 else
551 dev_err(ocelot->dev,
552 "missing SerDes phys for port%d\n",
553 port);
555 of_node_put(portnp);
556 goto out_put_ports;
559 priv->serdes = serdes;
562 register_netdevice_notifier(&ocelot_netdevice_nb);
563 register_switchdev_notifier(&ocelot_switchdev_nb);
564 register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
566 dev_info(&pdev->dev, "Ocelot switch probed\n");
568 out_put_ports:
569 of_node_put(ports);
570 return err;
573 static int mscc_ocelot_remove(struct platform_device *pdev)
575 struct ocelot *ocelot = platform_get_drvdata(pdev);
577 ocelot_deinit(ocelot);
578 unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
579 unregister_switchdev_notifier(&ocelot_switchdev_nb);
580 unregister_netdevice_notifier(&ocelot_netdevice_nb);
582 return 0;
585 static struct platform_driver mscc_ocelot_driver = {
586 .probe = mscc_ocelot_probe,
587 .remove = mscc_ocelot_remove,
588 .driver = {
589 .name = "ocelot-switch",
590 .of_match_table = mscc_ocelot_match,
594 module_platform_driver(mscc_ocelot_driver);
596 MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
597 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
598 MODULE_LICENSE("Dual MIT/GPL");