diff options
-rw-r--r-- | drivers/net/dsa/ocelot/Kconfig | 22 | ||||
-rw-r--r-- | drivers/net/dsa/ocelot/Makefile | 6 | ||||
-rw-r--r-- | drivers/net/dsa/ocelot/felix.c | 47 | ||||
-rw-r--r-- | drivers/net/dsa/ocelot/felix.h | 7 | ||||
-rw-r--r-- | drivers/net/dsa/ocelot/felix_vsc9959.c | 57 | ||||
-rw-r--r-- | drivers/net/dsa/ocelot/seville_vsc9953.c | 55 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_ptp.c | 3 | ||||
-rw-r--r-- | include/soc/mscc/ocelot_ptp.h | 3 |
8 files changed, 102 insertions, 98 deletions
diff --git a/drivers/net/dsa/ocelot/Kconfig b/drivers/net/dsa/ocelot/Kconfig index e19718d4a7d4..c110e82a7973 100644 --- a/drivers/net/dsa/ocelot/Kconfig +++ b/drivers/net/dsa/ocelot/Kconfig @@ -10,11 +10,17 @@ config NET_DSA_MSCC_FELIX select FSL_ENETC_MDIO select PCS_LYNX help - This driver supports network switches from the Vitesse / - Microsemi / Microchip Ocelot family of switching cores that are - connected to their host CPU via Ethernet. - The following switches are supported: - - VSC9959 (Felix): embedded as a PCIe function of the NXP LS1028A - ENETC integrated endpoint. - - VSC9953 (Seville): embedded as a platform device on the - NXP T1040 SoC. + This driver supports the VSC9959 (Felix) switch, which is embedded as + a PCIe function of the NXP LS1028A ENETC RCiEP. + +config NET_DSA_MSCC_SEVILLE + tristate "Ocelot / Seville Ethernet switch support" + depends on NET_DSA + depends on NET_VENDOR_MICROSEMI + depends on HAS_IOMEM + select MSCC_OCELOT_SWITCH_LIB + select NET_DSA_TAG_OCELOT + select PCS_LYNX + help + This driver supports the VSC9953 (Seville) switch, which is embedded + as a platform device on the NXP T1040 SoC. diff --git a/drivers/net/dsa/ocelot/Makefile b/drivers/net/dsa/ocelot/Makefile index ec57a5a12330..f6dd131e7491 100644 --- a/drivers/net/dsa/ocelot/Makefile +++ b/drivers/net/dsa/ocelot/Makefile @@ -1,7 +1,11 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_NET_DSA_MSCC_FELIX) += mscc_felix.o +obj-$(CONFIG_NET_DSA_MSCC_SEVILLE) += mscc_seville.o mscc_felix-objs := \ felix.o \ - felix_vsc9959.o \ + felix_vsc9959.o + +mscc_seville-objs := \ + felix.o \ seville_vsc9953.o diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index a1e1d3824110..f9a7034be0c7 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -538,23 +538,6 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) return 0; } -static struct ptp_clock_info ocelot_ptp_clock_info = { - .owner = THIS_MODULE, - .name = "felix ptp", - .max_adj = 0x7fffffff, - .n_alarm = 0, - .n_ext_ts = 0, - .n_per_out = OCELOT_PTP_PINS_NUM, - .n_pins = OCELOT_PTP_PINS_NUM, - .pps = 0, - .gettime64 = ocelot_ptp_gettime64, - .settime64 = ocelot_ptp_settime64, - .adjtime = ocelot_ptp_adjtime, - .adjfine = ocelot_ptp_adjfine, - .verify = ocelot_ptp_verify, - .enable = ocelot_ptp_enable, -}; - /* Hardware initialization done here so that we can allocate structures with * devm without fear of dsa_register_switch returning -EPROBE_DEFER and causing * us to allocate structures twice (leak memory) and map PCI memory twice @@ -573,7 +556,7 @@ static int felix_setup(struct dsa_switch *ds) ocelot_init(ocelot); if (ocelot->ptp) { - err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info); + err = ocelot_init_timestamp(ocelot, felix->info->ptp_caps); if (err) { dev_err(ocelot->dev, "Timestamp initialization failed\n"); @@ -797,31 +780,5 @@ const struct dsa_switch_ops felix_switch_ops = { .cls_flower_add = felix_cls_flower_add, .cls_flower_del = felix_cls_flower_del, .cls_flower_stats = felix_cls_flower_stats, - .port_setup_tc = felix_port_setup_tc, + .port_setup_tc = felix_port_setup_tc, }; - -static int __init felix_init(void) -{ - int err; - - err = pci_register_driver(&felix_vsc9959_pci_driver); - if (err) - return err; - - err = platform_driver_register(&seville_vsc9953_driver); - if (err) - return err; - - return 0; -} -module_init(felix_init); - -static void __exit felix_exit(void) -{ - pci_unregister_driver(&felix_vsc9959_pci_driver); - platform_driver_unregister(&seville_vsc9953_driver); -} -module_exit(felix_exit); - -MODULE_DESCRIPTION("Felix Switch driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index 9bceb994b7db..cc3ec83a600a 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -20,12 +20,13 @@ struct felix_info { const struct ocelot_stat_layout *stats_layout; unsigned int num_stats; int num_ports; - int num_tx_queues; + int num_tx_queues; struct vcap_field *vcap_is2_keys; struct vcap_field *vcap_is2_actions; const struct vcap_props *vcap; int switch_pci_bar; int imdio_pci_bar; + const struct ptp_clock_info *ptp_caps; int (*mdio_bus_alloc)(struct ocelot *ocelot); void (*mdio_bus_free)(struct ocelot *ocelot); void (*phylink_validate)(struct ocelot *ocelot, int port, @@ -41,8 +42,6 @@ struct felix_info { }; extern const struct dsa_switch_ops felix_switch_ops; -extern struct pci_driver felix_vsc9959_pci_driver; -extern struct platform_driver seville_vsc9953_driver; /* DSA glue / front-end for struct ocelot */ struct felix { @@ -55,6 +54,4 @@ struct felix { resource_size_t imdio_base; }; -void vsc9959_mdio_bus_free(struct ocelot *ocelot); - #endif diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 126a53a811f7..79ddc4ba27a3 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -296,15 +296,15 @@ static const u32 vsc9959_sys_regmap[] = { }; static const u32 vsc9959_ptp_regmap[] = { - REG(PTP_PIN_CFG, 0x000000), - REG(PTP_PIN_TOD_SEC_MSB, 0x000004), - REG(PTP_PIN_TOD_SEC_LSB, 0x000008), - REG(PTP_PIN_TOD_NSEC, 0x00000c), - REG(PTP_PIN_WF_HIGH_PERIOD, 0x000014), - REG(PTP_PIN_WF_LOW_PERIOD, 0x000018), - REG(PTP_CFG_MISC, 0x0000a0), - REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4), - REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8), + REG(PTP_PIN_CFG, 0x000000), + REG(PTP_PIN_TOD_SEC_MSB, 0x000004), + REG(PTP_PIN_TOD_SEC_LSB, 0x000008), + REG(PTP_PIN_TOD_NSEC, 0x00000c), + REG(PTP_PIN_WF_HIGH_PERIOD, 0x000014), + REG(PTP_PIN_WF_LOW_PERIOD, 0x000018), + REG(PTP_CFG_MISC, 0x0000a0), + REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4), + REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8), }; static const u32 vsc9959_gcb_regmap[] = { @@ -719,6 +719,23 @@ static const struct vcap_props vsc9959_vcap_props[] = { }, }; +static const struct ptp_clock_info vsc9959_ptp_caps = { + .owner = THIS_MODULE, + .name = "felix ptp", + .max_adj = 0x7fffffff, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = OCELOT_PTP_PINS_NUM, + .n_pins = OCELOT_PTP_PINS_NUM, + .pps = 0, + .gettime64 = ocelot_ptp_gettime64, + .settime64 = ocelot_ptp_settime64, + .adjtime = ocelot_ptp_adjtime, + .adjfine = ocelot_ptp_adjfine, + .verify = ocelot_ptp_verify, + .enable = ocelot_ptp_enable, +}; + #define VSC9959_INIT_TIMEOUT 50000 #define VSC9959_GCB_RST_SLEEP 100 #define VSC9959_SYS_RAMINIT_SLEEP 80 @@ -727,7 +744,7 @@ static int vsc9959_gcb_soft_rst_status(struct ocelot *ocelot) { int val; - regmap_field_read(ocelot->regfields[GCB_SOFT_RST_SWC_RST], &val); + ocelot_field_read(ocelot, GCB_SOFT_RST_SWC_RST, &val); return val; } @@ -737,12 +754,15 @@ static int vsc9959_sys_ram_init_status(struct ocelot *ocelot) return ocelot_read(ocelot, SYS_RAM_INIT); } +/* CORE_ENA is in SYS:SYSTEM:RESET_CFG + * RAM_INIT is in SYS:RAM_CTRL:RAM_INIT + */ static int vsc9959_reset(struct ocelot *ocelot) { int val, err; /* soft-reset the switch core */ - regmap_field_write(ocelot->regfields[GCB_SOFT_RST_SWC_RST], 1); + ocelot_field_write(ocelot, GCB_SOFT_RST_SWC_RST, 1); err = readx_poll_timeout(vsc9959_gcb_soft_rst_status, ocelot, val, !val, VSC9959_GCB_RST_SLEEP, VSC9959_INIT_TIMEOUT); @@ -762,7 +782,7 @@ static int vsc9959_reset(struct ocelot *ocelot) } /* enable switch core */ - regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1); + ocelot_field_write(ocelot, SYS_RESET_CFG_CORE_ENA, 1); return 0; } @@ -933,7 +953,7 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot) return 0; } -void vsc9959_mdio_bus_free(struct ocelot *ocelot) +static void vsc9959_mdio_bus_free(struct ocelot *ocelot) { struct felix *felix = ocelot_to_felix(ocelot); int port; @@ -1166,12 +1186,13 @@ static const struct felix_info felix_info_vsc9959 = { .num_tx_queues = FELIX_NUM_TC, .switch_pci_bar = 4, .imdio_pci_bar = 0, + .ptp_caps = &vsc9959_ptp_caps, .mdio_bus_alloc = vsc9959_mdio_bus_alloc, .mdio_bus_free = vsc9959_mdio_bus_free, .phylink_validate = vsc9959_phylink_validate, .prevalidate_phy_mode = vsc9959_prevalidate_phy_mode, - .port_setup_tc = vsc9959_port_setup_tc, - .port_sched_speed_set = vsc9959_sched_speed_set, + .port_setup_tc = vsc9959_port_setup_tc, + .port_sched_speed_set = vsc9959_sched_speed_set, .xmit_template_populate = vsc9959_xmit_template_populate, }; @@ -1307,9 +1328,13 @@ static struct pci_device_id felix_ids[] = { }; MODULE_DEVICE_TABLE(pci, felix_ids); -struct pci_driver felix_vsc9959_pci_driver = { +static struct pci_driver felix_vsc9959_pci_driver = { .name = "mscc_felix", .id_table = felix_ids, .probe = felix_pci_probe, .remove = felix_pci_remove, }; +module_pci_driver(felix_vsc9959_pci_driver); + +MODULE_DESCRIPTION("Felix Switch driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c index 2d6a5f5758f8..12c7fb9c2c3f 100644 --- a/drivers/net/dsa/ocelot/seville_vsc9953.c +++ b/drivers/net/dsa/ocelot/seville_vsc9953.c @@ -16,23 +16,12 @@ #define VSC9953_VCAP_IS2_ENTRY_WIDTH 376 #define VSC9953_VCAP_PORT_CNT 10 -#define MSCC_MIIM_REG_STATUS 0x0 -#define MSCC_MIIM_STATUS_STAT_BUSY BIT(3) -#define MSCC_MIIM_REG_CMD 0x8 -#define MSCC_MIIM_CMD_OPR_WRITE BIT(1) -#define MSCC_MIIM_CMD_OPR_READ BIT(2) -#define MSCC_MIIM_CMD_WRDATA_SHIFT 4 -#define MSCC_MIIM_CMD_REGAD_SHIFT 20 -#define MSCC_MIIM_CMD_PHYAD_SHIFT 25 -#define MSCC_MIIM_CMD_VLD BIT(31) -#define MSCC_MIIM_REG_DATA 0xC -#define MSCC_MIIM_DATA_ERROR (BIT(16) | BIT(17)) - -#define MSCC_PHY_REG_PHY_CFG 0x0 -#define PHY_CFG_PHY_ENA (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -#define PHY_CFG_PHY_COMMON_RESET BIT(4) -#define PHY_CFG_PHY_RESET (BIT(5) | BIT(6) | BIT(7) | BIT(8)) -#define MSCC_PHY_REG_PHY_STATUS 0x4 +#define MSCC_MIIM_CMD_OPR_WRITE BIT(1) +#define MSCC_MIIM_CMD_OPR_READ BIT(2) +#define MSCC_MIIM_CMD_WRDATA_SHIFT 4 +#define MSCC_MIIM_CMD_REGAD_SHIFT 20 +#define MSCC_MIIM_CMD_PHYAD_SHIFT 25 +#define MSCC_MIIM_CMD_VLD BIT(31) static const u32 vsc9953_ana_regmap[] = { REG(ANA_ADVLEARN, 0x00b500), @@ -820,6 +809,10 @@ out: return err; } +/* CORE_ENA is in SYS:SYSTEM:RESET_CFG + * MEM_INIT is in SYS:SYSTEM:RESET_CFG + * MEM_ENA is in SYS:SYSTEM:RESET_CFG + */ static int vsc9953_reset(struct ocelot *ocelot) { int val, err; @@ -835,8 +828,8 @@ static int vsc9953_reset(struct ocelot *ocelot) } /* initialize switch mem ~40us */ - ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_INIT, 1); ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_ENA, 1); + ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_INIT, 1); err = readx_poll_timeout(vsc9953_sys_ram_init_status, ocelot, val, !val, VSC9953_SYS_RAMINIT_SLEEP, @@ -847,7 +840,6 @@ static int vsc9953_reset(struct ocelot *ocelot) } /* enable switch core */ - ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_ENA, 1); ocelot_field_write(ocelot, SYS_RESET_CFG_CORE_ENA, 1); return 0; @@ -989,6 +981,23 @@ static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot) return 0; } +static void vsc9953_mdio_bus_free(struct ocelot *ocelot) +{ + struct felix *felix = ocelot_to_felix(ocelot); + int port; + + for (port = 0; port < ocelot->num_phys_ports; port++) { + struct lynx_pcs *pcs = felix->pcs[port]; + + if (!pcs) + continue; + + mdio_device_free(pcs->mdio); + lynx_pcs_destroy(pcs); + } + mdiobus_unregister(felix->imdio); +} + static void vsc9953_xmit_template_populate(struct ocelot *ocelot, int port) { struct ocelot_port *ocelot_port = ocelot->ports[port]; @@ -1022,7 +1031,7 @@ static const struct felix_info seville_info_vsc9953 = { .num_mact_rows = 2048, .num_ports = 10, .mdio_bus_alloc = vsc9953_mdio_bus_alloc, - .mdio_bus_free = vsc9959_mdio_bus_free, + .mdio_bus_free = vsc9953_mdio_bus_free, .phylink_validate = vsc9953_phylink_validate, .prevalidate_phy_mode = vsc9953_prevalidate_phy_mode, .xmit_template_populate = vsc9953_xmit_template_populate, @@ -1101,7 +1110,7 @@ static const struct of_device_id seville_of_match[] = { }; MODULE_DEVICE_TABLE(of, seville_of_match); -struct platform_driver seville_vsc9953_driver = { +static struct platform_driver seville_vsc9953_driver = { .probe = seville_probe, .remove = seville_remove, .driver = { @@ -1109,3 +1118,7 @@ struct platform_driver seville_vsc9953_driver = { .of_match_table = of_match_ptr(seville_of_match), }, }; +module_platform_driver(seville_vsc9953_driver); + +MODULE_DESCRIPTION("Seville Switch driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/ethernet/mscc/ocelot_ptp.c b/drivers/net/ethernet/mscc/ocelot_ptp.c index 1e08fe4daaef..a33ab315cc6b 100644 --- a/drivers/net/ethernet/mscc/ocelot_ptp.c +++ b/drivers/net/ethernet/mscc/ocelot_ptp.c @@ -300,7 +300,8 @@ int ocelot_ptp_enable(struct ptp_clock_info *ptp, } EXPORT_SYMBOL(ocelot_ptp_enable); -int ocelot_init_timestamp(struct ocelot *ocelot, struct ptp_clock_info *info) +int ocelot_init_timestamp(struct ocelot *ocelot, + const struct ptp_clock_info *info) { struct ptp_clock *ptp_clock; int i; diff --git a/include/soc/mscc/ocelot_ptp.h b/include/soc/mscc/ocelot_ptp.h index 4a6b2f71b6b2..6a7388fa7cc5 100644 --- a/include/soc/mscc/ocelot_ptp.h +++ b/include/soc/mscc/ocelot_ptp.h @@ -53,6 +53,7 @@ int ocelot_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, enum ptp_pin_function func, unsigned int chan); int ocelot_ptp_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *rq, int on); -int ocelot_init_timestamp(struct ocelot *ocelot, struct ptp_clock_info *info); +int ocelot_init_timestamp(struct ocelot *ocelot, + const struct ptp_clock_info *info); int ocelot_deinit_timestamp(struct ocelot *ocelot); #endif |