net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
|
|
|
/* Copyright 2017 Microsemi Corporation
|
|
|
|
* Copyright 2018-2019 NXP Semiconductors
|
|
|
|
*/
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
#include <linux/fsl/enetc_mdio.h>
|
2020-05-13 02:25:09 +00:00
|
|
|
#include <soc/mscc/ocelot_qsys.h>
|
2020-02-29 14:31:14 +00:00
|
|
|
#include <soc/mscc/ocelot_vcap.h>
|
2020-05-13 02:25:09 +00:00
|
|
|
#include <soc/mscc/ocelot_ptp.h>
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
#include <soc/mscc/ocelot_sys.h>
|
|
|
|
#include <soc/mscc/ocelot.h>
|
2021-02-13 22:37:56 +00:00
|
|
|
#include <linux/dsa/ocelot.h>
|
2020-08-30 08:34:02 +00:00
|
|
|
#include <linux/pcs-lynx.h>
|
2020-05-13 02:25:09 +00:00
|
|
|
#include <net/pkt_sched.h>
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
#include <linux/iopoll.h>
|
2020-07-19 22:03:34 +00:00
|
|
|
#include <linux/mdio.h>
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
#include <linux/pci.h>
|
|
|
|
#include "felix.h"
|
|
|
|
|
2020-05-13 02:25:09 +00:00
|
|
|
#define VSC9959_TAS_GCL_ENTRY_MAX 63
|
|
|
|
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
static const u32 vsc9959_ana_regmap[] = {
|
|
|
|
REG(ANA_ADVLEARN, 0x0089a0),
|
|
|
|
REG(ANA_VLANMASK, 0x0089a4),
|
|
|
|
REG_RESERVED(ANA_PORT_B_DOMAIN),
|
|
|
|
REG(ANA_ANAGEFIL, 0x0089ac),
|
|
|
|
REG(ANA_ANEVENTS, 0x0089b0),
|
|
|
|
REG(ANA_STORMLIMIT_BURST, 0x0089b4),
|
|
|
|
REG(ANA_STORMLIMIT_CFG, 0x0089b8),
|
|
|
|
REG(ANA_ISOLATED_PORTS, 0x0089c8),
|
|
|
|
REG(ANA_COMMUNITY_PORTS, 0x0089cc),
|
|
|
|
REG(ANA_AUTOAGE, 0x0089d0),
|
|
|
|
REG(ANA_MACTOPTIONS, 0x0089d4),
|
|
|
|
REG(ANA_LEARNDISC, 0x0089d8),
|
|
|
|
REG(ANA_AGENCTRL, 0x0089dc),
|
|
|
|
REG(ANA_MIRRORPORTS, 0x0089e0),
|
|
|
|
REG(ANA_EMIRRORPORTS, 0x0089e4),
|
|
|
|
REG(ANA_FLOODING, 0x0089e8),
|
|
|
|
REG(ANA_FLOODING_IPMC, 0x008a08),
|
|
|
|
REG(ANA_SFLOW_CFG, 0x008a0c),
|
|
|
|
REG(ANA_PORT_MODE, 0x008a28),
|
|
|
|
REG(ANA_CUT_THRU_CFG, 0x008a48),
|
|
|
|
REG(ANA_PGID_PGID, 0x008400),
|
|
|
|
REG(ANA_TABLES_ANMOVED, 0x007f1c),
|
|
|
|
REG(ANA_TABLES_MACHDATA, 0x007f20),
|
|
|
|
REG(ANA_TABLES_MACLDATA, 0x007f24),
|
|
|
|
REG(ANA_TABLES_STREAMDATA, 0x007f28),
|
|
|
|
REG(ANA_TABLES_MACACCESS, 0x007f2c),
|
|
|
|
REG(ANA_TABLES_MACTINDX, 0x007f30),
|
|
|
|
REG(ANA_TABLES_VLANACCESS, 0x007f34),
|
|
|
|
REG(ANA_TABLES_VLANTIDX, 0x007f38),
|
|
|
|
REG(ANA_TABLES_ISDXACCESS, 0x007f3c),
|
|
|
|
REG(ANA_TABLES_ISDXTIDX, 0x007f40),
|
|
|
|
REG(ANA_TABLES_ENTRYLIM, 0x007f00),
|
|
|
|
REG(ANA_TABLES_PTP_ID_HIGH, 0x007f44),
|
|
|
|
REG(ANA_TABLES_PTP_ID_LOW, 0x007f48),
|
|
|
|
REG(ANA_TABLES_STREAMACCESS, 0x007f4c),
|
|
|
|
REG(ANA_TABLES_STREAMTIDX, 0x007f50),
|
|
|
|
REG(ANA_TABLES_SEQ_HISTORY, 0x007f54),
|
|
|
|
REG(ANA_TABLES_SEQ_MASK, 0x007f58),
|
|
|
|
REG(ANA_TABLES_SFID_MASK, 0x007f5c),
|
|
|
|
REG(ANA_TABLES_SFIDACCESS, 0x007f60),
|
|
|
|
REG(ANA_TABLES_SFIDTIDX, 0x007f64),
|
|
|
|
REG(ANA_MSTI_STATE, 0x008600),
|
|
|
|
REG(ANA_OAM_UPM_LM_CNT, 0x008000),
|
|
|
|
REG(ANA_SG_ACCESS_CTRL, 0x008a64),
|
|
|
|
REG(ANA_SG_CONFIG_REG_1, 0x007fb0),
|
|
|
|
REG(ANA_SG_CONFIG_REG_2, 0x007fb4),
|
|
|
|
REG(ANA_SG_CONFIG_REG_3, 0x007fb8),
|
|
|
|
REG(ANA_SG_CONFIG_REG_4, 0x007fbc),
|
|
|
|
REG(ANA_SG_CONFIG_REG_5, 0x007fc0),
|
|
|
|
REG(ANA_SG_GCL_GS_CONFIG, 0x007f80),
|
|
|
|
REG(ANA_SG_GCL_TI_CONFIG, 0x007f90),
|
|
|
|
REG(ANA_SG_STATUS_REG_1, 0x008980),
|
|
|
|
REG(ANA_SG_STATUS_REG_2, 0x008984),
|
|
|
|
REG(ANA_SG_STATUS_REG_3, 0x008988),
|
|
|
|
REG(ANA_PORT_VLAN_CFG, 0x007800),
|
|
|
|
REG(ANA_PORT_DROP_CFG, 0x007804),
|
|
|
|
REG(ANA_PORT_QOS_CFG, 0x007808),
|
|
|
|
REG(ANA_PORT_VCAP_CFG, 0x00780c),
|
|
|
|
REG(ANA_PORT_VCAP_S1_KEY_CFG, 0x007810),
|
|
|
|
REG(ANA_PORT_VCAP_S2_CFG, 0x00781c),
|
|
|
|
REG(ANA_PORT_PCP_DEI_MAP, 0x007820),
|
|
|
|
REG(ANA_PORT_CPU_FWD_CFG, 0x007860),
|
|
|
|
REG(ANA_PORT_CPU_FWD_BPDU_CFG, 0x007864),
|
|
|
|
REG(ANA_PORT_CPU_FWD_GARP_CFG, 0x007868),
|
|
|
|
REG(ANA_PORT_CPU_FWD_CCM_CFG, 0x00786c),
|
|
|
|
REG(ANA_PORT_PORT_CFG, 0x007870),
|
|
|
|
REG(ANA_PORT_POL_CFG, 0x007874),
|
|
|
|
REG(ANA_PORT_PTP_CFG, 0x007878),
|
|
|
|
REG(ANA_PORT_PTP_DLY1_CFG, 0x00787c),
|
|
|
|
REG(ANA_PORT_PTP_DLY2_CFG, 0x007880),
|
|
|
|
REG(ANA_PORT_SFID_CFG, 0x007884),
|
|
|
|
REG(ANA_PFC_PFC_CFG, 0x008800),
|
|
|
|
REG_RESERVED(ANA_PFC_PFC_TIMER),
|
|
|
|
REG_RESERVED(ANA_IPT_OAM_MEP_CFG),
|
|
|
|
REG_RESERVED(ANA_IPT_IPT),
|
|
|
|
REG_RESERVED(ANA_PPT_PPT),
|
|
|
|
REG_RESERVED(ANA_FID_MAP_FID_MAP),
|
|
|
|
REG(ANA_AGGR_CFG, 0x008a68),
|
|
|
|
REG(ANA_CPUQ_CFG, 0x008a6c),
|
|
|
|
REG_RESERVED(ANA_CPUQ_CFG2),
|
|
|
|
REG(ANA_CPUQ_8021_CFG, 0x008a74),
|
|
|
|
REG(ANA_DSCP_CFG, 0x008ab4),
|
|
|
|
REG(ANA_DSCP_REWR_CFG, 0x008bb4),
|
|
|
|
REG(ANA_VCAP_RNG_TYPE_CFG, 0x008bf4),
|
|
|
|
REG(ANA_VCAP_RNG_VAL_CFG, 0x008c14),
|
|
|
|
REG_RESERVED(ANA_VRAP_CFG),
|
|
|
|
REG_RESERVED(ANA_VRAP_HDR_DATA),
|
|
|
|
REG_RESERVED(ANA_VRAP_HDR_MASK),
|
|
|
|
REG(ANA_DISCARD_CFG, 0x008c40),
|
|
|
|
REG(ANA_FID_CFG, 0x008c44),
|
|
|
|
REG(ANA_POL_PIR_CFG, 0x004000),
|
|
|
|
REG(ANA_POL_CIR_CFG, 0x004004),
|
|
|
|
REG(ANA_POL_MODE_CFG, 0x004008),
|
|
|
|
REG(ANA_POL_PIR_STATE, 0x00400c),
|
|
|
|
REG(ANA_POL_CIR_STATE, 0x004010),
|
|
|
|
REG_RESERVED(ANA_POL_STATE),
|
|
|
|
REG(ANA_POL_FLOWC, 0x008c48),
|
|
|
|
REG(ANA_POL_HYST, 0x008cb4),
|
|
|
|
REG_RESERVED(ANA_POL_MISC_CFG),
|
|
|
|
};
|
|
|
|
|
|
|
|
static const u32 vsc9959_qs_regmap[] = {
|
|
|
|
REG(QS_XTR_GRP_CFG, 0x000000),
|
|
|
|
REG(QS_XTR_RD, 0x000008),
|
|
|
|
REG(QS_XTR_FRM_PRUNING, 0x000010),
|
|
|
|
REG(QS_XTR_FLUSH, 0x000018),
|
|
|
|
REG(QS_XTR_DATA_PRESENT, 0x00001c),
|
|
|
|
REG(QS_XTR_CFG, 0x000020),
|
|
|
|
REG(QS_INJ_GRP_CFG, 0x000024),
|
|
|
|
REG(QS_INJ_WR, 0x00002c),
|
|
|
|
REG(QS_INJ_CTRL, 0x000034),
|
|
|
|
REG(QS_INJ_STATUS, 0x00003c),
|
|
|
|
REG(QS_INJ_ERR, 0x000040),
|
|
|
|
REG_RESERVED(QS_INH_DBG),
|
|
|
|
};
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-29 22:27:23 +00:00
|
|
|
static const u32 vsc9959_vcap_regmap[] = {
|
|
|
|
/* VCAP_CORE_CFG */
|
|
|
|
REG(VCAP_CORE_UPDATE_CTRL, 0x000000),
|
|
|
|
REG(VCAP_CORE_MV_CFG, 0x000004),
|
|
|
|
/* VCAP_CORE_CACHE */
|
|
|
|
REG(VCAP_CACHE_ENTRY_DAT, 0x000008),
|
|
|
|
REG(VCAP_CACHE_MASK_DAT, 0x000108),
|
|
|
|
REG(VCAP_CACHE_ACTION_DAT, 0x000208),
|
|
|
|
REG(VCAP_CACHE_CNT_DAT, 0x000308),
|
|
|
|
REG(VCAP_CACHE_TG_DAT, 0x000388),
|
2020-09-29 22:27:26 +00:00
|
|
|
/* VCAP_CONST */
|
|
|
|
REG(VCAP_CONST_VCAP_VER, 0x000398),
|
|
|
|
REG(VCAP_CONST_ENTRY_WIDTH, 0x00039c),
|
|
|
|
REG(VCAP_CONST_ENTRY_CNT, 0x0003a0),
|
|
|
|
REG(VCAP_CONST_ENTRY_SWCNT, 0x0003a4),
|
|
|
|
REG(VCAP_CONST_ENTRY_TG_WIDTH, 0x0003a8),
|
|
|
|
REG(VCAP_CONST_ACTION_DEF_CNT, 0x0003ac),
|
|
|
|
REG(VCAP_CONST_ACTION_WIDTH, 0x0003b0),
|
|
|
|
REG(VCAP_CONST_CNT_WIDTH, 0x0003b4),
|
|
|
|
REG(VCAP_CONST_CORE_CNT, 0x0003b8),
|
|
|
|
REG(VCAP_CONST_IF_CNT, 0x0003bc),
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const u32 vsc9959_qsys_regmap[] = {
|
|
|
|
REG(QSYS_PORT_MODE, 0x00f460),
|
|
|
|
REG(QSYS_SWITCH_PORT_MODE, 0x00f480),
|
|
|
|
REG(QSYS_STAT_CNT_CFG, 0x00f49c),
|
|
|
|
REG(QSYS_EEE_CFG, 0x00f4a0),
|
|
|
|
REG(QSYS_EEE_THRES, 0x00f4b8),
|
|
|
|
REG(QSYS_IGR_NO_SHARING, 0x00f4bc),
|
|
|
|
REG(QSYS_EGR_NO_SHARING, 0x00f4c0),
|
|
|
|
REG(QSYS_SW_STATUS, 0x00f4c4),
|
|
|
|
REG(QSYS_EXT_CPU_CFG, 0x00f4e0),
|
|
|
|
REG_RESERVED(QSYS_PAD_CFG),
|
|
|
|
REG(QSYS_CPU_GROUP_MAP, 0x00f4e8),
|
|
|
|
REG_RESERVED(QSYS_QMAP),
|
|
|
|
REG_RESERVED(QSYS_ISDX_SGRP),
|
|
|
|
REG_RESERVED(QSYS_TIMED_FRAME_ENTRY),
|
|
|
|
REG(QSYS_TFRM_MISC, 0x00f50c),
|
|
|
|
REG(QSYS_TFRM_PORT_DLY, 0x00f510),
|
|
|
|
REG(QSYS_TFRM_TIMER_CFG_1, 0x00f514),
|
|
|
|
REG(QSYS_TFRM_TIMER_CFG_2, 0x00f518),
|
|
|
|
REG(QSYS_TFRM_TIMER_CFG_3, 0x00f51c),
|
|
|
|
REG(QSYS_TFRM_TIMER_CFG_4, 0x00f520),
|
|
|
|
REG(QSYS_TFRM_TIMER_CFG_5, 0x00f524),
|
|
|
|
REG(QSYS_TFRM_TIMER_CFG_6, 0x00f528),
|
|
|
|
REG(QSYS_TFRM_TIMER_CFG_7, 0x00f52c),
|
|
|
|
REG(QSYS_TFRM_TIMER_CFG_8, 0x00f530),
|
|
|
|
REG(QSYS_RED_PROFILE, 0x00f534),
|
|
|
|
REG(QSYS_RES_QOS_MODE, 0x00f574),
|
|
|
|
REG(QSYS_RES_CFG, 0x00c000),
|
|
|
|
REG(QSYS_RES_STAT, 0x00c004),
|
|
|
|
REG(QSYS_EGR_DROP_MODE, 0x00f578),
|
|
|
|
REG(QSYS_EQ_CTRL, 0x00f57c),
|
|
|
|
REG_RESERVED(QSYS_EVENTS_CORE),
|
|
|
|
REG(QSYS_QMAXSDU_CFG_0, 0x00f584),
|
|
|
|
REG(QSYS_QMAXSDU_CFG_1, 0x00f5a0),
|
|
|
|
REG(QSYS_QMAXSDU_CFG_2, 0x00f5bc),
|
|
|
|
REG(QSYS_QMAXSDU_CFG_3, 0x00f5d8),
|
|
|
|
REG(QSYS_QMAXSDU_CFG_4, 0x00f5f4),
|
|
|
|
REG(QSYS_QMAXSDU_CFG_5, 0x00f610),
|
|
|
|
REG(QSYS_QMAXSDU_CFG_6, 0x00f62c),
|
|
|
|
REG(QSYS_QMAXSDU_CFG_7, 0x00f648),
|
|
|
|
REG(QSYS_PREEMPTION_CFG, 0x00f664),
|
2020-05-13 02:25:10 +00:00
|
|
|
REG(QSYS_CIR_CFG, 0x000000),
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
REG(QSYS_EIR_CFG, 0x000004),
|
|
|
|
REG(QSYS_SE_CFG, 0x000008),
|
|
|
|
REG(QSYS_SE_DWRR_CFG, 0x00000c),
|
|
|
|
REG_RESERVED(QSYS_SE_CONNECT),
|
|
|
|
REG(QSYS_SE_DLB_SENSE, 0x000040),
|
|
|
|
REG(QSYS_CIR_STATE, 0x000044),
|
|
|
|
REG(QSYS_EIR_STATE, 0x000048),
|
|
|
|
REG_RESERVED(QSYS_SE_STATE),
|
|
|
|
REG(QSYS_HSCH_MISC_CFG, 0x00f67c),
|
|
|
|
REG(QSYS_TAG_CONFIG, 0x00f680),
|
|
|
|
REG(QSYS_TAS_PARAM_CFG_CTRL, 0x00f698),
|
|
|
|
REG(QSYS_PORT_MAX_SDU, 0x00f69c),
|
|
|
|
REG(QSYS_PARAM_CFG_REG_1, 0x00f440),
|
|
|
|
REG(QSYS_PARAM_CFG_REG_2, 0x00f444),
|
|
|
|
REG(QSYS_PARAM_CFG_REG_3, 0x00f448),
|
|
|
|
REG(QSYS_PARAM_CFG_REG_4, 0x00f44c),
|
|
|
|
REG(QSYS_PARAM_CFG_REG_5, 0x00f450),
|
|
|
|
REG(QSYS_GCL_CFG_REG_1, 0x00f454),
|
|
|
|
REG(QSYS_GCL_CFG_REG_2, 0x00f458),
|
|
|
|
REG(QSYS_PARAM_STATUS_REG_1, 0x00f400),
|
|
|
|
REG(QSYS_PARAM_STATUS_REG_2, 0x00f404),
|
|
|
|
REG(QSYS_PARAM_STATUS_REG_3, 0x00f408),
|
|
|
|
REG(QSYS_PARAM_STATUS_REG_4, 0x00f40c),
|
|
|
|
REG(QSYS_PARAM_STATUS_REG_5, 0x00f410),
|
|
|
|
REG(QSYS_PARAM_STATUS_REG_6, 0x00f414),
|
|
|
|
REG(QSYS_PARAM_STATUS_REG_7, 0x00f418),
|
|
|
|
REG(QSYS_PARAM_STATUS_REG_8, 0x00f41c),
|
|
|
|
REG(QSYS_PARAM_STATUS_REG_9, 0x00f420),
|
|
|
|
REG(QSYS_GCL_STATUS_REG_1, 0x00f424),
|
|
|
|
REG(QSYS_GCL_STATUS_REG_2, 0x00f428),
|
|
|
|
};
|
|
|
|
|
|
|
|
static const u32 vsc9959_rew_regmap[] = {
|
|
|
|
REG(REW_PORT_VLAN_CFG, 0x000000),
|
|
|
|
REG(REW_TAG_CFG, 0x000004),
|
|
|
|
REG(REW_PORT_CFG, 0x000008),
|
|
|
|
REG(REW_DSCP_CFG, 0x00000c),
|
|
|
|
REG(REW_PCP_DEI_QOS_MAP_CFG, 0x000010),
|
|
|
|
REG(REW_PTP_CFG, 0x000050),
|
|
|
|
REG(REW_PTP_DLY1_CFG, 0x000054),
|
|
|
|
REG(REW_RED_TAG_CFG, 0x000058),
|
|
|
|
REG(REW_DSCP_REMAP_DP1_CFG, 0x000410),
|
|
|
|
REG(REW_DSCP_REMAP_CFG, 0x000510),
|
|
|
|
REG_RESERVED(REW_STAT_CFG),
|
|
|
|
REG_RESERVED(REW_REW_STICKY),
|
|
|
|
REG_RESERVED(REW_PPT),
|
|
|
|
};
|
|
|
|
|
|
|
|
static const u32 vsc9959_sys_regmap[] = {
|
|
|
|
REG(SYS_COUNT_RX_OCTETS, 0x000000),
|
|
|
|
REG(SYS_COUNT_RX_MULTICAST, 0x000008),
|
|
|
|
REG(SYS_COUNT_RX_SHORTS, 0x000010),
|
|
|
|
REG(SYS_COUNT_RX_FRAGMENTS, 0x000014),
|
|
|
|
REG(SYS_COUNT_RX_JABBERS, 0x000018),
|
|
|
|
REG(SYS_COUNT_RX_64, 0x000024),
|
|
|
|
REG(SYS_COUNT_RX_65_127, 0x000028),
|
|
|
|
REG(SYS_COUNT_RX_128_255, 0x00002c),
|
|
|
|
REG(SYS_COUNT_RX_256_1023, 0x000030),
|
|
|
|
REG(SYS_COUNT_RX_1024_1526, 0x000034),
|
|
|
|
REG(SYS_COUNT_RX_1527_MAX, 0x000038),
|
|
|
|
REG(SYS_COUNT_RX_LONGS, 0x000044),
|
|
|
|
REG(SYS_COUNT_TX_OCTETS, 0x000200),
|
|
|
|
REG(SYS_COUNT_TX_COLLISION, 0x000210),
|
|
|
|
REG(SYS_COUNT_TX_DROPS, 0x000214),
|
|
|
|
REG(SYS_COUNT_TX_64, 0x00021c),
|
|
|
|
REG(SYS_COUNT_TX_65_127, 0x000220),
|
|
|
|
REG(SYS_COUNT_TX_128_511, 0x000224),
|
|
|
|
REG(SYS_COUNT_TX_512_1023, 0x000228),
|
|
|
|
REG(SYS_COUNT_TX_1024_1526, 0x00022c),
|
|
|
|
REG(SYS_COUNT_TX_1527_MAX, 0x000230),
|
|
|
|
REG(SYS_COUNT_TX_AGING, 0x000278),
|
|
|
|
REG(SYS_RESET_CFG, 0x000e00),
|
|
|
|
REG(SYS_SR_ETYPE_CFG, 0x000e04),
|
|
|
|
REG(SYS_VLAN_ETYPE_CFG, 0x000e08),
|
|
|
|
REG(SYS_PORT_MODE, 0x000e0c),
|
|
|
|
REG(SYS_FRONT_PORT_MODE, 0x000e2c),
|
|
|
|
REG(SYS_FRM_AGING, 0x000e44),
|
|
|
|
REG(SYS_STAT_CFG, 0x000e48),
|
|
|
|
REG(SYS_SW_STATUS, 0x000e4c),
|
|
|
|
REG_RESERVED(SYS_MISC_CFG),
|
|
|
|
REG(SYS_REW_MAC_HIGH_CFG, 0x000e6c),
|
|
|
|
REG(SYS_REW_MAC_LOW_CFG, 0x000e84),
|
|
|
|
REG(SYS_TIMESTAMP_OFFSET, 0x000e9c),
|
|
|
|
REG(SYS_PAUSE_CFG, 0x000ea0),
|
|
|
|
REG(SYS_PAUSE_TOT_CFG, 0x000ebc),
|
|
|
|
REG(SYS_ATOP, 0x000ec0),
|
|
|
|
REG(SYS_ATOP_TOT_CFG, 0x000edc),
|
|
|
|
REG(SYS_MAC_FC_CFG, 0x000ee0),
|
|
|
|
REG(SYS_MMGT, 0x000ef8),
|
|
|
|
REG_RESERVED(SYS_MMGT_FAST),
|
|
|
|
REG_RESERVED(SYS_EVENTS_DIF),
|
|
|
|
REG_RESERVED(SYS_EVENTS_CORE),
|
|
|
|
REG_RESERVED(SYS_CNT),
|
|
|
|
REG(SYS_PTP_STATUS, 0x000f14),
|
|
|
|
REG(SYS_PTP_TXSTAMP, 0x000f18),
|
|
|
|
REG(SYS_PTP_NXT, 0x000f1c),
|
|
|
|
REG(SYS_PTP_CFG, 0x000f20),
|
|
|
|
REG(SYS_RAM_INIT, 0x000f24),
|
|
|
|
REG_RESERVED(SYS_CM_ADDR),
|
|
|
|
REG_RESERVED(SYS_CM_DATA_WR),
|
|
|
|
REG_RESERVED(SYS_CM_DATA_RD),
|
|
|
|
REG_RESERVED(SYS_CM_OP),
|
|
|
|
REG_RESERVED(SYS_CM_DATA),
|
|
|
|
};
|
|
|
|
|
2019-11-20 08:23:17 +00:00
|
|
|
static const u32 vsc9959_ptp_regmap[] = {
|
2020-09-18 10:57:49 +00:00
|
|
|
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),
|
2019-11-20 08:23:17 +00:00
|
|
|
};
|
|
|
|
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
static const u32 vsc9959_gcb_regmap[] = {
|
|
|
|
REG(GCB_SOFT_RST, 0x000004),
|
|
|
|
};
|
|
|
|
|
2020-07-13 16:57:01 +00:00
|
|
|
static const u32 vsc9959_dev_gmii_regmap[] = {
|
|
|
|
REG(DEV_CLOCK_CFG, 0x0),
|
|
|
|
REG(DEV_PORT_MISC, 0x4),
|
|
|
|
REG(DEV_EVENTS, 0x8),
|
|
|
|
REG(DEV_EEE_CFG, 0xc),
|
|
|
|
REG(DEV_RX_PATH_DELAY, 0x10),
|
|
|
|
REG(DEV_TX_PATH_DELAY, 0x14),
|
|
|
|
REG(DEV_PTP_PREDICT_CFG, 0x18),
|
|
|
|
REG(DEV_MAC_ENA_CFG, 0x1c),
|
|
|
|
REG(DEV_MAC_MODE_CFG, 0x20),
|
|
|
|
REG(DEV_MAC_MAXLEN_CFG, 0x24),
|
|
|
|
REG(DEV_MAC_TAGS_CFG, 0x28),
|
|
|
|
REG(DEV_MAC_ADV_CHK_CFG, 0x2c),
|
|
|
|
REG(DEV_MAC_IFG_CFG, 0x30),
|
|
|
|
REG(DEV_MAC_HDX_CFG, 0x34),
|
|
|
|
REG(DEV_MAC_DBG_CFG, 0x38),
|
|
|
|
REG(DEV_MAC_FC_MAC_LOW_CFG, 0x3c),
|
|
|
|
REG(DEV_MAC_FC_MAC_HIGH_CFG, 0x40),
|
|
|
|
REG(DEV_MAC_STICKY, 0x44),
|
|
|
|
REG_RESERVED(PCS1G_CFG),
|
|
|
|
REG_RESERVED(PCS1G_MODE_CFG),
|
|
|
|
REG_RESERVED(PCS1G_SD_CFG),
|
|
|
|
REG_RESERVED(PCS1G_ANEG_CFG),
|
|
|
|
REG_RESERVED(PCS1G_ANEG_NP_CFG),
|
|
|
|
REG_RESERVED(PCS1G_LB_CFG),
|
|
|
|
REG_RESERVED(PCS1G_DBG_CFG),
|
|
|
|
REG_RESERVED(PCS1G_CDET_CFG),
|
|
|
|
REG_RESERVED(PCS1G_ANEG_STATUS),
|
|
|
|
REG_RESERVED(PCS1G_ANEG_NP_STATUS),
|
|
|
|
REG_RESERVED(PCS1G_LINK_STATUS),
|
|
|
|
REG_RESERVED(PCS1G_LINK_DOWN_CNT),
|
|
|
|
REG_RESERVED(PCS1G_STICKY),
|
|
|
|
REG_RESERVED(PCS1G_DEBUG_STATUS),
|
|
|
|
REG_RESERVED(PCS1G_LPI_CFG),
|
|
|
|
REG_RESERVED(PCS1G_LPI_WAKE_ERROR_CNT),
|
|
|
|
REG_RESERVED(PCS1G_LPI_STATUS),
|
|
|
|
REG_RESERVED(PCS1G_TSTPAT_MODE_CFG),
|
|
|
|
REG_RESERVED(PCS1G_TSTPAT_STATUS),
|
|
|
|
REG_RESERVED(DEV_PCS_FX100_CFG),
|
|
|
|
REG_RESERVED(DEV_PCS_FX100_STATUS),
|
|
|
|
};
|
|
|
|
|
|
|
|
static const u32 *vsc9959_regmap[TARGET_MAX] = {
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
[ANA] = vsc9959_ana_regmap,
|
|
|
|
[QS] = vsc9959_qs_regmap,
|
|
|
|
[QSYS] = vsc9959_qsys_regmap,
|
|
|
|
[REW] = vsc9959_rew_regmap,
|
|
|
|
[SYS] = vsc9959_sys_regmap,
|
2020-09-29 22:27:25 +00:00
|
|
|
[S0] = vsc9959_vcap_regmap,
|
2020-09-29 22:27:24 +00:00
|
|
|
[S1] = vsc9959_vcap_regmap,
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-29 22:27:23 +00:00
|
|
|
[S2] = vsc9959_vcap_regmap,
|
2019-11-20 08:23:17 +00:00
|
|
|
[PTP] = vsc9959_ptp_regmap,
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
[GCB] = vsc9959_gcb_regmap,
|
2020-07-13 16:57:01 +00:00
|
|
|
[DEV_GMII] = vsc9959_dev_gmii_regmap,
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
};
|
|
|
|
|
2020-05-22 08:54:34 +00:00
|
|
|
/* Addresses are relative to the PCI device's base address */
|
2020-07-13 16:57:01 +00:00
|
|
|
static const struct resource vsc9959_target_io_res[TARGET_MAX] = {
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
[ANA] = {
|
|
|
|
.start = 0x0280000,
|
|
|
|
.end = 0x028ffff,
|
|
|
|
.name = "ana",
|
|
|
|
},
|
|
|
|
[QS] = {
|
|
|
|
.start = 0x0080000,
|
|
|
|
.end = 0x00800ff,
|
|
|
|
.name = "qs",
|
|
|
|
},
|
|
|
|
[QSYS] = {
|
|
|
|
.start = 0x0200000,
|
|
|
|
.end = 0x021ffff,
|
|
|
|
.name = "qsys",
|
|
|
|
},
|
|
|
|
[REW] = {
|
|
|
|
.start = 0x0030000,
|
|
|
|
.end = 0x003ffff,
|
|
|
|
.name = "rew",
|
|
|
|
},
|
|
|
|
[SYS] = {
|
|
|
|
.start = 0x0010000,
|
|
|
|
.end = 0x001ffff,
|
|
|
|
.name = "sys",
|
|
|
|
},
|
2020-09-29 22:27:25 +00:00
|
|
|
[S0] = {
|
|
|
|
.start = 0x0040000,
|
|
|
|
.end = 0x00403ff,
|
|
|
|
.name = "s0",
|
|
|
|
},
|
2020-09-29 22:27:24 +00:00
|
|
|
[S1] = {
|
|
|
|
.start = 0x0050000,
|
|
|
|
.end = 0x00503ff,
|
|
|
|
.name = "s1",
|
|
|
|
},
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
[S2] = {
|
|
|
|
.start = 0x0060000,
|
|
|
|
.end = 0x00603ff,
|
|
|
|
.name = "s2",
|
|
|
|
},
|
2019-11-20 08:23:17 +00:00
|
|
|
[PTP] = {
|
|
|
|
.start = 0x0090000,
|
|
|
|
.end = 0x00900cb,
|
|
|
|
.name = "ptp",
|
|
|
|
},
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
[GCB] = {
|
|
|
|
.start = 0x0070000,
|
|
|
|
.end = 0x00701ff,
|
|
|
|
.name = "devcpu_gcb",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2020-05-22 08:54:34 +00:00
|
|
|
static const struct resource vsc9959_port_io_res[] = {
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
{
|
|
|
|
.start = 0x0100000,
|
|
|
|
.end = 0x010ffff,
|
|
|
|
.name = "port0",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.start = 0x0110000,
|
|
|
|
.end = 0x011ffff,
|
|
|
|
.name = "port1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.start = 0x0120000,
|
|
|
|
.end = 0x012ffff,
|
|
|
|
.name = "port2",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.start = 0x0130000,
|
|
|
|
.end = 0x013ffff,
|
|
|
|
.name = "port3",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.start = 0x0140000,
|
|
|
|
.end = 0x014ffff,
|
|
|
|
.name = "port4",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.start = 0x0150000,
|
|
|
|
.end = 0x015ffff,
|
|
|
|
.name = "port5",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
/* Port MAC 0 Internal MDIO bus through which the SerDes acting as an
|
|
|
|
* SGMII/QSGMII MAC PCS can be found.
|
|
|
|
*/
|
2020-05-22 08:54:34 +00:00
|
|
|
static const struct resource vsc9959_imdio_res = {
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
.start = 0x8030,
|
|
|
|
.end = 0x8040,
|
|
|
|
.name = "imdio",
|
|
|
|
};
|
|
|
|
|
2020-07-13 16:57:02 +00:00
|
|
|
static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = {
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
[ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 6, 6),
|
|
|
|
[ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 5),
|
|
|
|
[ANA_ANEVENTS_FLOOD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 30, 30),
|
|
|
|
[ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 26, 26),
|
|
|
|
[ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 24, 24),
|
|
|
|
[ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 23, 23),
|
|
|
|
[ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 22, 22),
|
|
|
|
[ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 21, 21),
|
|
|
|
[ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 20, 20),
|
|
|
|
[ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 19, 19),
|
|
|
|
[ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
|
|
|
|
[ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 17, 17),
|
|
|
|
[ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 15, 15),
|
|
|
|
[ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 14, 14),
|
|
|
|
[ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 13, 13),
|
|
|
|
[ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 12, 12),
|
|
|
|
[ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
|
|
|
|
[ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
|
|
|
|
[ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 9, 9),
|
|
|
|
[ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 8, 8),
|
|
|
|
[ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 7, 7),
|
|
|
|
[ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
|
|
|
|
[ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
|
|
|
|
[ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 4, 4),
|
|
|
|
[ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 3, 3),
|
|
|
|
[ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 2, 2),
|
|
|
|
[ANA_ANEVENTS_SEQ_GEN_ERR_0] = REG_FIELD(ANA_ANEVENTS, 1, 1),
|
|
|
|
[ANA_ANEVENTS_SEQ_GEN_ERR_1] = REG_FIELD(ANA_ANEVENTS, 0, 0),
|
|
|
|
[ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 16, 16),
|
|
|
|
[ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 11, 12),
|
|
|
|
[ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 10),
|
|
|
|
[SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 0, 0),
|
|
|
|
[GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 0, 0),
|
net: mscc: ocelot: convert QSYS_SWITCH_PORT_MODE and SYS_PORT_MODE to regfields
Currently Felix and Ocelot share the same bit layout in these per-port
registers, but Seville does not. So we need reg_fields for that.
Actually since these are per-port registers, we need to also specify the
number of ports, and register size per port, and use the regmap API for
multiple ports.
There's a more subtle point to be made about the other 2 register
fields:
- QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG
- QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE
which we are not writing any longer, for 2 reasons:
- Using the previous API (ocelot_write_rix), we were only writing 1 for
Felix and Ocelot, which was their hardware-default value, and which
there wasn't any intention in changing.
- In the case of SCH_NEXT_CFG, in fact Seville does not have this
register field at all, and therefore, if we want to have common code
we would be required to not write to it.
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>
2020-07-13 16:57:03 +00:00
|
|
|
/* Replicated per number of ports (7), register size 4 per port */
|
|
|
|
[QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 14, 14, 7, 4),
|
|
|
|
[QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 11, 13, 7, 4),
|
|
|
|
[QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 7, 4),
|
|
|
|
[QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 7, 4),
|
|
|
|
[QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 7, 4),
|
|
|
|
[QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 7, 4),
|
|
|
|
[SYS_PORT_MODE_DATA_WO_TS] = REG_FIELD_ID(SYS_PORT_MODE, 5, 6, 7, 4),
|
|
|
|
[SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 3, 4, 7, 4),
|
|
|
|
[SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 1, 2, 7, 4),
|
|
|
|
[SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 7, 4),
|
2020-07-13 16:57:07 +00:00
|
|
|
[SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 10, 18, 7, 4),
|
|
|
|
[SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 9, 7, 4),
|
|
|
|
[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 7, 4),
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
|
|
|
|
{ .offset = 0x00, .name = "rx_octets", },
|
|
|
|
{ .offset = 0x01, .name = "rx_unicast", },
|
|
|
|
{ .offset = 0x02, .name = "rx_multicast", },
|
|
|
|
{ .offset = 0x03, .name = "rx_broadcast", },
|
|
|
|
{ .offset = 0x04, .name = "rx_shorts", },
|
|
|
|
{ .offset = 0x05, .name = "rx_fragments", },
|
|
|
|
{ .offset = 0x06, .name = "rx_jabbers", },
|
|
|
|
{ .offset = 0x07, .name = "rx_crc_align_errs", },
|
|
|
|
{ .offset = 0x08, .name = "rx_sym_errs", },
|
|
|
|
{ .offset = 0x09, .name = "rx_frames_below_65_octets", },
|
|
|
|
{ .offset = 0x0A, .name = "rx_frames_65_to_127_octets", },
|
|
|
|
{ .offset = 0x0B, .name = "rx_frames_128_to_255_octets", },
|
|
|
|
{ .offset = 0x0C, .name = "rx_frames_256_to_511_octets", },
|
|
|
|
{ .offset = 0x0D, .name = "rx_frames_512_to_1023_octets", },
|
|
|
|
{ .offset = 0x0E, .name = "rx_frames_1024_to_1526_octets", },
|
|
|
|
{ .offset = 0x0F, .name = "rx_frames_over_1526_octets", },
|
|
|
|
{ .offset = 0x10, .name = "rx_pause", },
|
|
|
|
{ .offset = 0x11, .name = "rx_control", },
|
|
|
|
{ .offset = 0x12, .name = "rx_longs", },
|
|
|
|
{ .offset = 0x13, .name = "rx_classified_drops", },
|
|
|
|
{ .offset = 0x14, .name = "rx_red_prio_0", },
|
|
|
|
{ .offset = 0x15, .name = "rx_red_prio_1", },
|
|
|
|
{ .offset = 0x16, .name = "rx_red_prio_2", },
|
|
|
|
{ .offset = 0x17, .name = "rx_red_prio_3", },
|
|
|
|
{ .offset = 0x18, .name = "rx_red_prio_4", },
|
|
|
|
{ .offset = 0x19, .name = "rx_red_prio_5", },
|
|
|
|
{ .offset = 0x1A, .name = "rx_red_prio_6", },
|
|
|
|
{ .offset = 0x1B, .name = "rx_red_prio_7", },
|
|
|
|
{ .offset = 0x1C, .name = "rx_yellow_prio_0", },
|
|
|
|
{ .offset = 0x1D, .name = "rx_yellow_prio_1", },
|
|
|
|
{ .offset = 0x1E, .name = "rx_yellow_prio_2", },
|
|
|
|
{ .offset = 0x1F, .name = "rx_yellow_prio_3", },
|
|
|
|
{ .offset = 0x20, .name = "rx_yellow_prio_4", },
|
|
|
|
{ .offset = 0x21, .name = "rx_yellow_prio_5", },
|
|
|
|
{ .offset = 0x22, .name = "rx_yellow_prio_6", },
|
|
|
|
{ .offset = 0x23, .name = "rx_yellow_prio_7", },
|
|
|
|
{ .offset = 0x24, .name = "rx_green_prio_0", },
|
|
|
|
{ .offset = 0x25, .name = "rx_green_prio_1", },
|
|
|
|
{ .offset = 0x26, .name = "rx_green_prio_2", },
|
|
|
|
{ .offset = 0x27, .name = "rx_green_prio_3", },
|
|
|
|
{ .offset = 0x28, .name = "rx_green_prio_4", },
|
|
|
|
{ .offset = 0x29, .name = "rx_green_prio_5", },
|
|
|
|
{ .offset = 0x2A, .name = "rx_green_prio_6", },
|
|
|
|
{ .offset = 0x2B, .name = "rx_green_prio_7", },
|
|
|
|
{ .offset = 0x80, .name = "tx_octets", },
|
|
|
|
{ .offset = 0x81, .name = "tx_unicast", },
|
|
|
|
{ .offset = 0x82, .name = "tx_multicast", },
|
|
|
|
{ .offset = 0x83, .name = "tx_broadcast", },
|
|
|
|
{ .offset = 0x84, .name = "tx_collision", },
|
|
|
|
{ .offset = 0x85, .name = "tx_drops", },
|
|
|
|
{ .offset = 0x86, .name = "tx_pause", },
|
|
|
|
{ .offset = 0x87, .name = "tx_frames_below_65_octets", },
|
|
|
|
{ .offset = 0x88, .name = "tx_frames_65_to_127_octets", },
|
|
|
|
{ .offset = 0x89, .name = "tx_frames_128_255_octets", },
|
|
|
|
{ .offset = 0x8B, .name = "tx_frames_256_511_octets", },
|
|
|
|
{ .offset = 0x8C, .name = "tx_frames_1024_1526_octets", },
|
|
|
|
{ .offset = 0x8D, .name = "tx_frames_over_1526_octets", },
|
|
|
|
{ .offset = 0x8E, .name = "tx_yellow_prio_0", },
|
|
|
|
{ .offset = 0x8F, .name = "tx_yellow_prio_1", },
|
|
|
|
{ .offset = 0x90, .name = "tx_yellow_prio_2", },
|
|
|
|
{ .offset = 0x91, .name = "tx_yellow_prio_3", },
|
|
|
|
{ .offset = 0x92, .name = "tx_yellow_prio_4", },
|
|
|
|
{ .offset = 0x93, .name = "tx_yellow_prio_5", },
|
|
|
|
{ .offset = 0x94, .name = "tx_yellow_prio_6", },
|
|
|
|
{ .offset = 0x95, .name = "tx_yellow_prio_7", },
|
|
|
|
{ .offset = 0x96, .name = "tx_green_prio_0", },
|
|
|
|
{ .offset = 0x97, .name = "tx_green_prio_1", },
|
|
|
|
{ .offset = 0x98, .name = "tx_green_prio_2", },
|
|
|
|
{ .offset = 0x99, .name = "tx_green_prio_3", },
|
|
|
|
{ .offset = 0x9A, .name = "tx_green_prio_4", },
|
|
|
|
{ .offset = 0x9B, .name = "tx_green_prio_5", },
|
|
|
|
{ .offset = 0x9C, .name = "tx_green_prio_6", },
|
|
|
|
{ .offset = 0x9D, .name = "tx_green_prio_7", },
|
|
|
|
{ .offset = 0x9E, .name = "tx_aged", },
|
|
|
|
{ .offset = 0x100, .name = "drop_local", },
|
|
|
|
{ .offset = 0x101, .name = "drop_tail", },
|
|
|
|
{ .offset = 0x102, .name = "drop_yellow_prio_0", },
|
|
|
|
{ .offset = 0x103, .name = "drop_yellow_prio_1", },
|
|
|
|
{ .offset = 0x104, .name = "drop_yellow_prio_2", },
|
|
|
|
{ .offset = 0x105, .name = "drop_yellow_prio_3", },
|
|
|
|
{ .offset = 0x106, .name = "drop_yellow_prio_4", },
|
|
|
|
{ .offset = 0x107, .name = "drop_yellow_prio_5", },
|
|
|
|
{ .offset = 0x108, .name = "drop_yellow_prio_6", },
|
|
|
|
{ .offset = 0x109, .name = "drop_yellow_prio_7", },
|
|
|
|
{ .offset = 0x10A, .name = "drop_green_prio_0", },
|
|
|
|
{ .offset = 0x10B, .name = "drop_green_prio_1", },
|
|
|
|
{ .offset = 0x10C, .name = "drop_green_prio_2", },
|
|
|
|
{ .offset = 0x10D, .name = "drop_green_prio_3", },
|
|
|
|
{ .offset = 0x10E, .name = "drop_green_prio_4", },
|
|
|
|
{ .offset = 0x10F, .name = "drop_green_prio_5", },
|
|
|
|
{ .offset = 0x110, .name = "drop_green_prio_6", },
|
|
|
|
{ .offset = 0x111, .name = "drop_green_prio_7", },
|
|
|
|
};
|
|
|
|
|
2020-09-29 22:27:25 +00:00
|
|
|
static const struct vcap_field vsc9959_vcap_es0_keys[] = {
|
|
|
|
[VCAP_ES0_EGR_PORT] = { 0, 3},
|
|
|
|
[VCAP_ES0_IGR_PORT] = { 3, 3},
|
|
|
|
[VCAP_ES0_RSV] = { 6, 2},
|
|
|
|
[VCAP_ES0_L2_MC] = { 8, 1},
|
|
|
|
[VCAP_ES0_L2_BC] = { 9, 1},
|
|
|
|
[VCAP_ES0_VID] = { 10, 12},
|
|
|
|
[VCAP_ES0_DP] = { 22, 1},
|
|
|
|
[VCAP_ES0_PCP] = { 23, 3},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct vcap_field vsc9959_vcap_es0_actions[] = {
|
|
|
|
[VCAP_ES0_ACT_PUSH_OUTER_TAG] = { 0, 2},
|
|
|
|
[VCAP_ES0_ACT_PUSH_INNER_TAG] = { 2, 1},
|
|
|
|
[VCAP_ES0_ACT_TAG_A_TPID_SEL] = { 3, 2},
|
|
|
|
[VCAP_ES0_ACT_TAG_A_VID_SEL] = { 5, 1},
|
|
|
|
[VCAP_ES0_ACT_TAG_A_PCP_SEL] = { 6, 2},
|
|
|
|
[VCAP_ES0_ACT_TAG_A_DEI_SEL] = { 8, 2},
|
|
|
|
[VCAP_ES0_ACT_TAG_B_TPID_SEL] = { 10, 2},
|
|
|
|
[VCAP_ES0_ACT_TAG_B_VID_SEL] = { 12, 1},
|
|
|
|
[VCAP_ES0_ACT_TAG_B_PCP_SEL] = { 13, 2},
|
|
|
|
[VCAP_ES0_ACT_TAG_B_DEI_SEL] = { 15, 2},
|
|
|
|
[VCAP_ES0_ACT_VID_A_VAL] = { 17, 12},
|
|
|
|
[VCAP_ES0_ACT_PCP_A_VAL] = { 29, 3},
|
|
|
|
[VCAP_ES0_ACT_DEI_A_VAL] = { 32, 1},
|
|
|
|
[VCAP_ES0_ACT_VID_B_VAL] = { 33, 12},
|
|
|
|
[VCAP_ES0_ACT_PCP_B_VAL] = { 45, 3},
|
|
|
|
[VCAP_ES0_ACT_DEI_B_VAL] = { 48, 1},
|
|
|
|
[VCAP_ES0_ACT_RSV] = { 49, 23},
|
|
|
|
[VCAP_ES0_ACT_HIT_STICKY] = { 72, 1},
|
|
|
|
};
|
|
|
|
|
2020-09-29 22:27:24 +00:00
|
|
|
static const struct vcap_field vsc9959_vcap_is1_keys[] = {
|
|
|
|
[VCAP_IS1_HK_TYPE] = { 0, 1},
|
|
|
|
[VCAP_IS1_HK_LOOKUP] = { 1, 2},
|
|
|
|
[VCAP_IS1_HK_IGR_PORT_MASK] = { 3, 7},
|
|
|
|
[VCAP_IS1_HK_RSV] = { 10, 9},
|
|
|
|
[VCAP_IS1_HK_OAM_Y1731] = { 19, 1},
|
|
|
|
[VCAP_IS1_HK_L2_MC] = { 20, 1},
|
|
|
|
[VCAP_IS1_HK_L2_BC] = { 21, 1},
|
|
|
|
[VCAP_IS1_HK_IP_MC] = { 22, 1},
|
|
|
|
[VCAP_IS1_HK_VLAN_TAGGED] = { 23, 1},
|
|
|
|
[VCAP_IS1_HK_VLAN_DBL_TAGGED] = { 24, 1},
|
|
|
|
[VCAP_IS1_HK_TPID] = { 25, 1},
|
|
|
|
[VCAP_IS1_HK_VID] = { 26, 12},
|
|
|
|
[VCAP_IS1_HK_DEI] = { 38, 1},
|
|
|
|
[VCAP_IS1_HK_PCP] = { 39, 3},
|
|
|
|
/* Specific Fields for IS1 Half Key S1_NORMAL */
|
|
|
|
[VCAP_IS1_HK_L2_SMAC] = { 42, 48},
|
|
|
|
[VCAP_IS1_HK_ETYPE_LEN] = { 90, 1},
|
|
|
|
[VCAP_IS1_HK_ETYPE] = { 91, 16},
|
|
|
|
[VCAP_IS1_HK_IP_SNAP] = {107, 1},
|
|
|
|
[VCAP_IS1_HK_IP4] = {108, 1},
|
|
|
|
/* Layer-3 Information */
|
|
|
|
[VCAP_IS1_HK_L3_FRAGMENT] = {109, 1},
|
|
|
|
[VCAP_IS1_HK_L3_FRAG_OFS_GT0] = {110, 1},
|
|
|
|
[VCAP_IS1_HK_L3_OPTIONS] = {111, 1},
|
|
|
|
[VCAP_IS1_HK_L3_DSCP] = {112, 6},
|
|
|
|
[VCAP_IS1_HK_L3_IP4_SIP] = {118, 32},
|
|
|
|
/* Layer-4 Information */
|
|
|
|
[VCAP_IS1_HK_TCP_UDP] = {150, 1},
|
|
|
|
[VCAP_IS1_HK_TCP] = {151, 1},
|
|
|
|
[VCAP_IS1_HK_L4_SPORT] = {152, 16},
|
|
|
|
[VCAP_IS1_HK_L4_RNG] = {168, 8},
|
|
|
|
/* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */
|
|
|
|
[VCAP_IS1_HK_IP4_INNER_TPID] = { 42, 1},
|
|
|
|
[VCAP_IS1_HK_IP4_INNER_VID] = { 43, 12},
|
|
|
|
[VCAP_IS1_HK_IP4_INNER_DEI] = { 55, 1},
|
|
|
|
[VCAP_IS1_HK_IP4_INNER_PCP] = { 56, 3},
|
|
|
|
[VCAP_IS1_HK_IP4_IP4] = { 59, 1},
|
|
|
|
[VCAP_IS1_HK_IP4_L3_FRAGMENT] = { 60, 1},
|
|
|
|
[VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0] = { 61, 1},
|
|
|
|
[VCAP_IS1_HK_IP4_L3_OPTIONS] = { 62, 1},
|
|
|
|
[VCAP_IS1_HK_IP4_L3_DSCP] = { 63, 6},
|
|
|
|
[VCAP_IS1_HK_IP4_L3_IP4_DIP] = { 69, 32},
|
|
|
|
[VCAP_IS1_HK_IP4_L3_IP4_SIP] = {101, 32},
|
|
|
|
[VCAP_IS1_HK_IP4_L3_PROTO] = {133, 8},
|
|
|
|
[VCAP_IS1_HK_IP4_TCP_UDP] = {141, 1},
|
|
|
|
[VCAP_IS1_HK_IP4_TCP] = {142, 1},
|
|
|
|
[VCAP_IS1_HK_IP4_L4_RNG] = {143, 8},
|
|
|
|
[VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE] = {151, 32},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct vcap_field vsc9959_vcap_is1_actions[] = {
|
|
|
|
[VCAP_IS1_ACT_DSCP_ENA] = { 0, 1},
|
|
|
|
[VCAP_IS1_ACT_DSCP_VAL] = { 1, 6},
|
|
|
|
[VCAP_IS1_ACT_QOS_ENA] = { 7, 1},
|
|
|
|
[VCAP_IS1_ACT_QOS_VAL] = { 8, 3},
|
|
|
|
[VCAP_IS1_ACT_DP_ENA] = { 11, 1},
|
|
|
|
[VCAP_IS1_ACT_DP_VAL] = { 12, 1},
|
|
|
|
[VCAP_IS1_ACT_PAG_OVERRIDE_MASK] = { 13, 8},
|
|
|
|
[VCAP_IS1_ACT_PAG_VAL] = { 21, 8},
|
|
|
|
[VCAP_IS1_ACT_RSV] = { 29, 9},
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 12:02:23 +00:00
|
|
|
/* The fields below are incorrectly shifted by 2 in the manual */
|
2020-09-29 22:27:24 +00:00
|
|
|
[VCAP_IS1_ACT_VID_REPLACE_ENA] = { 38, 1},
|
|
|
|
[VCAP_IS1_ACT_VID_ADD_VAL] = { 39, 12},
|
|
|
|
[VCAP_IS1_ACT_FID_SEL] = { 51, 2},
|
|
|
|
[VCAP_IS1_ACT_FID_VAL] = { 53, 13},
|
|
|
|
[VCAP_IS1_ACT_PCP_DEI_ENA] = { 66, 1},
|
|
|
|
[VCAP_IS1_ACT_PCP_VAL] = { 67, 3},
|
|
|
|
[VCAP_IS1_ACT_DEI_VAL] = { 70, 1},
|
|
|
|
[VCAP_IS1_ACT_VLAN_POP_CNT_ENA] = { 71, 1},
|
|
|
|
[VCAP_IS1_ACT_VLAN_POP_CNT] = { 72, 2},
|
|
|
|
[VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA] = { 74, 4},
|
|
|
|
[VCAP_IS1_ACT_HIT_STICKY] = { 78, 1},
|
|
|
|
};
|
|
|
|
|
2020-06-20 15:43:36 +00:00
|
|
|
static struct vcap_field vsc9959_vcap_is2_keys[] = {
|
2020-02-29 14:31:14 +00:00
|
|
|
/* Common: 41 bits */
|
|
|
|
[VCAP_IS2_TYPE] = { 0, 4},
|
|
|
|
[VCAP_IS2_HK_FIRST] = { 4, 1},
|
|
|
|
[VCAP_IS2_HK_PAG] = { 5, 8},
|
|
|
|
[VCAP_IS2_HK_IGR_PORT_MASK] = { 13, 7},
|
|
|
|
[VCAP_IS2_HK_RSV2] = { 20, 1},
|
|
|
|
[VCAP_IS2_HK_HOST_MATCH] = { 21, 1},
|
|
|
|
[VCAP_IS2_HK_L2_MC] = { 22, 1},
|
|
|
|
[VCAP_IS2_HK_L2_BC] = { 23, 1},
|
|
|
|
[VCAP_IS2_HK_VLAN_TAGGED] = { 24, 1},
|
|
|
|
[VCAP_IS2_HK_VID] = { 25, 12},
|
|
|
|
[VCAP_IS2_HK_DEI] = { 37, 1},
|
|
|
|
[VCAP_IS2_HK_PCP] = { 38, 3},
|
|
|
|
/* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
|
|
|
|
[VCAP_IS2_HK_L2_DMAC] = { 41, 48},
|
|
|
|
[VCAP_IS2_HK_L2_SMAC] = { 89, 48},
|
|
|
|
/* MAC_ETYPE (TYPE=000) */
|
|
|
|
[VCAP_IS2_HK_MAC_ETYPE_ETYPE] = {137, 16},
|
|
|
|
[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0] = {153, 16},
|
|
|
|
[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1] = {169, 8},
|
|
|
|
[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2] = {177, 3},
|
|
|
|
/* MAC_LLC (TYPE=001) */
|
|
|
|
[VCAP_IS2_HK_MAC_LLC_L2_LLC] = {137, 40},
|
|
|
|
/* MAC_SNAP (TYPE=010) */
|
|
|
|
[VCAP_IS2_HK_MAC_SNAP_L2_SNAP] = {137, 40},
|
|
|
|
/* MAC_ARP (TYPE=011) */
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_SMAC] = { 41, 48},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK] = { 89, 1},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK] = { 90, 1},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_LEN_OK] = { 91, 1},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_TARGET_MATCH] = { 92, 1},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_SENDER_MATCH] = { 93, 1},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN] = { 94, 1},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_OPCODE] = { 95, 2},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP] = { 97, 32},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP] = {129, 32},
|
|
|
|
[VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP] = {161, 1},
|
|
|
|
/* IP4_TCP_UDP / IP4_OTHER common */
|
|
|
|
[VCAP_IS2_HK_IP4] = { 41, 1},
|
|
|
|
[VCAP_IS2_HK_L3_FRAGMENT] = { 42, 1},
|
|
|
|
[VCAP_IS2_HK_L3_FRAG_OFS_GT0] = { 43, 1},
|
|
|
|
[VCAP_IS2_HK_L3_OPTIONS] = { 44, 1},
|
|
|
|
[VCAP_IS2_HK_IP4_L3_TTL_GT0] = { 45, 1},
|
|
|
|
[VCAP_IS2_HK_L3_TOS] = { 46, 8},
|
|
|
|
[VCAP_IS2_HK_L3_IP4_DIP] = { 54, 32},
|
|
|
|
[VCAP_IS2_HK_L3_IP4_SIP] = { 86, 32},
|
|
|
|
[VCAP_IS2_HK_DIP_EQ_SIP] = {118, 1},
|
|
|
|
/* IP4_TCP_UDP (TYPE=100) */
|
|
|
|
[VCAP_IS2_HK_TCP] = {119, 1},
|
2020-09-21 22:56:36 +00:00
|
|
|
[VCAP_IS2_HK_L4_DPORT] = {120, 16},
|
|
|
|
[VCAP_IS2_HK_L4_SPORT] = {136, 16},
|
2020-02-29 14:31:14 +00:00
|
|
|
[VCAP_IS2_HK_L4_RNG] = {152, 8},
|
|
|
|
[VCAP_IS2_HK_L4_SPORT_EQ_DPORT] = {160, 1},
|
|
|
|
[VCAP_IS2_HK_L4_SEQUENCE_EQ0] = {161, 1},
|
2020-09-21 22:56:36 +00:00
|
|
|
[VCAP_IS2_HK_L4_FIN] = {162, 1},
|
|
|
|
[VCAP_IS2_HK_L4_SYN] = {163, 1},
|
|
|
|
[VCAP_IS2_HK_L4_RST] = {164, 1},
|
|
|
|
[VCAP_IS2_HK_L4_PSH] = {165, 1},
|
|
|
|
[VCAP_IS2_HK_L4_ACK] = {166, 1},
|
|
|
|
[VCAP_IS2_HK_L4_URG] = {167, 1},
|
2020-02-29 14:31:14 +00:00
|
|
|
[VCAP_IS2_HK_L4_1588_DOM] = {168, 8},
|
|
|
|
[VCAP_IS2_HK_L4_1588_VER] = {176, 4},
|
|
|
|
/* IP4_OTHER (TYPE=101) */
|
|
|
|
[VCAP_IS2_HK_IP4_L3_PROTO] = {119, 8},
|
|
|
|
[VCAP_IS2_HK_L3_PAYLOAD] = {127, 56},
|
|
|
|
/* IP6_STD (TYPE=110) */
|
|
|
|
[VCAP_IS2_HK_IP6_L3_TTL_GT0] = { 41, 1},
|
|
|
|
[VCAP_IS2_HK_L3_IP6_SIP] = { 42, 128},
|
|
|
|
[VCAP_IS2_HK_IP6_L3_PROTO] = {170, 8},
|
|
|
|
/* OAM (TYPE=111) */
|
|
|
|
[VCAP_IS2_HK_OAM_MEL_FLAGS] = {137, 7},
|
|
|
|
[VCAP_IS2_HK_OAM_VER] = {144, 5},
|
|
|
|
[VCAP_IS2_HK_OAM_OPCODE] = {149, 8},
|
|
|
|
[VCAP_IS2_HK_OAM_FLAGS] = {157, 8},
|
|
|
|
[VCAP_IS2_HK_OAM_MEPID] = {165, 16},
|
|
|
|
[VCAP_IS2_HK_OAM_CCM_CNTS_EQ0] = {181, 1},
|
|
|
|
[VCAP_IS2_HK_OAM_IS_Y1731] = {182, 1},
|
|
|
|
};
|
|
|
|
|
2020-06-20 15:43:36 +00:00
|
|
|
static struct vcap_field vsc9959_vcap_is2_actions[] = {
|
2020-02-29 14:31:14 +00:00
|
|
|
[VCAP_IS2_ACT_HIT_ME_ONCE] = { 0, 1},
|
|
|
|
[VCAP_IS2_ACT_CPU_COPY_ENA] = { 1, 1},
|
|
|
|
[VCAP_IS2_ACT_CPU_QU_NUM] = { 2, 3},
|
|
|
|
[VCAP_IS2_ACT_MASK_MODE] = { 5, 2},
|
|
|
|
[VCAP_IS2_ACT_MIRROR_ENA] = { 7, 1},
|
|
|
|
[VCAP_IS2_ACT_LRN_DIS] = { 8, 1},
|
|
|
|
[VCAP_IS2_ACT_POLICE_ENA] = { 9, 1},
|
|
|
|
[VCAP_IS2_ACT_POLICE_IDX] = { 10, 9},
|
|
|
|
[VCAP_IS2_ACT_POLICE_VCAP_ONLY] = { 19, 1},
|
2020-09-29 11:20:24 +00:00
|
|
|
[VCAP_IS2_ACT_PORT_MASK] = { 20, 6},
|
|
|
|
[VCAP_IS2_ACT_REW_OP] = { 26, 9},
|
|
|
|
[VCAP_IS2_ACT_SMAC_REPLACE_ENA] = { 35, 1},
|
|
|
|
[VCAP_IS2_ACT_RSV] = { 36, 2},
|
|
|
|
[VCAP_IS2_ACT_ACL_ID] = { 38, 6},
|
|
|
|
[VCAP_IS2_ACT_HIT_CNT] = { 44, 32},
|
2020-02-29 14:31:14 +00:00
|
|
|
};
|
|
|
|
|
2020-09-29 22:27:26 +00:00
|
|
|
static struct vcap_props vsc9959_vcap_props[] = {
|
2020-09-29 22:27:25 +00:00
|
|
|
[VCAP_ES0] = {
|
|
|
|
.action_type_width = 0,
|
|
|
|
.action_table = {
|
|
|
|
[ES0_ACTION_TYPE_NORMAL] = {
|
|
|
|
.width = 72, /* HIT_STICKY not included */
|
|
|
|
.count = 1,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
.target = S0,
|
|
|
|
.keys = vsc9959_vcap_es0_keys,
|
|
|
|
.actions = vsc9959_vcap_es0_actions,
|
|
|
|
},
|
2020-09-29 22:27:24 +00:00
|
|
|
[VCAP_IS1] = {
|
|
|
|
.action_type_width = 0,
|
|
|
|
.action_table = {
|
|
|
|
[IS1_ACTION_TYPE_NORMAL] = {
|
|
|
|
.width = 78, /* HIT_STICKY not included */
|
|
|
|
.count = 4,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
.target = S1,
|
|
|
|
.keys = vsc9959_vcap_is1_keys,
|
|
|
|
.actions = vsc9959_vcap_is1_actions,
|
|
|
|
},
|
2020-02-29 14:31:14 +00:00
|
|
|
[VCAP_IS2] = {
|
|
|
|
.action_type_width = 1,
|
|
|
|
.action_table = {
|
|
|
|
[IS2_ACTION_TYPE_NORMAL] = {
|
|
|
|
.width = 44,
|
|
|
|
.count = 2
|
|
|
|
},
|
|
|
|
[IS2_ACTION_TYPE_SMAC_SIP] = {
|
|
|
|
.width = 6,
|
|
|
|
.count = 4
|
|
|
|
},
|
|
|
|
},
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-29 22:27:23 +00:00
|
|
|
.target = S2,
|
|
|
|
.keys = vsc9959_vcap_is2_keys,
|
|
|
|
.actions = vsc9959_vcap_is2_actions,
|
2020-02-29 14:31:14 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2020-09-18 10:57:52 +00:00
|
|
|
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,
|
|
|
|
};
|
|
|
|
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
#define VSC9959_INIT_TIMEOUT 50000
|
|
|
|
#define VSC9959_GCB_RST_SLEEP 100
|
|
|
|
#define VSC9959_SYS_RAMINIT_SLEEP 80
|
|
|
|
|
|
|
|
static int vsc9959_gcb_soft_rst_status(struct ocelot *ocelot)
|
|
|
|
{
|
|
|
|
int val;
|
|
|
|
|
2020-09-18 10:57:43 +00:00
|
|
|
ocelot_field_read(ocelot, GCB_SOFT_RST_SWC_RST, &val);
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vsc9959_sys_ram_init_status(struct ocelot *ocelot)
|
|
|
|
{
|
|
|
|
return ocelot_read(ocelot, SYS_RAM_INIT);
|
|
|
|
}
|
|
|
|
|
2020-09-18 10:57:46 +00:00
|
|
|
/* CORE_ENA is in SYS:SYSTEM:RESET_CFG
|
|
|
|
* RAM_INIT is in SYS:RAM_CTRL:RAM_INIT
|
|
|
|
*/
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
static int vsc9959_reset(struct ocelot *ocelot)
|
|
|
|
{
|
|
|
|
int val, err;
|
|
|
|
|
|
|
|
/* soft-reset the switch core */
|
2020-09-18 10:57:43 +00:00
|
|
|
ocelot_field_write(ocelot, GCB_SOFT_RST_SWC_RST, 1);
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
|
|
|
|
err = readx_poll_timeout(vsc9959_gcb_soft_rst_status, ocelot, val, !val,
|
|
|
|
VSC9959_GCB_RST_SLEEP, VSC9959_INIT_TIMEOUT);
|
|
|
|
if (err) {
|
|
|
|
dev_err(ocelot->dev, "timeout: switch core reset\n");
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize switch mem ~40us */
|
|
|
|
ocelot_write(ocelot, SYS_RAM_INIT_RAM_INIT, SYS_RAM_INIT);
|
|
|
|
err = readx_poll_timeout(vsc9959_sys_ram_init_status, ocelot, val, !val,
|
|
|
|
VSC9959_SYS_RAMINIT_SLEEP,
|
|
|
|
VSC9959_INIT_TIMEOUT);
|
|
|
|
if (err) {
|
|
|
|
dev_err(ocelot->dev, "timeout: switch sram init\n");
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* enable switch core */
|
2020-09-18 10:57:43 +00:00
|
|
|
ocelot_field_write(ocelot, SYS_RESET_CFG_CORE_ENA, 1);
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-07-13 16:57:09 +00:00
|
|
|
static void vsc9959_phylink_validate(struct ocelot *ocelot, int port,
|
|
|
|
unsigned long *supported,
|
|
|
|
struct phylink_link_state *state)
|
|
|
|
{
|
|
|
|
struct ocelot_port *ocelot_port = ocelot->ports[port];
|
|
|
|
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
|
|
|
|
|
|
|
if (state->interface != PHY_INTERFACE_MODE_NA &&
|
|
|
|
state->interface != ocelot_port->phy_mode) {
|
|
|
|
bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
phylink_set_port_modes(mask);
|
|
|
|
phylink_set(mask, Autoneg);
|
|
|
|
phylink_set(mask, Pause);
|
|
|
|
phylink_set(mask, Asym_Pause);
|
|
|
|
phylink_set(mask, 10baseT_Half);
|
|
|
|
phylink_set(mask, 10baseT_Full);
|
|
|
|
phylink_set(mask, 100baseT_Half);
|
|
|
|
phylink_set(mask, 100baseT_Full);
|
|
|
|
phylink_set(mask, 1000baseT_Half);
|
|
|
|
phylink_set(mask, 1000baseT_Full);
|
|
|
|
|
|
|
|
if (state->interface == PHY_INTERFACE_MODE_INTERNAL ||
|
|
|
|
state->interface == PHY_INTERFACE_MODE_2500BASEX ||
|
|
|
|
state->interface == PHY_INTERFACE_MODE_USXGMII) {
|
|
|
|
phylink_set(mask, 2500baseT_Full);
|
|
|
|
phylink_set(mask, 2500baseX_Full);
|
|
|
|
}
|
|
|
|
|
|
|
|
bitmap_and(supported, supported, mask,
|
|
|
|
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
|
|
|
bitmap_and(state->advertising, state->advertising, mask,
|
|
|
|
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
|
|
|
}
|
|
|
|
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port,
|
|
|
|
phy_interface_t phy_mode)
|
|
|
|
{
|
|
|
|
switch (phy_mode) {
|
2020-02-24 12:15:33 +00:00
|
|
|
case PHY_INTERFACE_MODE_INTERNAL:
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
if (port != 4 && port != 5)
|
|
|
|
return -ENOTSUPP;
|
|
|
|
return 0;
|
|
|
|
case PHY_INTERFACE_MODE_SGMII:
|
|
|
|
case PHY_INTERFACE_MODE_QSGMII:
|
|
|
|
case PHY_INTERFACE_MODE_USXGMII:
|
|
|
|
case PHY_INTERFACE_MODE_2500BASEX:
|
|
|
|
/* Not supported on internal to-CPU ports */
|
|
|
|
if (port == 4 || port == 5)
|
|
|
|
return -ENOTSUPP;
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
return -ENOTSUPP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-13 16:57:08 +00:00
|
|
|
/* Watermark encode
|
|
|
|
* Bit 8: Unit; 0:1, 1:16
|
|
|
|
* Bit 7-0: Value to be multiplied with unit
|
|
|
|
*/
|
|
|
|
static u16 vsc9959_wm_enc(u16 value)
|
|
|
|
{
|
2020-10-05 09:09:12 +00:00
|
|
|
WARN_ON(value >= 16 * BIT(8));
|
|
|
|
|
2020-07-13 16:57:08 +00:00
|
|
|
if (value >= BIT(8))
|
|
|
|
return BIT(8) | (value / 16);
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2021-01-15 02:11:12 +00:00
|
|
|
static u16 vsc9959_wm_dec(u16 wm)
|
|
|
|
{
|
|
|
|
WARN_ON(wm & ~GENMASK(8, 0));
|
|
|
|
|
|
|
|
if (wm & BIT(8))
|
|
|
|
return (wm & GENMASK(7, 0)) * 16;
|
|
|
|
|
|
|
|
return wm;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vsc9959_wm_stat(u32 val, u32 *inuse, u32 *maxuse)
|
|
|
|
{
|
|
|
|
*inuse = (val & GENMASK(23, 12)) >> 12;
|
|
|
|
*maxuse = val & GENMASK(11, 0);
|
|
|
|
}
|
|
|
|
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
static const struct ocelot_ops vsc9959_ops = {
|
|
|
|
.reset = vsc9959_reset,
|
2020-07-13 16:57:08 +00:00
|
|
|
.wm_enc = vsc9959_wm_enc,
|
2021-01-15 02:11:12 +00:00
|
|
|
.wm_dec = vsc9959_wm_dec,
|
|
|
|
.wm_stat = vsc9959_wm_stat,
|
2020-10-02 12:02:21 +00:00
|
|
|
.port_to_netdev = felix_port_to_netdev,
|
|
|
|
.netdev_to_port = felix_netdev_to_port,
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
};
|
|
|
|
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
|
|
|
|
{
|
|
|
|
struct felix *felix = ocelot_to_felix(ocelot);
|
|
|
|
struct enetc_mdio_priv *mdio_priv;
|
|
|
|
struct device *dev = ocelot->dev;
|
|
|
|
void __iomem *imdio_regs;
|
2020-05-22 08:54:34 +00:00
|
|
|
struct resource res;
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
struct enetc_hw *hw;
|
|
|
|
struct mii_bus *bus;
|
|
|
|
int port;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
felix->pcs = devm_kcalloc(dev, felix->info->num_ports,
|
2020-08-30 08:34:02 +00:00
|
|
|
sizeof(struct lynx_pcs *),
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
GFP_KERNEL);
|
|
|
|
if (!felix->pcs) {
|
|
|
|
dev_err(dev, "failed to allocate array for PCS PHYs\n");
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2020-05-22 08:54:34 +00:00
|
|
|
memcpy(&res, felix->info->imdio_res, sizeof(res));
|
|
|
|
res.flags = IORESOURCE_MEM;
|
2020-07-13 16:57:09 +00:00
|
|
|
res.start += felix->imdio_base;
|
|
|
|
res.end += felix->imdio_base;
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
|
2020-05-22 08:54:34 +00:00
|
|
|
imdio_regs = devm_ioremap_resource(dev, &res);
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
if (IS_ERR(imdio_regs)) {
|
|
|
|
dev_err(dev, "failed to map internal MDIO registers\n");
|
|
|
|
return PTR_ERR(imdio_regs);
|
|
|
|
}
|
|
|
|
|
|
|
|
hw = enetc_hw_alloc(dev, imdio_regs);
|
|
|
|
if (IS_ERR(hw)) {
|
|
|
|
dev_err(dev, "failed to allocate ENETC HW structure\n");
|
|
|
|
return PTR_ERR(hw);
|
|
|
|
}
|
|
|
|
|
|
|
|
bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
|
|
|
|
if (!bus)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
bus->name = "VSC9959 internal MDIO bus";
|
|
|
|
bus->read = enetc_mdio_read;
|
|
|
|
bus->write = enetc_mdio_write;
|
|
|
|
bus->parent = dev;
|
|
|
|
mdio_priv = bus->priv;
|
|
|
|
mdio_priv->hw = hw;
|
|
|
|
/* This gets added to imdio_regs, which already maps addresses
|
|
|
|
* starting with the proper offset.
|
|
|
|
*/
|
|
|
|
mdio_priv->mdio_base = 0;
|
|
|
|
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev));
|
|
|
|
|
|
|
|
/* Needed in order to initialize the bus mutex lock */
|
|
|
|
rc = mdiobus_register(bus);
|
|
|
|
if (rc < 0) {
|
|
|
|
dev_err(dev, "failed to register MDIO bus\n");
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
felix->imdio = bus;
|
|
|
|
|
|
|
|
for (port = 0; port < felix->info->num_ports; port++) {
|
|
|
|
struct ocelot_port *ocelot_port = ocelot->ports[port];
|
2020-08-30 08:34:02 +00:00
|
|
|
struct mdio_device *pcs;
|
|
|
|
struct lynx_pcs *lynx;
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
|
2020-08-30 08:34:02 +00:00
|
|
|
if (dsa_is_unused_port(felix->ds, port))
|
|
|
|
continue;
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
|
2020-08-30 08:34:02 +00:00
|
|
|
if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_INTERNAL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
pcs = mdio_device_create(felix->imdio, port);
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
if (IS_ERR(pcs))
|
|
|
|
continue;
|
|
|
|
|
2020-08-30 08:34:02 +00:00
|
|
|
lynx = lynx_pcs_create(pcs);
|
|
|
|
if (!lynx) {
|
|
|
|
mdio_device_free(pcs);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
felix->pcs[port] = lynx;
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
|
|
|
|
dev_info(dev, "Found PCS at internal MDIO address %d\n", port);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-09-18 10:57:50 +00:00
|
|
|
static void vsc9959_mdio_bus_free(struct ocelot *ocelot)
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
{
|
|
|
|
struct felix *felix = ocelot_to_felix(ocelot);
|
|
|
|
int port;
|
|
|
|
|
|
|
|
for (port = 0; port < ocelot->num_phys_ports; port++) {
|
2020-08-30 08:34:02 +00:00
|
|
|
struct lynx_pcs *pcs = felix->pcs[port];
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
|
|
|
|
if (!pcs)
|
|
|
|
continue;
|
|
|
|
|
2020-08-30 08:34:02 +00:00
|
|
|
mdio_device_free(pcs->mdio);
|
|
|
|
lynx_pcs_destroy(pcs);
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
}
|
|
|
|
mdiobus_unregister(felix->imdio);
|
|
|
|
}
|
|
|
|
|
2020-05-13 02:25:09 +00:00
|
|
|
static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port,
|
|
|
|
u32 speed)
|
|
|
|
{
|
2020-09-24 01:57:46 +00:00
|
|
|
u8 tas_speed;
|
|
|
|
|
|
|
|
switch (speed) {
|
|
|
|
case SPEED_10:
|
|
|
|
tas_speed = OCELOT_SPEED_10;
|
|
|
|
break;
|
|
|
|
case SPEED_100:
|
|
|
|
tas_speed = OCELOT_SPEED_100;
|
|
|
|
break;
|
|
|
|
case SPEED_1000:
|
|
|
|
tas_speed = OCELOT_SPEED_1000;
|
|
|
|
break;
|
|
|
|
case SPEED_2500:
|
|
|
|
tas_speed = OCELOT_SPEED_2500;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
tas_speed = OCELOT_SPEED_1000;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-05-13 02:25:09 +00:00
|
|
|
ocelot_rmw_rix(ocelot,
|
2020-09-24 01:57:46 +00:00
|
|
|
QSYS_TAG_CONFIG_LINK_SPEED(tas_speed),
|
2020-05-13 02:25:09 +00:00
|
|
|
QSYS_TAG_CONFIG_LINK_SPEED_M,
|
|
|
|
QSYS_TAG_CONFIG, port);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vsc9959_new_base_time(struct ocelot *ocelot, ktime_t base_time,
|
|
|
|
u64 cycle_time,
|
|
|
|
struct timespec64 *new_base_ts)
|
|
|
|
{
|
|
|
|
struct timespec64 ts;
|
|
|
|
ktime_t new_base_time;
|
|
|
|
ktime_t current_time;
|
|
|
|
|
|
|
|
ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
|
|
|
|
current_time = timespec64_to_ktime(ts);
|
|
|
|
new_base_time = base_time;
|
|
|
|
|
|
|
|
if (base_time < current_time) {
|
|
|
|
u64 nr_of_cycles = current_time - base_time;
|
|
|
|
|
|
|
|
do_div(nr_of_cycles, cycle_time);
|
|
|
|
new_base_time += cycle_time * (nr_of_cycles + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
*new_base_ts = ktime_to_timespec64(new_base_time);
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 vsc9959_tas_read_cfg_status(struct ocelot *ocelot)
|
|
|
|
{
|
|
|
|
return ocelot_read(ocelot, QSYS_TAS_PARAM_CFG_CTRL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vsc9959_tas_gcl_set(struct ocelot *ocelot, const u32 gcl_ix,
|
|
|
|
struct tc_taprio_sched_entry *entry)
|
|
|
|
{
|
|
|
|
ocelot_write(ocelot,
|
|
|
|
QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM(gcl_ix) |
|
|
|
|
QSYS_GCL_CFG_REG_1_GATE_STATE(entry->gate_mask),
|
|
|
|
QSYS_GCL_CFG_REG_1);
|
|
|
|
ocelot_write(ocelot, entry->interval, QSYS_GCL_CFG_REG_2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
|
|
|
|
struct tc_taprio_qopt_offload *taprio)
|
|
|
|
{
|
|
|
|
struct timespec64 base_ts;
|
|
|
|
int ret, i;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
if (!taprio->enable) {
|
|
|
|
ocelot_rmw_rix(ocelot,
|
|
|
|
QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF),
|
|
|
|
QSYS_TAG_CONFIG_ENABLE |
|
|
|
|
QSYS_TAG_CONFIG_INIT_GATE_STATE_M,
|
|
|
|
QSYS_TAG_CONFIG, port);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (taprio->cycle_time > NSEC_PER_SEC ||
|
|
|
|
taprio->cycle_time_extension >= NSEC_PER_SEC)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (taprio->num_entries > VSC9959_TAS_GCL_ENTRY_MAX)
|
|
|
|
return -ERANGE;
|
|
|
|
|
|
|
|
ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port) |
|
|
|
|
QSYS_TAS_PARAM_CFG_CTRL_ALWAYS_GUARD_BAND_SCH_Q,
|
|
|
|
QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M |
|
|
|
|
QSYS_TAS_PARAM_CFG_CTRL_ALWAYS_GUARD_BAND_SCH_Q,
|
|
|
|
QSYS_TAS_PARAM_CFG_CTRL);
|
|
|
|
|
|
|
|
/* Hardware errata - Admin config could not be overwritten if
|
|
|
|
* config is pending, need reset the TAS module
|
|
|
|
*/
|
|
|
|
val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8);
|
|
|
|
if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING)
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
ocelot_rmw_rix(ocelot,
|
|
|
|
QSYS_TAG_CONFIG_ENABLE |
|
|
|
|
QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF) |
|
|
|
|
QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES(0xFF),
|
|
|
|
QSYS_TAG_CONFIG_ENABLE |
|
|
|
|
QSYS_TAG_CONFIG_INIT_GATE_STATE_M |
|
|
|
|
QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M,
|
|
|
|
QSYS_TAG_CONFIG, port);
|
|
|
|
|
|
|
|
vsc9959_new_base_time(ocelot, taprio->base_time,
|
|
|
|
taprio->cycle_time, &base_ts);
|
|
|
|
ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1);
|
|
|
|
ocelot_write(ocelot, lower_32_bits(base_ts.tv_sec), QSYS_PARAM_CFG_REG_2);
|
|
|
|
val = upper_32_bits(base_ts.tv_sec);
|
|
|
|
ocelot_write(ocelot,
|
|
|
|
QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(val) |
|
|
|
|
QSYS_PARAM_CFG_REG_3_LIST_LENGTH(taprio->num_entries),
|
|
|
|
QSYS_PARAM_CFG_REG_3);
|
|
|
|
ocelot_write(ocelot, taprio->cycle_time, QSYS_PARAM_CFG_REG_4);
|
|
|
|
ocelot_write(ocelot, taprio->cycle_time_extension, QSYS_PARAM_CFG_REG_5);
|
|
|
|
|
|
|
|
for (i = 0; i < taprio->num_entries; i++)
|
|
|
|
vsc9959_tas_gcl_set(ocelot, i, &taprio->entries[i]);
|
|
|
|
|
|
|
|
ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
|
|
|
|
QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
|
|
|
|
QSYS_TAS_PARAM_CFG_CTRL);
|
|
|
|
|
|
|
|
ret = readx_poll_timeout(vsc9959_tas_read_cfg_status, ocelot, val,
|
|
|
|
!(val & QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE),
|
|
|
|
10, 100000);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-05-13 02:25:10 +00:00
|
|
|
static int vsc9959_qos_port_cbs_set(struct dsa_switch *ds, int port,
|
|
|
|
struct tc_cbs_qopt_offload *cbs_qopt)
|
|
|
|
{
|
|
|
|
struct ocelot *ocelot = ds->priv;
|
|
|
|
int port_ix = port * 8 + cbs_qopt->queue;
|
|
|
|
u32 rate, burst;
|
|
|
|
|
|
|
|
if (cbs_qopt->queue >= ds->num_tx_queues)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (!cbs_qopt->enable) {
|
|
|
|
ocelot_write_gix(ocelot, QSYS_CIR_CFG_CIR_RATE(0) |
|
|
|
|
QSYS_CIR_CFG_CIR_BURST(0),
|
|
|
|
QSYS_CIR_CFG, port_ix);
|
|
|
|
|
|
|
|
ocelot_rmw_gix(ocelot, 0, QSYS_SE_CFG_SE_AVB_ENA,
|
|
|
|
QSYS_SE_CFG, port_ix);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Rate unit is 100 kbps */
|
|
|
|
rate = DIV_ROUND_UP(cbs_qopt->idleslope, 100);
|
|
|
|
/* Avoid using zero rate */
|
|
|
|
rate = clamp_t(u32, rate, 1, GENMASK(14, 0));
|
|
|
|
/* Burst unit is 4kB */
|
|
|
|
burst = DIV_ROUND_UP(cbs_qopt->hicredit, 4096);
|
|
|
|
/* Avoid using zero burst size */
|
2020-05-14 18:33:02 +00:00
|
|
|
burst = clamp_t(u32, burst, 1, GENMASK(5, 0));
|
2020-05-13 02:25:10 +00:00
|
|
|
ocelot_write_gix(ocelot,
|
|
|
|
QSYS_CIR_CFG_CIR_RATE(rate) |
|
|
|
|
QSYS_CIR_CFG_CIR_BURST(burst),
|
|
|
|
QSYS_CIR_CFG,
|
|
|
|
port_ix);
|
|
|
|
|
|
|
|
ocelot_rmw_gix(ocelot,
|
|
|
|
QSYS_SE_CFG_SE_FRM_MODE(0) |
|
|
|
|
QSYS_SE_CFG_SE_AVB_ENA,
|
|
|
|
QSYS_SE_CFG_SE_AVB_ENA |
|
|
|
|
QSYS_SE_CFG_SE_FRM_MODE_M,
|
|
|
|
QSYS_SE_CFG,
|
|
|
|
port_ix);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-13 02:25:09 +00:00
|
|
|
static int vsc9959_port_setup_tc(struct dsa_switch *ds, int port,
|
|
|
|
enum tc_setup_type type,
|
|
|
|
void *type_data)
|
|
|
|
{
|
|
|
|
struct ocelot *ocelot = ds->priv;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case TC_SETUP_QDISC_TAPRIO:
|
|
|
|
return vsc9959_qos_port_tas_set(ocelot, port, type_data);
|
2020-05-13 02:25:10 +00:00
|
|
|
case TC_SETUP_QDISC_CBS:
|
|
|
|
return vsc9959_qos_port_cbs_set(ds, port, type_data);
|
2020-05-13 02:25:09 +00:00
|
|
|
default:
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-13 16:57:09 +00:00
|
|
|
static const struct felix_info felix_info_vsc9959 = {
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
.target_io_res = vsc9959_target_io_res,
|
|
|
|
.port_io_res = vsc9959_port_io_res,
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
.imdio_res = &vsc9959_imdio_res,
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
.regfields = vsc9959_regfields,
|
|
|
|
.map = vsc9959_regmap,
|
|
|
|
.ops = &vsc9959_ops,
|
|
|
|
.stats_layout = vsc9959_stats_layout,
|
|
|
|
.num_stats = ARRAY_SIZE(vsc9959_stats_layout),
|
2020-02-29 14:31:14 +00:00
|
|
|
.vcap = vsc9959_vcap_props,
|
2020-05-03 22:20:26 +00:00
|
|
|
.num_mact_rows = 2048,
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
.num_ports = 6,
|
2021-01-15 02:11:16 +00:00
|
|
|
.num_tx_queues = OCELOT_NUM_TC,
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
.switch_pci_bar = 4,
|
|
|
|
.imdio_pci_bar = 0,
|
2020-09-18 10:57:52 +00:00
|
|
|
.ptp_caps = &vsc9959_ptp_caps,
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
.mdio_bus_alloc = vsc9959_mdio_bus_alloc,
|
|
|
|
.mdio_bus_free = vsc9959_mdio_bus_free,
|
2020-07-13 16:57:09 +00:00
|
|
|
.phylink_validate = vsc9959_phylink_validate,
|
net: dsa: felix: Add PCS operations for PHYLINK
Layerscape SoCs traditionally expose the SerDes configuration/status for
Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register
format that is compatible with clause 22 or clause 45 (depending on
SerDes protocol). Each MAC has its own internal MDIO bus on which there
is one or more of these PCS's, responding to commands at a configurable
PHY address. The per-port internal MDIO bus (which is just for PCSs) is
totally separate and has nothing to do with the dedicated external MDIO
controller (which is just for PHYs), but the register map for the MDIO
controller is the same.
The VSC9959 (Felix) switch instantiated in the LS1028A is integrated
in hardware with the ENETC PCS of its DSA master, and reuses its MDIO
controller driver, so Felix has been made to depend on it in Kconfig.
+------------------------------------------------------------------------+
| +--------+ GMII (typically disabled via RCW) |
| ENETC PCI | ENETC |--------------------------+ |
| Root Complex | port 3 |-----------------------+ | |
| Integrated +--------+ | | |
| Endpoint | | |
| +--------+ 2.5G GMII | | |
| | ENETC |--------------+ | | |
| | port 2 |-----------+ | | | |
| +--------+ | | | | |
| +--------+ +--------+ |
| | Felix | | Felix | |
| | port 4 | | port 5 | |
| +--------+ +--------+ |
| |
| +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ |
| | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | |
| | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | |
+------------------------------------------------------------------------+
| |||| SerDes | |||| |||| |||| |||| |
| +--------+block | +--------------------------------------------+ |
| | ENETC | | | ENETC port 2 internal MDIO bus | |
| | port 0 | | | PCS PCS PCS PCS | |
| | PCS | | | 0 1 2 3 | |
+-----------------|------------------------------------------------------+
v v v v v v
SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X
USXGMII/ (bypasses
1000Base-X/ SerDes)
2500Base-X
In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of
the ENETC root complex, and has 2 BARs:
- BAR 4: the switch's effective registers
- BAR 0: the MDIO controller register map lended from ENETC port 2
(PF2), for accessing its associated PCS's.
This explanation is necessary because the patch does some renaming
"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear
a bit obtuse.
The fact that the internal MDIO bus is "borrowed" is relevant because
the register map is found in PF5 (the switch) but it triggers an access
fault if PF2 (the ENETC DSA master) is not enabled. This is not treated
in any way (and I don't think it can be treated).
All of this is so SoC-specific, that it was contained as much as
possible in the platform-integration file felix_vsc9959.c.
We need to parse and pre-validate the device tree because of 2 reasons:
- The PHY mode (SerDes protocol) cannot change at runtime due to SoC
design.
- There is a circular dependency in that we need to know what clause the
PCS speaks in order to find it on the internal MDIO bus. But the
clause of the PCS depends on what phy-mode it is configured for.
The goal of this patch is to make steps towards removing the bootloader
dependency for SGMII PCS pre-configuration, as well as to add support
for monitoring the in-band SGMII AN between the PCS and the system-side
link partner (PHY or other MAC).
In practice the bootloader dependency is not completely removed. U-Boot
pre-programs the PHY address at which each PCS can be found on the
internal MDIO bus (MDEV_PORT). This is needed because the PCS of each
port has the same out-of-reset PHY address of zero. The SerDes register
for changing MDEV_PORT is pretty deep in the SoC (outside the addresses
of the ENETC PCI BARs) and therefore inaccessible to us from here.
Felix VSC9959 and Ocelot VSC7514 are integrated very differently in
their respective SoCs, and for that reason Felix does not use the Ocelot
core library for PHYLINK. On one hand we don't want to impose the
fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't
need to force the MAC link speed the way Ocelot does, since the MAC is
connected to the PCS through a fixed GMII, and the PCS is the one who
does the rate adaptation at lower link speeds, which the MAC does not
even need to know about. In fact changing the GMII speed for Felix
irrecoverably breaks transmission through that port until a reset.
The pair with ENETC port 3 and Felix port 5 is optional and doesn't
support tagging. When we enable it, swp5 is a regular slave port, albeit
an internal one. The trouble is that it doesn't work, and that is
because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave
ports. So that is yet another reason for wanting to convert Felix to the
native PHYLINK API.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-01-06 01:34:17 +00:00
|
|
|
.prevalidate_phy_mode = vsc9959_prevalidate_phy_mode,
|
2020-09-18 10:57:49 +00:00
|
|
|
.port_setup_tc = vsc9959_port_setup_tc,
|
|
|
|
.port_sched_speed_set = vsc9959_sched_speed_set,
|
net: dsa: ocelot: add driver for Felix switch family
This supports an Ethernet switching core from Vitesse / Microsemi /
Microchip (VSC9959) which is part of the Ocelot family (a brand name),
and whose code name is Felix. The switch can be (and is) integrated on
different SoCs as a PCIe endpoint device.
The functionality is provided by the core of the Ocelot switch driver
(drivers/net/ethernet/mscc). In this regard, the current driver is an
instance of Microsemi's Ocelot core driver, with a DSA front-end. It
inherits its name from VSC9959's code name, to distinguish itself from
the switchdev ocelot driver.
The patch adds the logic for probing a PCI device and defines the
register map for the VSC9959 switch core, since it has some differences
in register addresses and bitfield mappings compared to the other Ocelot
switches (VSC7511, VSC7512, VSC7513, VSC7514).
The Felix driver declares the register map as part of the "instance
table". Currently the VSC9959 inside NXP LS1028A is the only instance,
but presumably it can support other switches in the Ocelot family, when
used in DSA mode (Linux running on the external CPU, and not on the
embedded MIPS).
In a few cases, some h/w operations have to be done differently on
VSC9959 due to missing bitfields. This is the case for the switch core
reset and init. Because for this operation Ocelot uses some bits that
are not present on Felix, the latter has to use a register from the
global registers block (GCB) instead.
Although it is a PCI driver, it relies on DT bindings for compatibility
with DSA (CPU port link, PHY library). It does not have any custom
device tree bindings, since we would like to minimize its dependency on
device tree though.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-14 15:03:30 +00:00
|
|
|
};
|
2020-07-13 16:57:09 +00:00
|
|
|
|
|
|
|
static irqreturn_t felix_irq_handler(int irq, void *data)
|
|
|
|
{
|
|
|
|
struct ocelot *ocelot = (struct ocelot *)data;
|
|
|
|
|
|
|
|
/* The INTB interrupt is used for both PTP TX timestamp interrupt
|
|
|
|
* and preemption status change interrupt on each port.
|
|
|
|
*
|
|
|
|
* - Get txtstamp if have
|
|
|
|
* - TODO: handle preemption. Without handling it, driver may get
|
|
|
|
* interrupt storm.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ocelot_get_txtstamp(ocelot);
|
|
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int felix_pci_probe(struct pci_dev *pdev,
|
|
|
|
const struct pci_device_id *id)
|
|
|
|
{
|
|
|
|
struct dsa_switch *ds;
|
|
|
|
struct ocelot *ocelot;
|
|
|
|
struct felix *felix;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
|
|
|
|
dev_info(&pdev->dev, "device is disabled, skipping\n");
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = pci_enable_device(pdev);
|
|
|
|
if (err) {
|
|
|
|
dev_err(&pdev->dev, "device enable failed\n");
|
|
|
|
goto err_pci_enable;
|
|
|
|
}
|
|
|
|
|
|
|
|
felix = kzalloc(sizeof(struct felix), GFP_KERNEL);
|
|
|
|
if (!felix) {
|
|
|
|
err = -ENOMEM;
|
|
|
|
dev_err(&pdev->dev, "Failed to allocate driver memory\n");
|
|
|
|
goto err_alloc_felix;
|
|
|
|
}
|
|
|
|
|
|
|
|
pci_set_drvdata(pdev, felix);
|
|
|
|
ocelot = &felix->ocelot;
|
|
|
|
ocelot->dev = &pdev->dev;
|
2021-01-15 02:11:16 +00:00
|
|
|
ocelot->num_flooding_pgids = OCELOT_NUM_TC;
|
2020-07-13 16:57:09 +00:00
|
|
|
felix->info = &felix_info_vsc9959;
|
|
|
|
felix->switch_base = pci_resource_start(pdev,
|
|
|
|
felix->info->switch_pci_bar);
|
|
|
|
felix->imdio_base = pci_resource_start(pdev,
|
|
|
|
felix->info->imdio_pci_bar);
|
|
|
|
|
|
|
|
pci_set_master(pdev);
|
|
|
|
|
|
|
|
err = devm_request_threaded_irq(&pdev->dev, pdev->irq, NULL,
|
|
|
|
&felix_irq_handler, IRQF_ONESHOT,
|
|
|
|
"felix-intb", ocelot);
|
|
|
|
if (err) {
|
|
|
|
dev_err(&pdev->dev, "Failed to request irq\n");
|
|
|
|
goto err_alloc_irq;
|
|
|
|
}
|
|
|
|
|
|
|
|
ocelot->ptp = 1;
|
|
|
|
|
|
|
|
ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL);
|
|
|
|
if (!ds) {
|
|
|
|
err = -ENOMEM;
|
|
|
|
dev_err(&pdev->dev, "Failed to allocate DSA switch\n");
|
|
|
|
goto err_alloc_ds;
|
|
|
|
}
|
|
|
|
|
|
|
|
ds->dev = &pdev->dev;
|
|
|
|
ds->num_ports = felix->info->num_ports;
|
|
|
|
ds->num_tx_queues = felix->info->num_tx_queues;
|
|
|
|
ds->ops = &felix_switch_ops;
|
|
|
|
ds->priv = ocelot;
|
|
|
|
felix->ds = ds;
|
net: dsa: felix: convert to the new .change_tag_protocol DSA API
In expectation of the new tag_ocelot_8021q tagger implementation, we
need to be able to do runtime switchover between one tagger and another.
So we must structure the existing code for the current NPI-based tagger
in a certain way.
We move the felix_npi_port_init function in expectation of the future
driver configuration necessary for tag_ocelot_8021q: we would like to
not have the NPI-related bits interspersed with the tag_8021q bits.
The conversion from this:
ocelot_write_rix(ocelot,
ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports, 0)),
ANA_PGID_PGID, PGID_UC);
to this:
cpu_flood = ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports));
ocelot_rmw_rix(ocelot, cpu_flood, cpu_flood, ANA_PGID_PGID, PGID_UC);
is perhaps non-trivial, but is nonetheless non-functional. The PGID_UC
(replicator for unknown unicast) is already configured out of hardware
reset to flood to all ports except ocelot->num_phys_ports (the CPU port
module). All we change is that we use a read-modify-write to only add
the CPU port module to the unknown unicast replicator, as opposed to
doing a full write to the register.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2021-01-29 01:00:07 +00:00
|
|
|
felix->tag_proto = DSA_TAG_PROTO_OCELOT;
|
2020-07-13 16:57:09 +00:00
|
|
|
|
|
|
|
err = dsa_register_switch(ds);
|
|
|
|
if (err) {
|
|
|
|
dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err);
|
|
|
|
goto err_register_ds;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_register_ds:
|
|
|
|
kfree(ds);
|
|
|
|
err_alloc_ds:
|
|
|
|
err_alloc_irq:
|
|
|
|
kfree(felix);
|
2021-01-09 20:34:15 +00:00
|
|
|
err_alloc_felix:
|
2020-07-13 16:57:09 +00:00
|
|
|
pci_disable_device(pdev);
|
|
|
|
err_pci_enable:
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void felix_pci_remove(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
struct felix *felix;
|
|
|
|
|
|
|
|
felix = pci_get_drvdata(pdev);
|
|
|
|
|
|
|
|
dsa_unregister_switch(felix->ds);
|
|
|
|
|
|
|
|
kfree(felix->ds);
|
|
|
|
kfree(felix);
|
|
|
|
|
|
|
|
pci_disable_device(pdev);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct pci_device_id felix_ids[] = {
|
|
|
|
{
|
|
|
|
/* NXP LS1028A */
|
|
|
|
PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0xEEF0),
|
|
|
|
},
|
|
|
|
{ 0, }
|
|
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(pci, felix_ids);
|
|
|
|
|
2020-09-18 10:57:53 +00:00
|
|
|
static struct pci_driver felix_vsc9959_pci_driver = {
|
2020-07-13 16:57:09 +00:00
|
|
|
.name = "mscc_felix",
|
|
|
|
.id_table = felix_ids,
|
|
|
|
.probe = felix_pci_probe,
|
|
|
|
.remove = felix_pci_remove,
|
|
|
|
};
|
2020-09-18 10:57:53 +00:00
|
|
|
module_pci_driver(felix_vsc9959_pci_driver);
|
|
|
|
|
|
|
|
MODULE_DESCRIPTION("Felix Switch driver");
|
|
|
|
MODULE_LICENSE("GPL v2");
|