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