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