This patch add support for SGMII interface and
2.5Gbps MAC in Cadence ethernet controller driver.

Signed-off-by: Parshuram Thombare <pthom...@cadence.com>
---
 drivers/net/ethernet/cadence/macb.h      | 54 ++++++++++++++++++------
 drivers/net/ethernet/cadence/macb_main.c | 42 +++++++++++++++++-
 2 files changed, 82 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h 
b/drivers/net/ethernet/cadence/macb.h
index a4007057b35e..301fbcb0df4b 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -77,6 +77,7 @@
 #define MACB_RBQPH             0x04D4
 
 /* GEM register offsets. */
+#define GEM_NCR                        0x0000 /* Network Control */
 #define GEM_NCFGR              0x0004 /* Network Config */
 #define GEM_USRIO              0x000c /* User IO */
 #define GEM_DMACFG             0x0010 /* DMA Configuration */
@@ -156,6 +157,7 @@
 #define GEM_PEFTN              0x01f4 /* PTP Peer Event Frame Tx Ns */
 #define GEM_PEFRSL             0x01f8 /* PTP Peer Event Frame Rx Sec Low */
 #define GEM_PEFRN              0x01fc /* PTP Peer Event Frame Rx Ns */
+#define GEM_PCS_CTRL           0x0200 /* PCS Control */
 #define GEM_DCFG1              0x0280 /* Design Config 1 */
 #define GEM_DCFG2              0x0284 /* Design Config 2 */
 #define GEM_DCFG3              0x0288 /* Design Config 3 */
@@ -271,6 +273,10 @@
 #define MACB_IRXFCS_OFFSET     19
 #define MACB_IRXFCS_SIZE       1
 
+/* GEM specific NCR bitfields. */
+#define GEM_TWO_PT_FIVE_GIG_OFFSET     29
+#define GEM_TWO_PT_FIVE_GIG_SIZE       1
+
 /* GEM specific NCFGR bitfields. */
 #define GEM_GBE_OFFSET         10 /* Gigabit mode enable */
 #define GEM_GBE_SIZE           1
@@ -323,6 +329,9 @@
 #define MACB_MDIO_SIZE         1
 #define MACB_IDLE_OFFSET       2 /* The PHY management logic is idle */
 #define MACB_IDLE_SIZE         1
+#define MACB_DUPLEX_OFFSET     3
+#define MACB_DUPLEX_SIZE       1
+
 
 /* Bitfields in TSR */
 #define MACB_UBR_OFFSET                0 /* Used bit read */
@@ -456,11 +465,17 @@
 #define MACB_REV_OFFSET                                0
 #define MACB_REV_SIZE                          16
 
+/* Bitfields in PCS_CONTROL. */
+#define GEM_PCS_CTRL_RST_OFFSET                        15
+#define GEM_PCS_CTRL_RST_SIZE                  1
+
 /* Bitfields in DCFG1. */
 #define GEM_IRQCOR_OFFSET                      23
 #define GEM_IRQCOR_SIZE                                1
 #define GEM_DBWDEF_OFFSET                      25
 #define GEM_DBWDEF_SIZE                                3
+#define GEM_NO_PCS_OFFSET                      0
+#define GEM_NO_PCS_SIZE                                1
 
 /* Bitfields in DCFG2. */
 #define GEM_RX_PKT_BUFF_OFFSET                 20
@@ -637,19 +652,32 @@
 #define MACB_MAN_CODE                          2
 
 /* Capability mask bits */
-#define MACB_CAPS_ISR_CLEAR_ON_WRITE           0x00000001
-#define MACB_CAPS_USRIO_HAS_CLKEN              0x00000002
-#define MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII    0x00000004
-#define MACB_CAPS_NO_GIGABIT_HALF              0x00000008
-#define MACB_CAPS_USRIO_DISABLED               0x00000010
-#define MACB_CAPS_JUMBO                                0x00000020
-#define MACB_CAPS_GEM_HAS_PTP                  0x00000040
-#define MACB_CAPS_BD_RD_PREFETCH               0x00000080
-#define MACB_CAPS_NEEDS_RSTONUBR               0x00000100
-#define MACB_CAPS_FIFO_MODE                    0x10000000
-#define MACB_CAPS_GIGABIT_MODE_AVAILABLE       0x20000000
-#define MACB_CAPS_SG_DISABLED                  0x40000000
-#define MACB_CAPS_MACB_IS_GEM                  0x80000000
+#define MACB_CAPS_ISR_CLEAR_ON_WRITE           BIT(0)
+#define MACB_CAPS_USRIO_HAS_CLKEN              BIT(1)
+#define MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII    BIT(2)
+#define MACB_CAPS_NO_GIGABIT_HALF              BIT(3)
+#define MACB_CAPS_USRIO_DISABLED               BIT(4)
+#define MACB_CAPS_JUMBO                                BIT(5)
+#define MACB_CAPS_GEM_HAS_PTP                  BIT(6)
+#define MACB_CAPS_BD_RD_PREFETCH               BIT(7)
+#define MACB_CAPS_NEEDS_RSTONUBR               BIT(8)
+#define MACB_CAPS_FIFO_MODE                    BIT(28)
+#define MACB_CAPS_GIGABIT_MODE_AVAILABLE       BIT(29)
+#define MACB_CAPS_SG_DISABLED                  BIT(30)
+#define MACB_CAPS_MACB_IS_GEM                  BIT(31)
+#define MACB_CAPS_PCS                          BIT(24)
+#define MACB_CAPS_MACB_IS_GEM_GXL              BIT(25)
+
+#define MACB_GEM7010_IDNUM                     0x009
+#define MACB_GEM7014_IDNU                      0x107
+#define MACB_GEM7014A_IDNUM                    0x207
+#define MACB_GEM7016_IDNUM                     0x10a
+#define MACB_GEM7017_IDNUM                     0x00a
+#define MACB_GEM7017A_IDNUM                    0x20a
+#define MACB_GEM7020_IDNUM                     0x003
+#define MACB_GEM7021_IDNUM                     0x00c
+#define MACB_GEM7021A_IDNUM                    0x20c
+#define MACB_GEM7022_IDNUM                     0x00b
 
 /* LSO settings */
 #define MACB_LSO_UFO_ENABLE                    0x01
diff --git a/drivers/net/ethernet/cadence/macb_main.c 
b/drivers/net/ethernet/cadence/macb_main.c
index ce064eb9252a..6485fcc0560b 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -443,6 +443,10 @@ static void gem_phylink_validate(struct phylink_config 
*pl_config,
        __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
 
        switch (state->interface) {
+       case PHY_INTERFACE_MODE_SGMII:
+               if (!(bp->caps & MACB_CAPS_PCS))
+                       goto empty_set;
+               break;
        case PHY_INTERFACE_MODE_GMII:
        case PHY_INTERFACE_MODE_RGMII:
                if (!macb_is_gem(bp))
@@ -453,6 +457,8 @@ static void gem_phylink_validate(struct phylink_config 
*pl_config,
        }
 
        switch (state->interface) {
+       case PHY_INTERFACE_MODE_NA:
+       case PHY_INTERFACE_MODE_SGMII:
        case PHY_INTERFACE_MODE_GMII:
        case PHY_INTERFACE_MODE_RGMII:
                if (bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE) {
@@ -497,8 +503,26 @@ static void gem_mac_config(struct phylink_config 
*pl_config, unsigned int mode,
 
        spin_lock_irqsave(&bp->lock, flags);
 
-       if (change_interface)
+       if (change_interface) {
                bp->phy_interface = state->interface;
+               /* 2.5G mode not supported */
+               gem_writel(bp, NCR, ~GEM_BIT(TWO_PT_FIVE_GIG) &
+                          gem_readl(bp, NCR));
+
+               if (state->interface == PHY_INTERFACE_MODE_SGMII) {
+                       gem_writel(bp, NCFGR, GEM_BIT(SGMIIEN) |
+                                  GEM_BIT(PCSSEL) |
+                                  gem_readl(bp, NCFGR));
+               } else {
+                       /* Disable SGMII mode and PCS */
+                       gem_writel(bp, NCFGR, ~(GEM_BIT(SGMIIEN) |
+                                  GEM_BIT(PCSSEL)) &
+                                  gem_readl(bp, NCFGR));
+                       /* Reset PCS */
+                       gem_writel(bp, PCS_CTRL, gem_readl(bp, PCS_CTRL) |
+                                  GEM_BIT(PCS_CTRL_RST));
+               }
+       }
 
        if (!phylink_autoneg_inband(mode) &&
            (bp->speed != state->speed ||
@@ -3356,6 +3380,22 @@ static void macb_configure_caps(struct macb *bp,
                dcfg = gem_readl(bp, DCFG1);
                if (GEM_BFEXT(IRQCOR, dcfg) == 0)
                        bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
+               if (GEM_BFEXT(NO_PCS, dcfg) == 0)
+                       bp->caps |= MACB_CAPS_PCS;
+               switch (MACB_BFEXT(IDNUM, macb_readl(bp, MID))) {
+               case MACB_GEM7016_IDNUM:
+               case MACB_GEM7017_IDNUM:
+               case MACB_GEM7017A_IDNUM:
+               case MACB_GEM7020_IDNUM:
+               case MACB_GEM7021_IDNUM:
+               case MACB_GEM7021A_IDNUM:
+               case MACB_GEM7022_IDNUM:
+                       bp->caps |= MACB_CAPS_USRIO_DISABLED;
+                       bp->caps |= MACB_CAPS_MACB_IS_GEM_GXL;
+                       break;
+               default:
+                       break;
+               }
                dcfg = gem_readl(bp, DCFG2);
                if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
                        bp->caps |= MACB_CAPS_FIFO_MODE;
-- 
2.17.1

Reply via email to