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/iopoll.h> 10 #include <linux/module.h> 11 #include <linux/of_net.h> 12 #include <linux/netdevice.h> 13 #include <linux/phylink.h> 14 #include <linux/of_mdio.h> 15 #include <linux/of_platform.h> 16 #include <linux/mfd/syscon.h> 17 #include <linux/skbuff.h> 18 #include <net/switchdev.h> 19 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 #define MEM_INIT_SLEEP_US 1000 30 #define MEM_INIT_TIMEOUT_US 100000 31 32 static const u32 *ocelot_regmap[TARGET_MAX] = { 33 [ANA] = vsc7514_ana_regmap, 34 [QS] = vsc7514_qs_regmap, 35 [QSYS] = vsc7514_qsys_regmap, 36 [REW] = vsc7514_rew_regmap, 37 [SYS] = vsc7514_sys_regmap, 38 [S0] = vsc7514_vcap_regmap, 39 [S1] = vsc7514_vcap_regmap, 40 [S2] = vsc7514_vcap_regmap, 41 [PTP] = vsc7514_ptp_regmap, 42 [DEV_GMII] = vsc7514_dev_gmii_regmap, 43 }; 44 45 static const struct reg_field ocelot_regfields[REGFIELD_MAX] = { 46 [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 11, 11), 47 [ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 10), 48 [ANA_ANEVENTS_MSTI_DROP] = REG_FIELD(ANA_ANEVENTS, 27, 27), 49 [ANA_ANEVENTS_ACLKILL] = REG_FIELD(ANA_ANEVENTS, 26, 26), 50 [ANA_ANEVENTS_ACLUSED] = REG_FIELD(ANA_ANEVENTS, 25, 25), 51 [ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24), 52 [ANA_ANEVENTS_VS2TTL1] = REG_FIELD(ANA_ANEVENTS, 23, 23), 53 [ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22), 54 [ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21), 55 [ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20), 56 [ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19), 57 [ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18), 58 [ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17), 59 [ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16), 60 [ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15), 61 [ANA_ANEVENTS_DROPPED] = REG_FIELD(ANA_ANEVENTS, 14, 14), 62 [ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13), 63 [ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12), 64 [ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11), 65 [ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10), 66 [ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9), 67 [ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8), 68 [ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7), 69 [ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6), 70 [ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5), 71 [ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4), 72 [ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3), 73 [ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2), 74 [ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1), 75 [ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0), 76 [ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 18, 18), 77 [ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 10, 11), 78 [ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 9), 79 [QSYS_TIMED_FRAME_ENTRY_TFRM_VLD] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 20, 20), 80 [QSYS_TIMED_FRAME_ENTRY_TFRM_FP] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 8, 19), 81 [QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 4, 7), 82 [QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 1, 3), 83 [QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 0, 0), 84 [SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 2, 2), 85 [SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 1, 1), 86 [SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 0, 0), 87 /* Replicated per number of ports (12), register size 4 per port */ 88 [QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 14, 14, 12, 4), 89 [QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 11, 13, 12, 4), 90 [QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 12, 4), 91 [QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 12, 4), 92 [QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 12, 4), 93 [QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 12, 4), 94 [SYS_PORT_MODE_DATA_WO_TS] = REG_FIELD_ID(SYS_PORT_MODE, 5, 6, 12, 4), 95 [SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 3, 4, 12, 4), 96 [SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 1, 2, 12, 4), 97 [SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 12, 4), 98 [SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 10, 18, 12, 4), 99 [SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 9, 12, 4), 100 [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 12, 4), 101 }; 102 103 static void ocelot_pll5_init(struct ocelot *ocelot) 104 { 105 /* Configure PLL5. This will need a proper CCF driver 106 * The values are coming from the VTSS API for Ocelot 107 */ 108 regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG4, 109 HSIO_PLL5G_CFG4_IB_CTRL(0x7600) | 110 HSIO_PLL5G_CFG4_IB_BIAS_CTRL(0x8)); 111 regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG0, 112 HSIO_PLL5G_CFG0_CORE_CLK_DIV(0x11) | 113 HSIO_PLL5G_CFG0_CPU_CLK_DIV(2) | 114 HSIO_PLL5G_CFG0_ENA_BIAS | 115 HSIO_PLL5G_CFG0_ENA_VCO_BUF | 116 HSIO_PLL5G_CFG0_ENA_CP1 | 117 HSIO_PLL5G_CFG0_SELCPI(2) | 118 HSIO_PLL5G_CFG0_LOOP_BW_RES(0xe) | 119 HSIO_PLL5G_CFG0_SELBGV820(4) | 120 HSIO_PLL5G_CFG0_DIV4 | 121 HSIO_PLL5G_CFG0_ENA_CLKTREE | 122 HSIO_PLL5G_CFG0_ENA_LANE); 123 regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG2, 124 HSIO_PLL5G_CFG2_EN_RESET_FRQ_DET | 125 HSIO_PLL5G_CFG2_EN_RESET_OVERRUN | 126 HSIO_PLL5G_CFG2_GAIN_TEST(0x8) | 127 HSIO_PLL5G_CFG2_ENA_AMPCTRL | 128 HSIO_PLL5G_CFG2_PWD_AMPCTRL_N | 129 HSIO_PLL5G_CFG2_AMPC_SEL(0x10)); 130 } 131 132 static int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops) 133 { 134 int ret; 135 136 ocelot->map = ocelot_regmap; 137 ocelot->num_mact_rows = 1024; 138 ocelot->ops = ops; 139 140 ret = ocelot_regfields_init(ocelot, ocelot_regfields); 141 if (ret) 142 return ret; 143 144 ocelot_pll5_init(ocelot); 145 146 eth_random_addr(ocelot->base_mac); 147 ocelot->base_mac[5] &= 0xf0; 148 149 return 0; 150 } 151 152 static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg) 153 { 154 struct ocelot *ocelot = arg; 155 int grp = 0, err; 156 157 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)) { 158 struct sk_buff *skb; 159 160 err = ocelot_xtr_poll_frame(ocelot, grp, &skb); 161 if (err) 162 goto out; 163 164 skb->dev->stats.rx_bytes += skb->len; 165 skb->dev->stats.rx_packets++; 166 167 if (!skb_defer_rx_timestamp(skb)) 168 netif_rx(skb); 169 } 170 171 out: 172 if (err < 0) 173 ocelot_drain_cpu_queue(ocelot, 0); 174 175 return IRQ_HANDLED; 176 } 177 178 static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg) 179 { 180 struct ocelot *ocelot = arg; 181 182 ocelot_get_txtstamp(ocelot); 183 184 return IRQ_HANDLED; 185 } 186 187 static const struct of_device_id mscc_ocelot_match[] = { 188 { .compatible = "mscc,vsc7514-switch" }, 189 { } 190 }; 191 MODULE_DEVICE_TABLE(of, mscc_ocelot_match); 192 193 static int ocelot_mem_init_status(struct ocelot *ocelot) 194 { 195 unsigned int val; 196 int err; 197 198 err = regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 199 &val); 200 201 return err ?: val; 202 } 203 204 static int ocelot_reset(struct ocelot *ocelot) 205 { 206 int err; 207 u32 val; 208 209 err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1); 210 if (err) 211 return err; 212 213 err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); 214 if (err) 215 return err; 216 217 /* MEM_INIT is a self-clearing bit. Wait for it to be cleared (should be 218 * 100us) before enabling the switch core. 219 */ 220 err = readx_poll_timeout(ocelot_mem_init_status, ocelot, val, !val, 221 MEM_INIT_SLEEP_US, MEM_INIT_TIMEOUT_US); 222 if (err) 223 return err; 224 225 err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); 226 if (err) 227 return err; 228 229 return regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1); 230 } 231 232 /* Watermark encode 233 * Bit 8: Unit; 0:1, 1:16 234 * Bit 7-0: Value to be multiplied with unit 235 */ 236 static u16 ocelot_wm_enc(u16 value) 237 { 238 WARN_ON(value >= 16 * BIT(8)); 239 240 if (value >= BIT(8)) 241 return BIT(8) | (value / 16); 242 243 return value; 244 } 245 246 static u16 ocelot_wm_dec(u16 wm) 247 { 248 if (wm & BIT(8)) 249 return (wm & GENMASK(7, 0)) * 16; 250 251 return wm; 252 } 253 254 static void ocelot_wm_stat(u32 val, u32 *inuse, u32 *maxuse) 255 { 256 *inuse = (val & GENMASK(23, 12)) >> 12; 257 *maxuse = val & GENMASK(11, 0); 258 } 259 260 static const struct ocelot_ops ocelot_ops = { 261 .reset = ocelot_reset, 262 .wm_enc = ocelot_wm_enc, 263 .wm_dec = ocelot_wm_dec, 264 .wm_stat = ocelot_wm_stat, 265 .port_to_netdev = ocelot_port_to_netdev, 266 .netdev_to_port = ocelot_netdev_to_port, 267 }; 268 269 static struct vcap_props vsc7514_vcap_props[] = { 270 [VCAP_ES0] = { 271 .action_type_width = 0, 272 .action_table = { 273 [ES0_ACTION_TYPE_NORMAL] = { 274 .width = 73, /* HIT_STICKY not included */ 275 .count = 1, 276 }, 277 }, 278 .target = S0, 279 .keys = vsc7514_vcap_es0_keys, 280 .actions = vsc7514_vcap_es0_actions, 281 }, 282 [VCAP_IS1] = { 283 .action_type_width = 0, 284 .action_table = { 285 [IS1_ACTION_TYPE_NORMAL] = { 286 .width = 78, /* HIT_STICKY not included */ 287 .count = 4, 288 }, 289 }, 290 .target = S1, 291 .keys = vsc7514_vcap_is1_keys, 292 .actions = vsc7514_vcap_is1_actions, 293 }, 294 [VCAP_IS2] = { 295 .action_type_width = 1, 296 .action_table = { 297 [IS2_ACTION_TYPE_NORMAL] = { 298 .width = 49, 299 .count = 2 300 }, 301 [IS2_ACTION_TYPE_SMAC_SIP] = { 302 .width = 6, 303 .count = 4 304 }, 305 }, 306 .target = S2, 307 .keys = vsc7514_vcap_is2_keys, 308 .actions = vsc7514_vcap_is2_actions, 309 }, 310 }; 311 312 static struct ptp_clock_info ocelot_ptp_clock_info = { 313 .owner = THIS_MODULE, 314 .name = "ocelot ptp", 315 .max_adj = 0x7fffffff, 316 .n_alarm = 0, 317 .n_ext_ts = 0, 318 .n_per_out = OCELOT_PTP_PINS_NUM, 319 .n_pins = OCELOT_PTP_PINS_NUM, 320 .pps = 0, 321 .gettime64 = ocelot_ptp_gettime64, 322 .settime64 = ocelot_ptp_settime64, 323 .adjtime = ocelot_ptp_adjtime, 324 .adjfine = ocelot_ptp_adjfine, 325 .verify = ocelot_ptp_verify, 326 .enable = ocelot_ptp_enable, 327 }; 328 329 static void mscc_ocelot_teardown_devlink_ports(struct ocelot *ocelot) 330 { 331 int port; 332 333 for (port = 0; port < ocelot->num_phys_ports; port++) 334 ocelot_port_devlink_teardown(ocelot, port); 335 } 336 337 static void mscc_ocelot_release_ports(struct ocelot *ocelot) 338 { 339 int port; 340 341 for (port = 0; port < ocelot->num_phys_ports; port++) { 342 struct ocelot_port *ocelot_port; 343 344 ocelot_port = ocelot->ports[port]; 345 if (!ocelot_port) 346 continue; 347 348 ocelot_deinit_port(ocelot, port); 349 ocelot_release_port(ocelot_port); 350 } 351 } 352 353 static int mscc_ocelot_init_ports(struct platform_device *pdev, 354 struct device_node *ports) 355 { 356 struct ocelot *ocelot = platform_get_drvdata(pdev); 357 u32 devlink_ports_registered = 0; 358 struct device_node *portnp; 359 int port, err; 360 u32 reg; 361 362 ocelot->ports = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports, 363 sizeof(struct ocelot_port *), GFP_KERNEL); 364 if (!ocelot->ports) 365 return -ENOMEM; 366 367 ocelot->devlink_ports = devm_kcalloc(ocelot->dev, 368 ocelot->num_phys_ports, 369 sizeof(*ocelot->devlink_ports), 370 GFP_KERNEL); 371 if (!ocelot->devlink_ports) 372 return -ENOMEM; 373 374 for_each_available_child_of_node(ports, portnp) { 375 struct regmap *target; 376 struct resource *res; 377 char res_name[8]; 378 379 if (of_property_read_u32(portnp, "reg", ®)) 380 continue; 381 382 port = reg; 383 if (port < 0 || port >= ocelot->num_phys_ports) { 384 dev_err(ocelot->dev, 385 "invalid port number: %d >= %d\n", port, 386 ocelot->num_phys_ports); 387 continue; 388 } 389 390 snprintf(res_name, sizeof(res_name), "port%d", port); 391 392 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 393 res_name); 394 target = ocelot_regmap_init(ocelot, res); 395 if (IS_ERR(target)) { 396 err = PTR_ERR(target); 397 of_node_put(portnp); 398 goto out_teardown; 399 } 400 401 err = ocelot_port_devlink_init(ocelot, port, 402 DEVLINK_PORT_FLAVOUR_PHYSICAL); 403 if (err) { 404 of_node_put(portnp); 405 goto out_teardown; 406 } 407 408 err = ocelot_probe_port(ocelot, port, target, portnp); 409 if (err) { 410 ocelot_port_devlink_teardown(ocelot, port); 411 continue; 412 } 413 414 devlink_ports_registered |= BIT(port); 415 } 416 417 /* Initialize unused devlink ports at the end */ 418 for (port = 0; port < ocelot->num_phys_ports; port++) { 419 if (devlink_ports_registered & BIT(port)) 420 continue; 421 422 err = ocelot_port_devlink_init(ocelot, port, 423 DEVLINK_PORT_FLAVOUR_UNUSED); 424 if (err) 425 goto out_teardown; 426 427 devlink_ports_registered |= BIT(port); 428 } 429 430 return 0; 431 432 out_teardown: 433 /* Unregister the network interfaces */ 434 mscc_ocelot_release_ports(ocelot); 435 /* Tear down devlink ports for the registered network interfaces */ 436 for (port = 0; port < ocelot->num_phys_ports; port++) { 437 if (devlink_ports_registered & BIT(port)) 438 ocelot_port_devlink_teardown(ocelot, port); 439 } 440 return err; 441 } 442 443 static int mscc_ocelot_probe(struct platform_device *pdev) 444 { 445 struct device_node *np = pdev->dev.of_node; 446 int err, irq_xtr, irq_ptp_rdy; 447 struct device_node *ports; 448 struct devlink *devlink; 449 struct ocelot *ocelot; 450 struct regmap *hsio; 451 unsigned int i; 452 453 struct { 454 enum ocelot_target id; 455 char *name; 456 u8 optional:1; 457 } io_target[] = { 458 { SYS, "sys" }, 459 { REW, "rew" }, 460 { QSYS, "qsys" }, 461 { ANA, "ana" }, 462 { QS, "qs" }, 463 { S0, "s0" }, 464 { S1, "s1" }, 465 { S2, "s2" }, 466 { PTP, "ptp", 1 }, 467 { FDMA, "fdma", 1 }, 468 }; 469 470 if (!np && !pdev->dev.platform_data) 471 return -ENODEV; 472 473 devlink = 474 devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot), &pdev->dev); 475 if (!devlink) 476 return -ENOMEM; 477 478 ocelot = devlink_priv(devlink); 479 ocelot->devlink = priv_to_devlink(ocelot); 480 platform_set_drvdata(pdev, ocelot); 481 ocelot->dev = &pdev->dev; 482 483 for (i = 0; i < ARRAY_SIZE(io_target); i++) { 484 struct regmap *target; 485 struct resource *res; 486 487 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 488 io_target[i].name); 489 490 target = ocelot_regmap_init(ocelot, res); 491 if (IS_ERR(target)) { 492 if (io_target[i].optional) { 493 ocelot->targets[io_target[i].id] = NULL; 494 continue; 495 } 496 err = PTR_ERR(target); 497 goto out_free_devlink; 498 } 499 500 ocelot->targets[io_target[i].id] = target; 501 } 502 503 if (ocelot->targets[FDMA]) 504 ocelot_fdma_init(pdev, ocelot); 505 506 hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio"); 507 if (IS_ERR(hsio)) { 508 dev_err(&pdev->dev, "missing hsio syscon\n"); 509 err = PTR_ERR(hsio); 510 goto out_free_devlink; 511 } 512 513 ocelot->targets[HSIO] = hsio; 514 515 err = ocelot_chip_init(ocelot, &ocelot_ops); 516 if (err) 517 goto out_free_devlink; 518 519 irq_xtr = platform_get_irq_byname(pdev, "xtr"); 520 if (irq_xtr < 0) { 521 err = irq_xtr; 522 goto out_free_devlink; 523 } 524 525 err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL, 526 ocelot_xtr_irq_handler, IRQF_ONESHOT, 527 "frame extraction", ocelot); 528 if (err) 529 goto out_free_devlink; 530 531 irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy"); 532 if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) { 533 err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL, 534 ocelot_ptp_rdy_irq_handler, 535 IRQF_ONESHOT, "ptp ready", 536 ocelot); 537 if (err) 538 goto out_free_devlink; 539 540 /* Both the PTP interrupt and the PTP bank are available */ 541 ocelot->ptp = 1; 542 } 543 544 ports = of_get_child_by_name(np, "ethernet-ports"); 545 if (!ports) { 546 dev_err(ocelot->dev, "no ethernet-ports child node found\n"); 547 err = -ENODEV; 548 goto out_free_devlink; 549 } 550 551 ocelot->num_phys_ports = of_get_child_count(ports); 552 ocelot->num_flooding_pgids = 1; 553 554 ocelot->vcap = vsc7514_vcap_props; 555 556 ocelot->vcap_pol.base = VSC7514_VCAP_POLICER_BASE; 557 ocelot->vcap_pol.max = VSC7514_VCAP_POLICER_MAX; 558 559 ocelot->npi = -1; 560 561 err = ocelot_init(ocelot); 562 if (err) 563 goto out_put_ports; 564 565 err = mscc_ocelot_init_ports(pdev, ports); 566 if (err) 567 goto out_ocelot_devlink_unregister; 568 569 if (ocelot->fdma) 570 ocelot_fdma_start(ocelot); 571 572 err = ocelot_devlink_sb_register(ocelot); 573 if (err) 574 goto out_ocelot_release_ports; 575 576 if (ocelot->ptp) { 577 err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info); 578 if (err) { 579 dev_err(ocelot->dev, 580 "Timestamp initialization failed\n"); 581 ocelot->ptp = 0; 582 } 583 } 584 585 register_netdevice_notifier(&ocelot_netdevice_nb); 586 register_switchdev_notifier(&ocelot_switchdev_nb); 587 register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb); 588 589 of_node_put(ports); 590 devlink_register(devlink); 591 592 dev_info(&pdev->dev, "Ocelot switch probed\n"); 593 594 return 0; 595 596 out_ocelot_release_ports: 597 mscc_ocelot_release_ports(ocelot); 598 mscc_ocelot_teardown_devlink_ports(ocelot); 599 out_ocelot_devlink_unregister: 600 ocelot_deinit(ocelot); 601 out_put_ports: 602 of_node_put(ports); 603 out_free_devlink: 604 devlink_free(devlink); 605 return err; 606 } 607 608 static int mscc_ocelot_remove(struct platform_device *pdev) 609 { 610 struct ocelot *ocelot = platform_get_drvdata(pdev); 611 612 if (ocelot->fdma) 613 ocelot_fdma_deinit(ocelot); 614 devlink_unregister(ocelot->devlink); 615 ocelot_deinit_timestamp(ocelot); 616 ocelot_devlink_sb_unregister(ocelot); 617 mscc_ocelot_release_ports(ocelot); 618 mscc_ocelot_teardown_devlink_ports(ocelot); 619 ocelot_deinit(ocelot); 620 unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb); 621 unregister_switchdev_notifier(&ocelot_switchdev_nb); 622 unregister_netdevice_notifier(&ocelot_netdevice_nb); 623 devlink_free(ocelot->devlink); 624 625 return 0; 626 } 627 628 static struct platform_driver mscc_ocelot_driver = { 629 .probe = mscc_ocelot_probe, 630 .remove = mscc_ocelot_remove, 631 .driver = { 632 .name = "ocelot-switch", 633 .of_match_table = mscc_ocelot_match, 634 }, 635 }; 636 637 module_platform_driver(mscc_ocelot_driver); 638 639 MODULE_DESCRIPTION("Microsemi Ocelot switch driver"); 640 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>"); 641 MODULE_LICENSE("Dual MIT/GPL"); 642