summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2016-12-23 15:40:35 +0000
committerRussell King <rmk+kernel@armlinux.org.uk>2019-07-09 16:42:06 +0100
commitcfbdfed91906a59c61b55187ebf707653c1efc5f (patch)
tree6fedab6f7d40c542672b84cb3709d2dee0d24a8c
parentf57e3915150a868b9035a9ccde04da11e748c495 (diff)
net: marvell: mvpp2x: convert to gmac
-rw-r--r--drivers/net/ethernet/marvell/Kconfig1
-rw-r--r--drivers/net/ethernet/marvell/mvgmac.c2
-rw-r--r--drivers/net/ethernet/marvell/mvpp2x/mv_pp2x.h2
-rw-r--r--drivers/net/ethernet/marvell/mvpp2x/mv_pp2x_main.c202
4 files changed, 23 insertions, 184 deletions
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index 547c5be18b0f..a7522b53f6fc 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -97,6 +97,7 @@ config MVPP2
config MVPP2X
tristate "Marvell Armada 375/70xx/80xx network interface support"
depends on ARCH_MVEBU
+ select MVGMAC
select MVMDIO
select MVXMDIO
select PHYLINK
diff --git a/drivers/net/ethernet/marvell/mvgmac.c b/drivers/net/ethernet/marvell/mvgmac.c
index 933c1c627b2d..aed5acdcac02 100644
--- a/drivers/net/ethernet/marvell/mvgmac.c
+++ b/drivers/net/ethernet/marvell/mvgmac.c
@@ -146,6 +146,8 @@ int mvgmac_configure(struct mvgmac *gmac, phy_interface_t phy_mode)
switch (phy_mode) {
case PHY_INTERFACE_MODE_QSGMII:
case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_2500BASEX:
ext_pin_gmii = false;
break;
diff --git a/drivers/net/ethernet/marvell/mvpp2x/mv_pp2x.h b/drivers/net/ethernet/marvell/mvpp2x/mv_pp2x.h
index eb3fe355ea31..c24f1ad22d40 100644
--- a/drivers/net/ethernet/marvell/mvpp2x/mv_pp2x.h
+++ b/drivers/net/ethernet/marvell/mvpp2x/mv_pp2x.h
@@ -28,6 +28,7 @@
#include "mv_pp2x_hw_type.h"
#include "mv_gop110_hw_type.h"
+#include "../mvgmac.h"
struct phylink;
@@ -590,6 +591,7 @@ struct mv_pp2x_port {
struct mv_pp2x *priv;
struct mv_mac_data mac_data;
+ struct mvgmac gmac;
struct tasklet_struct link_change_tasklet;
/* Per-port registers' base address */
diff --git a/drivers/net/ethernet/marvell/mvpp2x/mv_pp2x_main.c b/drivers/net/ethernet/marvell/mvpp2x/mv_pp2x_main.c
index 9dd4c87d7ebb..68f7970c3189 100644
--- a/drivers/net/ethernet/marvell/mvpp2x/mv_pp2x_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2x/mv_pp2x_main.c
@@ -52,6 +52,7 @@
#include "mv_pp2x.h"
#include "mv_pp2x_hw.h"
#include "mv_gop110_hw.h"
+#include "../mvgmac.h"
#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
#include <if_mv_pp2x_netmap.h>
@@ -1826,110 +1827,6 @@ static void mv_pp22_link_event(struct net_device *dev)
}
}
-
-static void mv_pp21_validate(struct net_device *dev, unsigned long *support,
- struct phylink_link_state *state)
-{
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-
- /* Allow all the expected bits */
- phylink_set(mask, Autoneg);
- phylink_set(mask, TP);
- phylink_set(mask, AUI);
- phylink_set(mask, MII);
- phylink_set(mask, FIBRE);
- phylink_set(mask, BNC);
- phylink_set(mask, Backplane);
-
- phylink_set(mask, Pause);
- phylink_set(mask, Asym_Pause);
-
- /* Half-duplex at speeds higher than 100Mbit are unsupported */
- phylink_set(mask, 1000baseT_Full);
- phylink_set(mask, 1000baseX_Full);
-
- if (!phy_interface_mode_is_8023z(state->interface)) {
- /* 10M and 100M are only supported in non-802.3z mode */
- phylink_set(mask, 10baseT_Half);
- phylink_set(mask, 10baseT_Full);
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
- }
-
- bitmap_and(support, support, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
-}
-
-static int mv_pp2_mac_link_state(struct net_device *dev,
- struct phylink_link_state *state)
-{
-// struct mv_pp2x_port *port = netdev_priv(dev);
- return 0;
-}
-
-static void mv_pp2_mac_an_restart(struct net_device *dev)
-{
-}
-
-static void mv_pp21_mac_config(struct net_device *dev, unsigned int mode,
- const struct phylink_link_state *state)
-{
- struct mv_pp2x_port *port = netdev_priv(dev);
- u32 new_an, an = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
-
- new_an = an & ~(MVPP2_GMAC_CONFIG_MII_SPEED |
- MVPP2_GMAC_CONFIG_GMII_SPEED |
- MVPP2_GMAC_AN_SPEED_EN |
- MVPP2_GMAC_CONFIG_FULL_DUPLEX |
- MVPP2_GMAC_AN_DUPLEX_EN);
-
- if (state->duplex)
- new_an |= MVPP2_GMAC_CONFIG_FULL_DUPLEX;
-
- if (state->speed == SPEED_1000)
- new_an |= MVPP2_GMAC_CONFIG_GMII_SPEED;
- else if (state->speed == SPEED_100)
- new_an |= MVPP2_GMAC_CONFIG_MII_SPEED;
-
- if (an != new_an)
- writel(new_an, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
-
- port->mac_data.speed = state->speed;
- port->mac_data.duplex = state->duplex;
-}
-
-static void mv_pp21_mac_link_down(struct net_device *dev, unsigned int mode)
-{
- struct mv_pp2x_port *port = netdev_priv(dev);
-
- port->mac_data.link = 0;
- mv_pp2x_ingress_disable(port);
- mv_pp2x_egress_disable(port);
-}
-
-static void mv_pp21_mac_link_up(struct net_device *dev, unsigned int mode,
- struct phy_device *phy)
-{
- struct mv_pp2x_port *port = netdev_priv(dev);
- u32 val;
-
- port->mac_data.link = 1;
- val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
- val |= (MVPP2_GMAC_FORCE_LINK_PASS | MVPP2_GMAC_FORCE_LINK_DOWN);
- writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
-
- mv_pp2x_egress_enable(port);
- mv_pp2x_ingress_enable(port);
-}
-
-static struct phylink_mac_ops mv_pp21_phylink_ops = {
- .validate = mv_pp21_validate,
- .mac_link_state = mv_pp2_mac_link_state,
- .mac_an_restart = mv_pp2_mac_an_restart,
- .mac_config = mv_pp21_mac_config,
- .mac_link_down = mv_pp21_mac_link_down,
- .mac_link_up = mv_pp21_mac_link_up,
-};
-
static void mv_pp22_validate(struct net_device *dev, unsigned long *supported,
struct phylink_link_state *state)
{
@@ -2045,79 +1942,7 @@ static void mv_pp22_mac_an_restart(struct net_device *dev)
{
struct mv_pp2x_port *port = netdev_priv(dev);
- mv_gop110_autoneg_restart(&port->priv->hw.gop, &port->mac_data);
-}
-
-static void mv_pp22_mac_config_gop(struct net_device *dev, unsigned int mode,
- const struct phylink_link_state *state)
-{
- struct mv_pp2x_port *port = netdev_priv(dev);
- struct gop_hw *gop = &port->priv->hw.gop;
- void __iomem *base = gop->gop_110.gmac.base +
- port->mac_data.gop_index * gop->gop_110.gmac.obj_size;
- u32 old_ctl0, ctl0;
- u32 old_ctl2, ctl2;
- u32 old_ctl4, ctl4;
- u32 old_an, an;
-
- port->mac_data.speed = state->speed;
- port->mac_data.duplex = state->duplex;
-
- old_ctl0 = readl(base + 0x00);
- old_ctl2 = readl(base + 0x08);
- old_ctl4 = readl(base + 0x90);
- old_an = readl(base + 0x0c);
-
- ctl0 = old_ctl0;
- ctl2 = old_ctl2;
- ctl4 = old_ctl4 & ~(BIT(3) | BIT(4));
- an = old_an & ~(BIT(5) | BIT(6) | BIT(7) | BIT(9) | BIT(10) | BIT(11));
-
- if (phylink_test(state->advertising, Pause))
- an |= BIT(9); /* ADV_PAUSE */
- if (phylink_test(state->advertising, Asym_Pause))
- an |= BIT(10); /* ADV_ASM_PAUSE */
-
- if (!phylink_autoneg_inband(mode)) {
- an = old_an;
- } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
- /* SGMII mode receives the state from the PHY */
- ctl0 = old_ctl0 & ~BIT(1);
- ctl2 = old_ctl2 | BIT(0); /* CTL2_SGMII_MODE */
- an |= BIT(7) | /* EN_AN_SPEED */
- BIT(13); /* EN_AN_FDX */
- /* SGMII FC is out of band */
- if (state->pause & MLO_PAUSE_TX)
- ctl4 |= BIT(4);
- if (state->pause & MLO_PAUSE_RX)
- ctl4 |= BIT(3);
- } else {
- /* 802.3z negotiation - only 1000base-X */
- ctl0 = old_ctl0 | BIT(1);
- ctl2 = old_ctl2 & ~BIT(0); /* CTRL2_SGMII_MODE */
- an |= BIT(6); /* SET_GMII_SPEED */
- if (state->pause & MLO_PAUSE_AN && state->an_enabled)
- an |= BIT(11); /* EN_FC_AN */
- }
-
- if ((old_ctl0 ^ ctl0) & BIT(1) ||
- (old_ctl2 ^ ctl2) & BIT(0)) {
- mv_gop110_port_disable(gop, &port->mac_data);
- writel(ctl0, base + 0x00);
- writel(ctl2, base + 0x08);
- writel(ctl4, base + 0x90);
- writel(an | 1, base + 0x0c);
- mv_gop110_port_enable(gop, &port->mac_data);
- } else {
- if (old_ctl0 != ctl0)
- writel(ctl0, base + 0x00);
- if (old_ctl2 != ctl2)
- writel(ctl2, base + 0x08);
- if (old_ctl4 != ctl4)
- writel(ctl4, base + 0x90);
- if (old_an != an)
- writel(an, base + 0x0c);
- }
+ mvgmac_an_restart(&port->gmac);
}
static void mv_pp22_mac_config(struct net_device *dev, unsigned int mode,
@@ -2129,11 +1954,14 @@ static void mv_pp22_mac_config(struct net_device *dev, unsigned int mode,
reconfig = mv_pp2x_reconfig_port(port, state->interface,
state->interface == PHY_INTERFACE_MODE_2500BASEX);
+ port->mac_data.speed = state->speed;
+ port->mac_data.duplex = state->duplex;
+
switch (port->mac_data.phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_QSGMII:
- mv_pp22_mac_config_gop(dev, mode, state);
+ mvgmac_config(&port->gmac, mode, state);
break;
default:
@@ -4891,6 +4719,9 @@ static int mv_pp2x_port_probe(struct platform_device *pdev,
port->mac_data.phy_mode = phy_mode;
port->mac_data.phy_node = phy_node;
emac_node = port_node;
+
+ port->gmac.base = port->base;
+ port->gmac.version = MVGMAC_PP21;
} else {
emac_node = of_parse_phandle(port_node, "emac-data", 0);
if (!emac_node) {
@@ -4903,21 +4734,24 @@ static int mv_pp2x_port_probe(struct platform_device *pdev,
if (err)
goto err_free_netdev;
+ port->gmac.base = priv->hw.gop.gop_110.gmac.base +
+ priv->hw.gop.gop_110.gmac.obj_size *
+ port->mac_data.gop_index;
+ port->gmac.version = MVGMAC_PP22;
+
comphy = devm_of_phy_get(&pdev->dev, emac_node, "comphy");
if (!IS_ERR(comphy))
port->comphy = comphy;
}
- if (port->mac_data.phy_mode == PHY_INTERFACE_MODE_SGMII ||
- port->mac_data.phy_mode == PHY_INTERFACE_MODE_10GKR) {
+ if (priv->pp2_version == PPV22 &&
+ (port->mac_data.phy_mode == PHY_INTERFACE_MODE_SGMII ||
+ port->mac_data.phy_mode == PHY_INTERFACE_MODE_10GKR)) {
struct phylink *pl;
const struct phylink_mac_ops *ops;
- if (port->priv->pp2_version == PPV21)
- ops = &mv_pp21_phylink_ops;
- else
- ops = &mv_pp22_phylink_ops;
+ ops = &mv_pp22_phylink_ops;
pl = phylink_create(dev, of_fwnode_handle(emac_node),
port->mac_data.phy_mode, ops);