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