[PATCH net-next v3 06/10] net: mvpp2: 2500baseX support

2018-05-17 Thread Antoine Tenart
This patch adds the 2500Base-X PHY mode support in the Marvell PPv2
driver. 2500Base-X is quite close to 1000Base-X and SGMII modes and uses
nearly the same code path.

Signed-off-by: Antoine Tenart 
---
 drivers/net/ethernet/marvell/mvpp2.c | 51 +---
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index ece61f1727e4..5e580482769e 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -4871,6 +4871,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
break;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
+   case PHY_INTERFACE_MODE_2500BASEX:
mvpp22_gop_init_sgmii(port);
break;
case PHY_INTERFACE_MODE_10GKR:
@@ -4909,7 +4910,8 @@ static void mvpp22_gop_unmask_irq(struct mvpp2_port *port)
 
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+   port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
/* Enable the GMAC link status irq for this port */
val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
val |= MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
@@ -4940,7 +4942,8 @@ static void mvpp22_gop_mask_irq(struct mvpp2_port *port)
 
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+   port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
val &= ~MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK);
@@ -4953,7 +4956,8 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
 
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+   port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_MASK);
val |= MVPP22_GMAC_INT_MASK_LINK_STAT;
writel(val, port->base + MVPP22_GMAC_INT_MASK);
@@ -4968,6 +4972,16 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
mvpp22_gop_unmask_irq(port);
 }
 
+/* Sets the PHY mode of the COMPHY (which configures the serdes lanes).
+ *
+ * The PHY mode used by the PPv2 driver comes from the network subsystem, while
+ * the one given to the COMPHY comes from the generic PHY subsystem. Hence they
+ * differ.
+ *
+ * The COMPHY configures the serdes lanes regardless of the actual use of the
+ * lanes by the physical layer. This is why configurations like
+ * "PPv2 (2500BaseX) - COMPHY (2500SGMII)" are valid.
+ */
 static int mvpp22_comphy_init(struct mvpp2_port *port)
 {
enum phy_mode mode;
@@ -4981,6 +4995,9 @@ static int mvpp22_comphy_init(struct mvpp2_port *port)
case PHY_INTERFACE_MODE_1000BASEX:
mode = PHY_MODE_SGMII;
break;
+   case PHY_INTERFACE_MODE_2500BASEX:
+   mode = PHY_MODE_2500SGMII;
+   break;
case PHY_INTERFACE_MODE_10GKR:
mode = PHY_MODE_10GKR;
break;
@@ -5062,7 +5079,8 @@ static void mvpp2_port_loopback_set(struct mvpp2_port 
*port,
val &= ~MVPP2_GMAC_GMII_LB_EN_MASK;
 
if (port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
+   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+   port->phy_interface == PHY_INTERFACE_MODE_2500BASEX)
val |= MVPP2_GMAC_PCS_LB_EN_MASK;
else
val &= ~MVPP2_GMAC_PCS_LB_EN_MASK;
@@ -6273,7 +6291,8 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void 
*dev_id)
}
} else if (phy_interface_mode_is_rgmii(port->phy_interface) ||
   port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-  port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+  port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+  port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_STAT);
if (val & MVPP22_GMAC_INT_STAT_LINK) {
event = true;
@@ -8056,8 +8075,10 @@ static void mvpp2_phylink_validate(struct net_device 
*dev,
 

[PATCH net-next v3 06/10] net: mvpp2: 2500baseX support

2018-05-17 Thread Antoine Tenart
This patch adds the 2500Base-X PHY mode support in the Marvell PPv2
driver. 2500Base-X is quite close to 1000Base-X and SGMII modes and uses
nearly the same code path.

Signed-off-by: Antoine Tenart 
---
 drivers/net/ethernet/marvell/mvpp2.c | 51 +---
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index ece61f1727e4..5e580482769e 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -4871,6 +4871,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
break;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
+   case PHY_INTERFACE_MODE_2500BASEX:
mvpp22_gop_init_sgmii(port);
break;
case PHY_INTERFACE_MODE_10GKR:
@@ -4909,7 +4910,8 @@ static void mvpp22_gop_unmask_irq(struct mvpp2_port *port)
 
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+   port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
/* Enable the GMAC link status irq for this port */
val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
val |= MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
@@ -4940,7 +4942,8 @@ static void mvpp22_gop_mask_irq(struct mvpp2_port *port)
 
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+   port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
val &= ~MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK);
@@ -4953,7 +4956,8 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
 
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+   port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_MASK);
val |= MVPP22_GMAC_INT_MASK_LINK_STAT;
writel(val, port->base + MVPP22_GMAC_INT_MASK);
@@ -4968,6 +4972,16 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
mvpp22_gop_unmask_irq(port);
 }
 
+/* Sets the PHY mode of the COMPHY (which configures the serdes lanes).
+ *
+ * The PHY mode used by the PPv2 driver comes from the network subsystem, while
+ * the one given to the COMPHY comes from the generic PHY subsystem. Hence they
+ * differ.
+ *
+ * The COMPHY configures the serdes lanes regardless of the actual use of the
+ * lanes by the physical layer. This is why configurations like
+ * "PPv2 (2500BaseX) - COMPHY (2500SGMII)" are valid.
+ */
 static int mvpp22_comphy_init(struct mvpp2_port *port)
 {
enum phy_mode mode;
@@ -4981,6 +4995,9 @@ static int mvpp22_comphy_init(struct mvpp2_port *port)
case PHY_INTERFACE_MODE_1000BASEX:
mode = PHY_MODE_SGMII;
break;
+   case PHY_INTERFACE_MODE_2500BASEX:
+   mode = PHY_MODE_2500SGMII;
+   break;
case PHY_INTERFACE_MODE_10GKR:
mode = PHY_MODE_10GKR;
break;
@@ -5062,7 +5079,8 @@ static void mvpp2_port_loopback_set(struct mvpp2_port 
*port,
val &= ~MVPP2_GMAC_GMII_LB_EN_MASK;
 
if (port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
+   port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+   port->phy_interface == PHY_INTERFACE_MODE_2500BASEX)
val |= MVPP2_GMAC_PCS_LB_EN_MASK;
else
val &= ~MVPP2_GMAC_PCS_LB_EN_MASK;
@@ -6273,7 +6291,8 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void 
*dev_id)
}
} else if (phy_interface_mode_is_rgmii(port->phy_interface) ||
   port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-  port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+  port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+  port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_STAT);
if (val & MVPP22_GMAC_INT_STAT_LINK) {
event = true;
@@ -8056,8 +8075,10 @@ static void mvpp2_phylink_validate(struct net_device 
*dev,
phylink_set(mask,