RE: [PATCH net-next v4 2/5] net: stmmac: introducing support for DWC xPCS logics

2019-05-29 Thread Jose Abreu
From: Voon Weifeng 
Date: Wed, May 29, 2019 at 17:58:24

> +/* Helpers for DW xPCS */
> +struct stmmac_xpcs {
> + void (*xpcs_init)(struct net_device *ndev, int pcs_mode);
> + void (*xpcs_ctrl_ane)(struct net_device *ndev, bool ane, bool loopback);
> + void (*xpcs_get_adv_lp)(struct net_device *ndev, struct rgmii_adv *adv,
> + int pcs_mode);
> + int (*xpcs_irq_status)(struct net_device *ndev,
> +struct stmmac_extra_stats *x, int pcs_mode);
> +};

Please rename the structure to stmmac_xpcs_ops, to keep consistency with 
other helpers.

Thanks,
Jose Miguel Abreu


[PATCH net-next v4 2/5] net: stmmac: introducing support for DWC xPCS logics

2019-05-29 Thread Voon Weifeng
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