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/dsa/ocelot.h> 8 #include <linux/interrupt.h> 9 #include <linux/module.h> 10 #include <linux/of_net.h> 11 #include <linux/netdevice.h> 12 #include <linux/phylink.h> 13 #include <linux/of.h> 14 #include <linux/of_mdio.h> 15 #include <linux/platform_device.h> 16 #include <linux/mfd/syscon.h> 17 #include <linux/skbuff.h> 18 #include <net/switchdev.h> 19 20 #include <soc/mscc/ocelot.h> 21 #include <soc/mscc/ocelot_vcap.h> 22 #include <soc/mscc/vsc7514_regs.h> 23 #include "ocelot_fdma.h" 24 #include "ocelot.h" 25 26 #define VSC7514_VCAP_POLICER_BASE 128 27 #define VSC7514_VCAP_POLICER_MAX 191 28 29 static int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops) 30 { 31 int ret; 32 33 ocelot->map = vsc7514_regmap; 34 ocelot->num_mact_rows = 1024; 35 ocelot->ops = ops; 36 37 ret = ocelot_regfields_init(ocelot, vsc7514_regfields); 38 if (ret) 39 return ret; 40 41 ocelot_pll5_init(ocelot); 42 43 eth_random_addr(ocelot->base_mac); 44 ocelot->base_mac[5] &= 0xf0; 45 46 return 0; 47 } 48 49 static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg) 50 { 51 struct ocelot *ocelot = arg; 52 int grp = 0, err; 53 54 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)) { 55 struct sk_buff *skb; 56 57 err = ocelot_xtr_poll_frame(ocelot, grp, &skb); 58 if (err) 59 goto out; 60 61 skb->dev->stats.rx_bytes += skb->len; 62 skb->dev->stats.rx_packets++; 63 64 if (!skb_defer_rx_timestamp(skb)) 65 netif_rx(skb); 66 } 67 68 out: 69 if (err < 0) 70 ocelot_drain_cpu_queue(ocelot, 0); 71 72 return IRQ_HANDLED; 73 } 74 75 static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg) 76 { 77 struct ocelot *ocelot = arg; 78 79 ocelot_get_txtstamp(ocelot); 80 81 return IRQ_HANDLED; 82 } 83 84 static const struct of_device_id mscc_ocelot_match[] = { 85 { .compatible = "mscc,vsc7514-switch" }, 86 { } 87 }; 88 MODULE_DEVICE_TABLE(of, mscc_ocelot_match); 89 90 static const struct ocelot_ops ocelot_ops = { 91 .reset = ocelot_reset, 92 .wm_enc = ocelot_wm_enc, 93 .wm_dec = ocelot_wm_dec, 94 .wm_stat = ocelot_wm_stat, 95 .port_to_netdev = ocelot_port_to_netdev, 96 .netdev_to_port = ocelot_netdev_to_port, 97 }; 98 99 static struct ptp_clock_info ocelot_ptp_clock_info = { 100 .owner = THIS_MODULE, 101 .name = "ocelot ptp", 102 .max_adj = 0x7fffffff, 103 .n_alarm = 0, 104 .n_ext_ts = 0, 105 .n_per_out = OCELOT_PTP_PINS_NUM, 106 .n_pins = OCELOT_PTP_PINS_NUM, 107 .pps = 0, 108 .gettime64 = ocelot_ptp_gettime64, 109 .settime64 = ocelot_ptp_settime64, 110 .adjtime = ocelot_ptp_adjtime, 111 .adjfine = ocelot_ptp_adjfine, 112 .verify = ocelot_ptp_verify, 113 .enable = ocelot_ptp_enable, 114 }; 115 116 static void mscc_ocelot_teardown_devlink_ports(struct ocelot *ocelot) 117 { 118 int port; 119 120 for (port = 0; port < ocelot->num_phys_ports; port++) 121 ocelot_port_devlink_teardown(ocelot, port); 122 } 123 124 static void mscc_ocelot_release_ports(struct ocelot *ocelot) 125 { 126 int port; 127 128 for (port = 0; port < ocelot->num_phys_ports; port++) { 129 struct ocelot_port *ocelot_port; 130 131 ocelot_port = ocelot->ports[port]; 132 if (!ocelot_port) 133 continue; 134 135 ocelot_deinit_port(ocelot, port); 136 ocelot_release_port(ocelot_port); 137 } 138 } 139 140 static int mscc_ocelot_init_ports(struct platform_device *pdev, 141 struct device_node *ports) 142 { 143 struct ocelot *ocelot = platform_get_drvdata(pdev); 144 u32 devlink_ports_registered = 0; 145 struct device_node *portnp; 146 int port, err; 147 u32 reg; 148 149 ocelot->ports = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports, 150 sizeof(struct ocelot_port *), GFP_KERNEL); 151 if (!ocelot->ports) 152 return -ENOMEM; 153 154 ocelot->devlink_ports = devm_kcalloc(ocelot->dev, 155 ocelot->num_phys_ports, 156 sizeof(*ocelot->devlink_ports), 157 GFP_KERNEL); 158 if (!ocelot->devlink_ports) 159 return -ENOMEM; 160 161 for_each_available_child_of_node(ports, portnp) { 162 struct regmap *target; 163 struct resource *res; 164 char res_name[8]; 165 166 if (of_property_read_u32(portnp, "reg", ®)) 167 continue; 168 169 port = reg; 170 if (port < 0 || port >= ocelot->num_phys_ports) { 171 dev_err(ocelot->dev, 172 "invalid port number: %d >= %d\n", port, 173 ocelot->num_phys_ports); 174 continue; 175 } 176 177 snprintf(res_name, sizeof(res_name), "port%d", port); 178 179 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 180 res_name); 181 target = ocelot_regmap_init(ocelot, res); 182 if (IS_ERR(target)) { 183 err = PTR_ERR(target); 184 of_node_put(portnp); 185 goto out_teardown; 186 } 187 188 err = ocelot_port_devlink_init(ocelot, port, 189 DEVLINK_PORT_FLAVOUR_PHYSICAL); 190 if (err) { 191 of_node_put(portnp); 192 goto out_teardown; 193 } 194 195 err = ocelot_probe_port(ocelot, port, target, portnp); 196 if (err) { 197 ocelot_port_devlink_teardown(ocelot, port); 198 continue; 199 } 200 201 devlink_ports_registered |= BIT(port); 202 } 203 204 /* Initialize unused devlink ports at the end */ 205 for (port = 0; port < ocelot->num_phys_ports; port++) { 206 if (devlink_ports_registered & BIT(port)) 207 continue; 208 209 err = ocelot_port_devlink_init(ocelot, port, 210 DEVLINK_PORT_FLAVOUR_UNUSED); 211 if (err) 212 goto out_teardown; 213 214 devlink_ports_registered |= BIT(port); 215 } 216 217 return 0; 218 219 out_teardown: 220 /* Unregister the network interfaces */ 221 mscc_ocelot_release_ports(ocelot); 222 /* Tear down devlink ports for the registered network interfaces */ 223 for (port = 0; port < ocelot->num_phys_ports; port++) { 224 if (devlink_ports_registered & BIT(port)) 225 ocelot_port_devlink_teardown(ocelot, port); 226 } 227 return err; 228 } 229 230 static int mscc_ocelot_probe(struct platform_device *pdev) 231 { 232 struct device_node *np = pdev->dev.of_node; 233 int err, irq_xtr, irq_ptp_rdy; 234 struct device_node *ports; 235 struct devlink *devlink; 236 struct ocelot *ocelot; 237 struct regmap *hsio; 238 unsigned int i; 239 240 struct { 241 enum ocelot_target id; 242 char *name; 243 u8 optional:1; 244 } io_target[] = { 245 { SYS, "sys" }, 246 { REW, "rew" }, 247 { QSYS, "qsys" }, 248 { ANA, "ana" }, 249 { QS, "qs" }, 250 { S0, "s0" }, 251 { S1, "s1" }, 252 { S2, "s2" }, 253 { PTP, "ptp", 1 }, 254 { FDMA, "fdma", 1 }, 255 }; 256 257 if (!np && !pdev->dev.platform_data) 258 return -ENODEV; 259 260 devlink = 261 devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot), &pdev->dev); 262 if (!devlink) 263 return -ENOMEM; 264 265 ocelot = devlink_priv(devlink); 266 ocelot->devlink = priv_to_devlink(ocelot); 267 platform_set_drvdata(pdev, ocelot); 268 ocelot->dev = &pdev->dev; 269 270 for (i = 0; i < ARRAY_SIZE(io_target); i++) { 271 struct regmap *target; 272 struct resource *res; 273 274 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 275 io_target[i].name); 276 277 target = ocelot_regmap_init(ocelot, res); 278 if (IS_ERR(target)) { 279 if (io_target[i].optional) { 280 ocelot->targets[io_target[i].id] = NULL; 281 continue; 282 } 283 err = PTR_ERR(target); 284 goto out_free_devlink; 285 } 286 287 ocelot->targets[io_target[i].id] = target; 288 } 289 290 if (ocelot->targets[FDMA]) 291 ocelot_fdma_init(pdev, ocelot); 292 293 hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio"); 294 if (IS_ERR(hsio)) { 295 dev_err(&pdev->dev, "missing hsio syscon\n"); 296 err = PTR_ERR(hsio); 297 goto out_free_devlink; 298 } 299 300 ocelot->targets[HSIO] = hsio; 301 302 err = ocelot_chip_init(ocelot, &ocelot_ops); 303 if (err) 304 goto out_free_devlink; 305 306 irq_xtr = platform_get_irq_byname(pdev, "xtr"); 307 if (irq_xtr < 0) { 308 err = irq_xtr; 309 goto out_free_devlink; 310 } 311 312 err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL, 313 ocelot_xtr_irq_handler, IRQF_ONESHOT, 314 "frame extraction", ocelot); 315 if (err) 316 goto out_free_devlink; 317 318 irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy"); 319 if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) { 320 err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL, 321 ocelot_ptp_rdy_irq_handler, 322 IRQF_ONESHOT, "ptp ready", 323 ocelot); 324 if (err) 325 goto out_free_devlink; 326 327 /* Both the PTP interrupt and the PTP bank are available */ 328 ocelot->ptp = 1; 329 } 330 331 ports = of_get_child_by_name(np, "ethernet-ports"); 332 if (!ports) { 333 dev_err(ocelot->dev, "no ethernet-ports child node found\n"); 334 err = -ENODEV; 335 goto out_free_devlink; 336 } 337 338 ocelot->num_phys_ports = of_get_child_count(ports); 339 ocelot->num_flooding_pgids = 1; 340 341 ocelot->vcap = vsc7514_vcap_props; 342 343 ocelot->vcap_pol.base = VSC7514_VCAP_POLICER_BASE; 344 ocelot->vcap_pol.max = VSC7514_VCAP_POLICER_MAX; 345 346 ocelot->npi = -1; 347 348 err = ocelot_init(ocelot); 349 if (err) 350 goto out_put_ports; 351 352 err = mscc_ocelot_init_ports(pdev, ports); 353 if (err) 354 goto out_ocelot_devlink_unregister; 355 356 if (ocelot->fdma) 357 ocelot_fdma_start(ocelot); 358 359 err = ocelot_devlink_sb_register(ocelot); 360 if (err) 361 goto out_ocelot_release_ports; 362 363 if (ocelot->ptp) { 364 err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info); 365 if (err) { 366 dev_err(ocelot->dev, 367 "Timestamp initialization failed\n"); 368 ocelot->ptp = 0; 369 } 370 } 371 372 register_netdevice_notifier(&ocelot_netdevice_nb); 373 register_switchdev_notifier(&ocelot_switchdev_nb); 374 register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb); 375 376 of_node_put(ports); 377 devlink_register(devlink); 378 379 dev_info(&pdev->dev, "Ocelot switch probed\n"); 380 381 return 0; 382 383 out_ocelot_release_ports: 384 mscc_ocelot_release_ports(ocelot); 385 mscc_ocelot_teardown_devlink_ports(ocelot); 386 out_ocelot_devlink_unregister: 387 ocelot_deinit(ocelot); 388 out_put_ports: 389 of_node_put(ports); 390 out_free_devlink: 391 devlink_free(devlink); 392 return err; 393 } 394 395 static int mscc_ocelot_remove(struct platform_device *pdev) 396 { 397 struct ocelot *ocelot = platform_get_drvdata(pdev); 398 399 if (ocelot->fdma) 400 ocelot_fdma_deinit(ocelot); 401 devlink_unregister(ocelot->devlink); 402 ocelot_deinit_timestamp(ocelot); 403 ocelot_devlink_sb_unregister(ocelot); 404 mscc_ocelot_release_ports(ocelot); 405 mscc_ocelot_teardown_devlink_ports(ocelot); 406 ocelot_deinit(ocelot); 407 unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb); 408 unregister_switchdev_notifier(&ocelot_switchdev_nb); 409 unregister_netdevice_notifier(&ocelot_netdevice_nb); 410 devlink_free(ocelot->devlink); 411 412 return 0; 413 } 414 415 static struct platform_driver mscc_ocelot_driver = { 416 .probe = mscc_ocelot_probe, 417 .remove = mscc_ocelot_remove, 418 .driver = { 419 .name = "ocelot-switch", 420 .of_match_table = mscc_ocelot_match, 421 }, 422 }; 423 424 module_platform_driver(mscc_ocelot_driver); 425 426 MODULE_DESCRIPTION("Microsemi Ocelot switch driver"); 427 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>"); 428 MODULE_LICENSE("Dual MIT/GPL"); 429