Skip to content

Commit 84705fc

Browse files
fidomaxdavem330
authored andcommitted
net: dsa: felix: introduce support for Seville VSC9953 switch
This is another switch from Vitesse / Microsemi / Microchip, that has 10 ports (8 external, 2 internal) and is integrated into the Freescale / NXP T1040 PowerPC SoC. It is very similar to Felix from NXP LS1028A, except that this is a platform device and Felix is a PCI device, and it doesn't support IEEE 1588 and TSN. Like Felix, this driver configures its own PCS on the internal MDIO bus using a phy_device abstraction for it (yes, it will be refactored to use a raw mdio_device, like other phylink drivers do, but let's keep it like that for now). But unlike Felix, the MDIO bus and the PCS are not from the same vendor. The PCS is the same QorIQ/Layerscape PCS as found in Felix/ENETC/DPAA*, but the internal MDIO bus that is used to access it is actually an instantiation of drivers/net/phy/mdio-mscc-miim.c. But it would be difficult to reuse that driver (it doesn't even use regmap, and it's less than 200 lines of code), so we hand-roll here some internal MDIO bus accessors within seville_vsc9953.c, which serves the purpose of driving the PCS absolutely fine. Also, same as Felix, the PCS doesn't support dynamic reconfiguration of SerDes protocol, so we need to do pre-validation of PHY mode from device tree and not let phylink change it. Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 375e131 commit 84705fc

File tree

6 files changed

+1149
-16
lines changed

6 files changed

+1149
-16
lines changed

drivers/net/dsa/ocelot/Kconfig

+8-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ config NET_DSA_MSCC_FELIX
1010
select NET_DSA_TAG_OCELOT
1111
select FSL_ENETC_MDIO
1212
help
13-
This driver supports the VSC9959 network switch, which is a member of
14-
the Vitesse / Microsemi / Microchip Ocelot family of switching cores.
15-
It is embedded as a PCIe function of the NXP LS1028A ENETC integrated
16-
endpoint.
13+
This driver supports network switches from the the Vitesse /
14+
Microsemi / Microchip Ocelot family of switching cores that are
15+
connected to their host CPU via Ethernet.
16+
The following switches are supported:
17+
- VSC9959 (Felix): embedded as a PCIe function of the NXP LS1028A
18+
ENETC integrated endpoint.
19+
- VSC9953 (Seville): embedded as a platform device on the
20+
NXP T1040 SoC.

drivers/net/dsa/ocelot/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ obj-$(CONFIG_NET_DSA_MSCC_FELIX) += mscc_felix.o
33

44
mscc_felix-objs := \
55
felix.o \
6-
felix_vsc9959.o
6+
felix_vsc9959.o \
7+
seville_vsc9953.o

drivers/net/dsa/ocelot/felix.c

+13-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <soc/mscc/ocelot_ana.h>
1414
#include <soc/mscc/ocelot_ptp.h>
1515
#include <soc/mscc/ocelot.h>
16+
#include <linux/platform_device.h>
1617
#include <linux/packing.h>
1718
#include <linux/module.h>
1819
#include <linux/of_net.h>
@@ -820,13 +821,24 @@ const struct dsa_switch_ops felix_switch_ops = {
820821

821822
static int __init felix_init(void)
822823
{
823-
return pci_register_driver(&felix_vsc9959_pci_driver);
824+
int err;
825+
826+
err = pci_register_driver(&felix_vsc9959_pci_driver);
827+
if (err)
828+
return err;
829+
830+
err = platform_driver_register(&seville_vsc9953_driver);
831+
if (err)
832+
return err;
833+
834+
return 0;
824835
}
825836
module_init(felix_init);
826837

827838
static void __exit felix_exit(void)
828839
{
829840
pci_unregister_driver(&felix_vsc9959_pci_driver);
841+
platform_driver_unregister(&seville_vsc9953_driver);
830842
}
831843
module_exit(felix_exit);
832844

drivers/net/dsa/ocelot/felix.h

+12
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct felix_info {
5151

5252
extern const struct dsa_switch_ops felix_switch_ops;
5353
extern struct pci_driver felix_vsc9959_pci_driver;
54+
extern struct platform_driver seville_vsc9953_driver;
5455

5556
/* DSA glue / front-end for struct ocelot */
5657
struct felix {
@@ -63,4 +64,15 @@ struct felix {
6364
resource_size_t imdio_base;
6465
};
6566

67+
void vsc9959_pcs_link_state(struct ocelot *ocelot, int port,
68+
struct phylink_link_state *state);
69+
void vsc9959_pcs_config(struct ocelot *ocelot, int port,
70+
unsigned int link_an_mode,
71+
const struct phylink_link_state *state);
72+
void vsc9959_pcs_link_up(struct ocelot *ocelot, int port,
73+
unsigned int link_an_mode,
74+
phy_interface_t interface,
75+
int speed, int duplex);
76+
void vsc9959_mdio_bus_free(struct ocelot *ocelot);
77+
6678
#endif

drivers/net/dsa/ocelot/felix_vsc9959.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -852,9 +852,9 @@ static void vsc9959_pcs_config_usxgmii(struct phy_device *pcs,
852852
USXGMII_ADVERTISE_FDX);
853853
}
854854

855-
static void vsc9959_pcs_config(struct ocelot *ocelot, int port,
856-
unsigned int link_an_mode,
857-
const struct phylink_link_state *state)
855+
void vsc9959_pcs_config(struct ocelot *ocelot, int port,
856+
unsigned int link_an_mode,
857+
const struct phylink_link_state *state)
858858
{
859859
struct felix *felix = ocelot_to_felix(ocelot);
860860
struct phy_device *pcs = felix->pcs[port];
@@ -965,10 +965,10 @@ static void vsc9959_pcs_link_up_2500basex(struct phy_device *pcs,
965965
phy_clear_bits(pcs, MII_BMCR, BMCR_ANENABLE);
966966
}
967967

968-
static void vsc9959_pcs_link_up(struct ocelot *ocelot, int port,
969-
unsigned int link_an_mode,
970-
phy_interface_t interface,
971-
int speed, int duplex)
968+
void vsc9959_pcs_link_up(struct ocelot *ocelot, int port,
969+
unsigned int link_an_mode,
970+
phy_interface_t interface,
971+
int speed, int duplex)
972972
{
973973
struct felix *felix = ocelot_to_felix(ocelot);
974974
struct phy_device *pcs = felix->pcs[port];
@@ -1096,8 +1096,8 @@ static void vsc9959_pcs_link_state_usxgmii(struct phy_device *pcs,
10961096
pcs->duplex = DUPLEX_HALF;
10971097
}
10981098

1099-
static void vsc9959_pcs_link_state(struct ocelot *ocelot, int port,
1100-
struct phylink_link_state *state)
1099+
void vsc9959_pcs_link_state(struct ocelot *ocelot, int port,
1100+
struct phylink_link_state *state)
11011101
{
11021102
struct felix *felix = ocelot_to_felix(ocelot);
11031103
struct phy_device *pcs = felix->pcs[port];
@@ -1286,7 +1286,7 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
12861286
return 0;
12871287
}
12881288

1289-
static void vsc9959_mdio_bus_free(struct ocelot *ocelot)
1289+
void vsc9959_mdio_bus_free(struct ocelot *ocelot)
12901290
{
12911291
struct felix *felix = ocelot_to_felix(ocelot);
12921292
int port;

0 commit comments

Comments
 (0)