Merge tag 'libnvdimm-for-4.19_dax-memory-failure' of gitolite.kernel.org:pub/scm...
[linux-block.git] / drivers / net / ethernet / mscc / ocelot_board.c
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/netdevice.h>
10 #include <linux/of_mdio.h>
11 #include <linux/of_platform.h>
12 #include <linux/skbuff.h>
13
14 #include "ocelot.h"
15
16 static int ocelot_parse_ifh(u32 *ifh, struct frame_info *info)
17 {
18         int i;
19         u8 llen, wlen;
20
21         /* The IFH is in network order, switch to CPU order */
22         for (i = 0; i < IFH_LEN; i++)
23                 ifh[i] = ntohl((__force __be32)ifh[i]);
24
25         wlen = (ifh[1] >> 7) & 0xff;
26         llen = (ifh[1] >> 15) & 0x3f;
27         info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80;
28
29         info->port = (ifh[2] & GENMASK(14, 11)) >> 11;
30
31         info->cpuq = (ifh[3] & GENMASK(27, 20)) >> 20;
32         info->tag_type = (ifh[3] & BIT(16)) >> 16;
33         info->vid = ifh[3] & GENMASK(11, 0);
34
35         return 0;
36 }
37
38 static int ocelot_rx_frame_word(struct ocelot *ocelot, u8 grp, bool ifh,
39                                 u32 *rval)
40 {
41         u32 val;
42         u32 bytes_valid;
43
44         val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
45         if (val == XTR_NOT_READY) {
46                 if (ifh)
47                         return -EIO;
48
49                 do {
50                         val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
51                 } while (val == XTR_NOT_READY);
52         }
53
54         switch (val) {
55         case XTR_ABORT:
56                 return -EIO;
57         case XTR_EOF_0:
58         case XTR_EOF_1:
59         case XTR_EOF_2:
60         case XTR_EOF_3:
61         case XTR_PRUNED:
62                 bytes_valid = XTR_VALID_BYTES(val);
63                 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
64                 if (val == XTR_ESCAPE)
65                         *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
66                 else
67                         *rval = val;
68
69                 return bytes_valid;
70         case XTR_ESCAPE:
71                 *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
72
73                 return 4;
74         default:
75                 *rval = val;
76
77                 return 4;
78         }
79 }
80
81 static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
82 {
83         struct ocelot *ocelot = arg;
84         int i = 0, grp = 0;
85         int err = 0;
86
87         if (!(ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)))
88                 return IRQ_NONE;
89
90         do {
91                 struct sk_buff *skb;
92                 struct net_device *dev;
93                 u32 *buf;
94                 int sz, len;
95                 u32 ifh[4];
96                 u32 val;
97                 struct frame_info info;
98
99                 for (i = 0; i < IFH_LEN; i++) {
100                         err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]);
101                         if (err != 4)
102                                 break;
103                 }
104
105                 if (err != 4)
106                         break;
107
108                 ocelot_parse_ifh(ifh, &info);
109
110                 dev = ocelot->ports[info.port]->dev;
111
112                 skb = netdev_alloc_skb(dev, info.len);
113
114                 if (unlikely(!skb)) {
115                         netdev_err(dev, "Unable to allocate sk_buff\n");
116                         err = -ENOMEM;
117                         break;
118                 }
119                 buf = (u32 *)skb_put(skb, info.len);
120
121                 len = 0;
122                 do {
123                         sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
124                         *buf++ = val;
125                         len += sz;
126                 } while ((sz == 4) && (len < info.len));
127
128                 if (sz < 0) {
129                         err = sz;
130                         break;
131                 }
132
133                 /* Everything we see on an interface that is in the HW bridge
134                  * has already been forwarded.
135                  */
136                 if (ocelot->bridge_mask & BIT(info.port))
137                         skb->offload_fwd_mark = 1;
138
139                 skb->protocol = eth_type_trans(skb, dev);
140                 netif_rx(skb);
141                 dev->stats.rx_bytes += len;
142                 dev->stats.rx_packets++;
143         } while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp));
144
145         if (err)
146                 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp))
147                         ocelot_read_rix(ocelot, QS_XTR_RD, grp);
148
149         return IRQ_HANDLED;
150 }
151
152 static const struct of_device_id mscc_ocelot_match[] = {
153         { .compatible = "mscc,vsc7514-switch" },
154         { }
155 };
156 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
157
158 static int mscc_ocelot_probe(struct platform_device *pdev)
159 {
160         int err, irq;
161         unsigned int i;
162         struct device_node *np = pdev->dev.of_node;
163         struct device_node *ports, *portnp;
164         struct ocelot *ocelot;
165         u32 val;
166
167         struct {
168                 enum ocelot_target id;
169                 char *name;
170         } res[] = {
171                 { SYS, "sys" },
172                 { REW, "rew" },
173                 { QSYS, "qsys" },
174                 { ANA, "ana" },
175                 { QS, "qs" },
176                 { HSIO, "hsio" },
177         };
178
179         if (!np && !pdev->dev.platform_data)
180                 return -ENODEV;
181
182         ocelot = devm_kzalloc(&pdev->dev, sizeof(*ocelot), GFP_KERNEL);
183         if (!ocelot)
184                 return -ENOMEM;
185
186         platform_set_drvdata(pdev, ocelot);
187         ocelot->dev = &pdev->dev;
188
189         for (i = 0; i < ARRAY_SIZE(res); i++) {
190                 struct regmap *target;
191
192                 target = ocelot_io_platform_init(ocelot, pdev, res[i].name);
193                 if (IS_ERR(target))
194                         return PTR_ERR(target);
195
196                 ocelot->targets[res[i].id] = target;
197         }
198
199         err = ocelot_chip_init(ocelot);
200         if (err)
201                 return err;
202
203         irq = platform_get_irq_byname(pdev, "xtr");
204         if (irq < 0)
205                 return -ENODEV;
206
207         err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
208                                         ocelot_xtr_irq_handler, IRQF_ONESHOT,
209                                         "frame extraction", ocelot);
210         if (err)
211                 return err;
212
213         regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
214         regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
215
216         do {
217                 msleep(1);
218                 regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
219                                   &val);
220         } while (val);
221
222         regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
223         regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
224
225         ocelot->num_cpu_ports = 1; /* 1 port on the switch, two groups */
226
227         ports = of_get_child_by_name(np, "ethernet-ports");
228         if (!ports) {
229                 dev_err(&pdev->dev, "no ethernet-ports child node found\n");
230                 return -ENODEV;
231         }
232
233         ocelot->num_phys_ports = of_get_child_count(ports);
234
235         ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
236                                      sizeof(struct ocelot_port *), GFP_KERNEL);
237
238         INIT_LIST_HEAD(&ocelot->multicast);
239         ocelot_init(ocelot);
240
241         ocelot_rmw(ocelot, HSIO_HW_CFG_DEV1G_4_MODE |
242                      HSIO_HW_CFG_DEV1G_6_MODE |
243                      HSIO_HW_CFG_DEV1G_9_MODE,
244                      HSIO_HW_CFG_DEV1G_4_MODE |
245                      HSIO_HW_CFG_DEV1G_6_MODE |
246                      HSIO_HW_CFG_DEV1G_9_MODE,
247                      HSIO_HW_CFG);
248
249         for_each_available_child_of_node(ports, portnp) {
250                 struct device_node *phy_node;
251                 struct phy_device *phy;
252                 struct resource *res;
253                 void __iomem *regs;
254                 char res_name[8];
255                 u32 port;
256
257                 if (of_property_read_u32(portnp, "reg", &port))
258                         continue;
259
260                 snprintf(res_name, sizeof(res_name), "port%d", port);
261
262                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
263                                                    res_name);
264                 regs = devm_ioremap_resource(&pdev->dev, res);
265                 if (IS_ERR(regs))
266                         continue;
267
268                 phy_node = of_parse_phandle(portnp, "phy-handle", 0);
269                 if (!phy_node)
270                         continue;
271
272                 phy = of_phy_find_device(phy_node);
273                 if (!phy)
274                         continue;
275
276                 err = ocelot_probe_port(ocelot, port, regs, phy);
277                 if (err) {
278                         dev_err(&pdev->dev, "failed to probe ports\n");
279                         goto err_probe_ports;
280                 }
281         }
282
283         register_netdevice_notifier(&ocelot_netdevice_nb);
284
285         dev_info(&pdev->dev, "Ocelot switch probed\n");
286
287         return 0;
288
289 err_probe_ports:
290         return err;
291 }
292
293 static int mscc_ocelot_remove(struct platform_device *pdev)
294 {
295         struct ocelot *ocelot = platform_get_drvdata(pdev);
296
297         ocelot_deinit(ocelot);
298         unregister_netdevice_notifier(&ocelot_netdevice_nb);
299
300         return 0;
301 }
302
303 static struct platform_driver mscc_ocelot_driver = {
304         .probe = mscc_ocelot_probe,
305         .remove = mscc_ocelot_remove,
306         .driver = {
307                 .name = "ocelot-switch",
308                 .of_match_table = mscc_ocelot_match,
309         },
310 };
311
312 module_platform_driver(mscc_ocelot_driver);
313
314 MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
315 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
316 MODULE_LICENSE("Dual MIT/GPL");