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 .supported_perout_flags = PTP_PEROUT_DUTY_CYCLE | 112 PTP_PEROUT_PHASE, 113 .pps = 0, 114 .gettime64 = ocelot_ptp_gettime64, 115 .settime64 = ocelot_ptp_settime64, 116 .adjtime = ocelot_ptp_adjtime, 117 .adjfine = ocelot_ptp_adjfine, 118 .verify = ocelot_ptp_verify, 119 .enable = ocelot_ptp_enable, 120 }; 121 122 static void mscc_ocelot_teardown_devlink_ports(struct ocelot *ocelot) 123 { 124 int port; 125 126 for (port = 0; port < ocelot->num_phys_ports; port++) 127 ocelot_port_devlink_teardown(ocelot, port); 128 } 129 130 static void mscc_ocelot_release_ports(struct ocelot *ocelot) 131 { 132 int port; 133 134 for (port = 0; port < ocelot->num_phys_ports; port++) { 135 struct ocelot_port *ocelot_port; 136 137 ocelot_port = ocelot->ports[port]; 138 if (!ocelot_port) 139 continue; 140 141 ocelot_deinit_port(ocelot, port); 142 ocelot_release_port(ocelot_port); 143 } 144 } 145 146 static int mscc_ocelot_init_ports(struct platform_device *pdev, 147 struct device_node *ports) 148 { 149 struct ocelot *ocelot = platform_get_drvdata(pdev); 150 u32 devlink_ports_registered = 0; 151 struct device_node *portnp; 152 int port, err; 153 u32 reg; 154 155 ocelot->ports = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports, 156 sizeof(struct ocelot_port *), GFP_KERNEL); 157 if (!ocelot->ports) 158 return -ENOMEM; 159 160 ocelot->devlink_ports = devm_kcalloc(ocelot->dev, 161 ocelot->num_phys_ports, 162 sizeof(*ocelot->devlink_ports), 163 GFP_KERNEL); 164 if (!ocelot->devlink_ports) 165 return -ENOMEM; 166 167 for_each_available_child_of_node(ports, portnp) { 168 struct regmap *target; 169 struct resource *res; 170 char res_name[8]; 171 172 if (of_property_read_u32(portnp, "reg", ®)) 173 continue; 174 175 port = reg; 176 if (port < 0 || port >= ocelot->num_phys_ports) { 177 dev_err(ocelot->dev, 178 "invalid port number: %d >= %d\n", port, 179 ocelot->num_phys_ports); 180 continue; 181 } 182 183 snprintf(res_name, sizeof(res_name), "port%d", port); 184 185 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 186 res_name); 187 target = ocelot_regmap_init(ocelot, res); 188 if (IS_ERR(target)) { 189 err = PTR_ERR(target); 190 of_node_put(portnp); 191 goto out_teardown; 192 } 193 194 err = ocelot_port_devlink_init(ocelot, port, 195 DEVLINK_PORT_FLAVOUR_PHYSICAL); 196 if (err) { 197 of_node_put(portnp); 198 goto out_teardown; 199 } 200 201 err = ocelot_probe_port(ocelot, port, target, portnp); 202 if (err) { 203 ocelot_port_devlink_teardown(ocelot, port); 204 continue; 205 } 206 207 devlink_ports_registered |= BIT(port); 208 } 209 210 /* Initialize unused devlink ports at the end */ 211 for (port = 0; port < ocelot->num_phys_ports; port++) { 212 if (devlink_ports_registered & BIT(port)) 213 continue; 214 215 err = ocelot_port_devlink_init(ocelot, port, 216 DEVLINK_PORT_FLAVOUR_UNUSED); 217 if (err) 218 goto out_teardown; 219 220 devlink_ports_registered |= BIT(port); 221 } 222 223 return 0; 224 225 out_teardown: 226 /* Unregister the network interfaces */ 227 mscc_ocelot_release_ports(ocelot); 228 /* Tear down devlink ports for the registered network interfaces */ 229 for (port = 0; port < ocelot->num_phys_ports; port++) { 230 if (devlink_ports_registered & BIT(port)) 231 ocelot_port_devlink_teardown(ocelot, port); 232 } 233 return err; 234 } 235 236 static int mscc_ocelot_probe(struct platform_device *pdev) 237 { 238 struct device_node *np = pdev->dev.of_node; 239 int err, irq_xtr, irq_ptp_rdy; 240 struct device_node *ports; 241 struct devlink *devlink; 242 struct ocelot *ocelot; 243 struct regmap *hsio; 244 unsigned int i; 245 246 struct { 247 enum ocelot_target id; 248 char *name; 249 u8 optional:1; 250 } io_target[] = { 251 { SYS, "sys" }, 252 { REW, "rew" }, 253 { QSYS, "qsys" }, 254 { ANA, "ana" }, 255 { QS, "qs" }, 256 { S0, "s0" }, 257 { S1, "s1" }, 258 { S2, "s2" }, 259 { PTP, "ptp", 1 }, 260 { FDMA, "fdma", 1 }, 261 }; 262 263 if (!np && !pdev->dev.platform_data) 264 return -ENODEV; 265 266 devlink = 267 devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot), &pdev->dev); 268 if (!devlink) 269 return -ENOMEM; 270 271 ocelot = devlink_priv(devlink); 272 ocelot->devlink = priv_to_devlink(ocelot); 273 platform_set_drvdata(pdev, ocelot); 274 ocelot->dev = &pdev->dev; 275 276 for (i = 0; i < ARRAY_SIZE(io_target); i++) { 277 struct regmap *target; 278 struct resource *res; 279 280 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 281 io_target[i].name); 282 283 target = ocelot_regmap_init(ocelot, res); 284 if (IS_ERR(target)) { 285 if (io_target[i].optional) { 286 ocelot->targets[io_target[i].id] = NULL; 287 continue; 288 } 289 err = PTR_ERR(target); 290 goto out_free_devlink; 291 } 292 293 ocelot->targets[io_target[i].id] = target; 294 } 295 296 if (ocelot->targets[FDMA]) 297 ocelot_fdma_init(pdev, ocelot); 298 299 hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio"); 300 if (IS_ERR(hsio)) { 301 dev_err(&pdev->dev, "missing hsio syscon\n"); 302 err = PTR_ERR(hsio); 303 goto out_free_devlink; 304 } 305 306 ocelot->targets[HSIO] = hsio; 307 308 err = ocelot_chip_init(ocelot, &ocelot_ops); 309 if (err) 310 goto out_free_devlink; 311 312 irq_xtr = platform_get_irq_byname(pdev, "xtr"); 313 if (irq_xtr < 0) { 314 err = irq_xtr; 315 goto out_free_devlink; 316 } 317 318 err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL, 319 ocelot_xtr_irq_handler, IRQF_ONESHOT, 320 "frame extraction", ocelot); 321 if (err) 322 goto out_free_devlink; 323 324 irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy"); 325 if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) { 326 err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL, 327 ocelot_ptp_rdy_irq_handler, 328 IRQF_ONESHOT, "ptp ready", 329 ocelot); 330 if (err) 331 goto out_free_devlink; 332 333 /* Both the PTP interrupt and the PTP bank are available */ 334 ocelot->ptp = 1; 335 } 336 337 ports = of_get_child_by_name(np, "ethernet-ports"); 338 if (!ports) { 339 dev_err(ocelot->dev, "no ethernet-ports child node found\n"); 340 err = -ENODEV; 341 goto out_free_devlink; 342 } 343 344 ocelot->num_phys_ports = of_get_child_count(ports); 345 ocelot->num_flooding_pgids = 1; 346 347 ocelot->vcap = vsc7514_vcap_props; 348 349 ocelot->vcap_pol.base = VSC7514_VCAP_POLICER_BASE; 350 ocelot->vcap_pol.max = VSC7514_VCAP_POLICER_MAX; 351 352 ocelot->npi = -1; 353 354 err = ocelot_init(ocelot); 355 if (err) 356 goto out_put_ports; 357 358 err = mscc_ocelot_init_ports(pdev, ports); 359 if (err) 360 goto out_ocelot_devlink_unregister; 361 362 if (ocelot->fdma) 363 ocelot_fdma_start(ocelot); 364 365 err = ocelot_devlink_sb_register(ocelot); 366 if (err) 367 goto out_ocelot_release_ports; 368 369 if (ocelot->ptp) { 370 err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info); 371 if (err) { 372 dev_err(ocelot->dev, 373 "Timestamp initialization failed\n"); 374 ocelot->ptp = 0; 375 } 376 } 377 378 register_netdevice_notifier(&ocelot_netdevice_nb); 379 register_switchdev_notifier(&ocelot_switchdev_nb); 380 register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb); 381 382 of_node_put(ports); 383 devlink_register(devlink); 384 385 dev_info(&pdev->dev, "Ocelot switch probed\n"); 386 387 return 0; 388 389 out_ocelot_release_ports: 390 mscc_ocelot_release_ports(ocelot); 391 mscc_ocelot_teardown_devlink_ports(ocelot); 392 out_ocelot_devlink_unregister: 393 ocelot_deinit(ocelot); 394 out_put_ports: 395 of_node_put(ports); 396 out_free_devlink: 397 devlink_free(devlink); 398 return err; 399 } 400 401 static void mscc_ocelot_remove(struct platform_device *pdev) 402 { 403 struct ocelot *ocelot = platform_get_drvdata(pdev); 404 405 if (ocelot->fdma) 406 ocelot_fdma_deinit(ocelot); 407 devlink_unregister(ocelot->devlink); 408 ocelot_deinit_timestamp(ocelot); 409 ocelot_devlink_sb_unregister(ocelot); 410 mscc_ocelot_release_ports(ocelot); 411 mscc_ocelot_teardown_devlink_ports(ocelot); 412 ocelot_deinit(ocelot); 413 unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb); 414 unregister_switchdev_notifier(&ocelot_switchdev_nb); 415 unregister_netdevice_notifier(&ocelot_netdevice_nb); 416 devlink_free(ocelot->devlink); 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