From: Ong Boon Leong
xPCS is DWC Ethernet Physical Coding Sublayer that may be integrated
into a GbE controller that uses DWC EQoS MAC controller. An example of
HW configuration is shown below:-
<-GBE Controller-->|<--External PHY chip-->
+--+ +++---+ +--+
| EQoS | <-GMII->| DW |<-->|PHY| <-- SGMII --> | External GbE |
| MAC| |xPCS||IF | | PHY Chip |
+--+ +++---+ +--+
^ ^ ^
| | |
+-MDIO-+
xPCS is a Clause-45 MDIO Manageable Device (MMD) and we need a way to
differentiate it from external PHY chip that is discovered over MDIO.
Therefore, xpcs_phy_addr is introduced in stmmac platform data
(plat_stmmacenet_data) for differentiating xPCS from 'phy_addr' that
belongs to external PHY.
Basic functionalities for initializing xPCS and configuring auto
negotiation (AN), loopback, link status, AN advertisement and Link
Partner ability are implemented. The implementation supports the C37
AN for 1000BASE-X and SGMII (MAC side SGMII only).
Tested-by: Tan, Tee Min
Reviewed-by: Voon Weifeng
Reviewed-by: Kweh Hock Leong
Signed-off-by: Ong Boon Leong
Signed-off-by: Voon Weifeng
---
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
drivers/net/ethernet/stmicro/stmmac/common.h | 1 +
drivers/net/ethernet/stmicro/stmmac/dwxpcs.c | 198 +++
drivers/net/ethernet/stmicro/stmmac/dwxpcs.h | 51 +++
drivers/net/ethernet/stmicro/stmmac/hwif.h | 19 +++
include/linux/stmmac.h | 1 +
6 files changed, 271 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxpcs.c
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxpcs.h
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index c59926d96bcc..f007fb873455 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -6,7 +6,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o
ring_mode.o \
mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \
dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
- $(stmmac-y)
+ dwxpcs.o $(stmmac-y)
stmmac-$(CONFIG_STMMAC_SELFTESTS) += stmmac_selftests.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1961fe9144ca..822786872796 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -419,6 +419,7 @@ struct mii_regs {
struct mac_device_info {
const struct stmmac_ops *mac;
+ const struct stmmac_xpcs *xpcs;
const struct stmmac_desc_ops *desc;
const struct stmmac_dma_ops *dma;
const struct stmmac_mode_ops *mode;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxpcs.c
b/drivers/net/ethernet/stmicro/stmmac/dwxpcs.c
new file mode 100644
index ..081d3631afd2
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxpcs.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019, Intel Corporation.
+ * DWC Ethernet Physical Coding Sublayer
+ */
+#include
+#include
+#include "dwxpcs.h"
+#include "stmmac.h"
+
+/* DW xPCS mdiobus_read and mdiobus_write helper functions */
+#define xpcs_read(dev, reg) \
+ mdiobus_read(priv->mii, xpcs_phy_addr, \
+MII_ADDR_C45 | (reg) | \
+((dev) << MII_DEVADDR_C45_SHIFT))
+#define xpcs_write(dev, reg, val) \
+ mdiobus_write(priv->mii, xpcs_phy_addr, \
+ MII_ADDR_C45 | (reg) | \
+ ((dev) << MII_DEVADDR_C45_SHIFT), val)
+
+static void dw_xpcs_init(struct net_device *ndev, int pcs_mode)
+{
+ struct stmmac_priv *priv = netdev_priv(ndev);
+ int xpcs_phy_addr = priv->plat->xpcs_phy_addr;
+ int phydata;
+
+ if (pcs_mode == AN_CTRL_PCS_MD_C37_SGMII) {
+ /* For AN for SGMII mode, the settings are :-
+* 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
+* 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
+*DW xPCS used with DW EQoS MAC is always MAC
+*side SGMII.
+* 3) VR_MII_AN_CTRL Bit(0) [AN_INTR_EN] = 1b (AN Interrupt
+*enabled)
+* 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
+*speed mode change after SGMII AN complete)
+* Note: Since it is MAC side SGMII, there is no need to set
+* SR_MII_AN_ADV. MAC side