net: dsa: lantiq: allow to use all GPHYs on xRX300 and xRX330
This patch allows to use all PHYs on GRX300 and GRX330. The ARX300 has 3 and the GRX330 has 4 integrated PHYs connected to different ports compared to VRX200. Each integrated PHY can work as single Gigabit Ethernet PHY (GMII) or as double Fast Ethernet PHY (MII). Allowed port configurations: xRX200: GMAC0: RGMII, MII, REVMII or RMII port GMAC1: RGMII, MII, REVMII or RMII port GMAC2: GPHY0 (GMII) GMAC3: GPHY0 (MII) GMAC4: GPHY1 (GMII) GMAC5: GPHY1 (MII) or RGMII port xRX300: GMAC0: RGMII port GMAC1: GPHY2 (GMII) GMAC2: GPHY0 (GMII) GMAC3: GPHY0 (MII) GMAC4: GPHY1 (GMII) GMAC5: GPHY1 (MII) or RGMII port xRX330: GMAC0: RGMII, GMII or RMII port GMAC1: GPHY2 (GMII) GMAC2: GPHY0 (GMII) GMAC3: GPHY0 (MII) or GPHY3 (GMII) GMAC4: GPHY1 (GMII) GMAC5: GPHY1 (MII), RGMII or RMII port Tested on D-Link DWR966 (xRX330) with OpenWRT. Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl> Acked-by: Hauke Mehrtens <hauke@hauke-m.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
853b0df952
commit
a09d042b08
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Lantiq / Intel GSWIP switch driver for VRX200 SoCs
|
||||
* Lantiq / Intel GSWIP switch driver for VRX200, xRX300 and xRX330 SoCs
|
||||
*
|
||||
* Copyright (C) 2010 Lantiq Deutschland
|
||||
* Copyright (C) 2012 John Crispin <john@phrozen.org>
|
||||
@ -100,6 +100,7 @@
|
||||
#define GSWIP_MII_CFG_MODE_RMIIP 0x2
|
||||
#define GSWIP_MII_CFG_MODE_RMIIM 0x3
|
||||
#define GSWIP_MII_CFG_MODE_RGMII 0x4
|
||||
#define GSWIP_MII_CFG_MODE_GMII 0x9
|
||||
#define GSWIP_MII_CFG_MODE_MASK 0xf
|
||||
#define GSWIP_MII_CFG_RATE_M2P5 0x00
|
||||
#define GSWIP_MII_CFG_RATE_M25 0x10
|
||||
@ -220,6 +221,7 @@
|
||||
struct gswip_hw_info {
|
||||
int max_ports;
|
||||
int cpu_port;
|
||||
const struct dsa_switch_ops *ops;
|
||||
};
|
||||
|
||||
struct xway_gphy_match_data {
|
||||
@ -1384,38 +1386,11 @@ static int gswip_port_fdb_dump(struct dsa_switch *ds, int port,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gswip_phylink_validate(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
static void gswip_phylink_set_capab(unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||
|
||||
switch (port) {
|
||||
case 0:
|
||||
case 1:
|
||||
if (!phy_interface_mode_is_rgmii(state->interface) &&
|
||||
state->interface != PHY_INTERFACE_MODE_MII &&
|
||||
state->interface != PHY_INTERFACE_MODE_REVMII &&
|
||||
state->interface != PHY_INTERFACE_MODE_RMII)
|
||||
goto unsupported;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
goto unsupported;
|
||||
break;
|
||||
case 5:
|
||||
if (!phy_interface_mode_is_rgmii(state->interface) &&
|
||||
state->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
goto unsupported;
|
||||
break;
|
||||
default:
|
||||
bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||
dev_err(ds->dev, "Unsupported port: %i\n", port);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allow all the expected bits */
|
||||
phylink_set(mask, Autoneg);
|
||||
phylink_set_port_modes(mask);
|
||||
@ -1441,13 +1416,86 @@ static void gswip_phylink_validate(struct dsa_switch *ds, int port,
|
||||
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||
bitmap_and(state->advertising, state->advertising, mask,
|
||||
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||
}
|
||||
|
||||
static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
switch (port) {
|
||||
case 0:
|
||||
case 1:
|
||||
if (!phy_interface_mode_is_rgmii(state->interface) &&
|
||||
state->interface != PHY_INTERFACE_MODE_MII &&
|
||||
state->interface != PHY_INTERFACE_MODE_REVMII &&
|
||||
state->interface != PHY_INTERFACE_MODE_RMII)
|
||||
goto unsupported;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
goto unsupported;
|
||||
break;
|
||||
case 5:
|
||||
if (!phy_interface_mode_is_rgmii(state->interface) &&
|
||||
state->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
goto unsupported;
|
||||
break;
|
||||
default:
|
||||
bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||
dev_err(ds->dev, "Unsupported port: %i\n", port);
|
||||
return;
|
||||
}
|
||||
|
||||
gswip_phylink_set_capab(supported, state);
|
||||
|
||||
return;
|
||||
|
||||
unsupported:
|
||||
bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||
dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
|
||||
phy_modes(state->interface), port);
|
||||
}
|
||||
|
||||
static void gswip_xrx300_phylink_validate(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
switch (port) {
|
||||
case 0:
|
||||
if (!phy_interface_mode_is_rgmii(state->interface) &&
|
||||
state->interface != PHY_INTERFACE_MODE_GMII &&
|
||||
state->interface != PHY_INTERFACE_MODE_RMII)
|
||||
goto unsupported;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
goto unsupported;
|
||||
break;
|
||||
case 5:
|
||||
if (!phy_interface_mode_is_rgmii(state->interface) &&
|
||||
state->interface != PHY_INTERFACE_MODE_INTERNAL &&
|
||||
state->interface != PHY_INTERFACE_MODE_RMII)
|
||||
goto unsupported;
|
||||
break;
|
||||
default:
|
||||
bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||
dev_err(ds->dev, "Unsupported port: %i\n", port);
|
||||
return;
|
||||
}
|
||||
|
||||
gswip_phylink_set_capab(supported, state);
|
||||
|
||||
return;
|
||||
|
||||
unsupported:
|
||||
bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||
dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
|
||||
phy_modes(state->interface), port);
|
||||
}
|
||||
|
||||
static void gswip_phylink_mac_config(struct dsa_switch *ds, int port,
|
||||
@ -1476,6 +1524,9 @@ static void gswip_phylink_mac_config(struct dsa_switch *ds, int port,
|
||||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
miicfg |= GSWIP_MII_CFG_MODE_RGMII;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_GMII:
|
||||
miicfg |= GSWIP_MII_CFG_MODE_GMII;
|
||||
break;
|
||||
default:
|
||||
dev_err(ds->dev,
|
||||
"Unsupported interface: %d\n", state->interface);
|
||||
@ -1588,7 +1639,7 @@ static int gswip_get_sset_count(struct dsa_switch *ds, int port, int sset)
|
||||
return ARRAY_SIZE(gswip_rmon_cnt);
|
||||
}
|
||||
|
||||
static const struct dsa_switch_ops gswip_switch_ops = {
|
||||
static const struct dsa_switch_ops gswip_xrx200_switch_ops = {
|
||||
.get_tag_protocol = gswip_get_tag_protocol,
|
||||
.setup = gswip_setup,
|
||||
.port_enable = gswip_port_enable,
|
||||
@ -1603,7 +1654,31 @@ static const struct dsa_switch_ops gswip_switch_ops = {
|
||||
.port_fdb_add = gswip_port_fdb_add,
|
||||
.port_fdb_del = gswip_port_fdb_del,
|
||||
.port_fdb_dump = gswip_port_fdb_dump,
|
||||
.phylink_validate = gswip_phylink_validate,
|
||||
.phylink_validate = gswip_xrx200_phylink_validate,
|
||||
.phylink_mac_config = gswip_phylink_mac_config,
|
||||
.phylink_mac_link_down = gswip_phylink_mac_link_down,
|
||||
.phylink_mac_link_up = gswip_phylink_mac_link_up,
|
||||
.get_strings = gswip_get_strings,
|
||||
.get_ethtool_stats = gswip_get_ethtool_stats,
|
||||
.get_sset_count = gswip_get_sset_count,
|
||||
};
|
||||
|
||||
static const struct dsa_switch_ops gswip_xrx300_switch_ops = {
|
||||
.get_tag_protocol = gswip_get_tag_protocol,
|
||||
.setup = gswip_setup,
|
||||
.port_enable = gswip_port_enable,
|
||||
.port_disable = gswip_port_disable,
|
||||
.port_bridge_join = gswip_port_bridge_join,
|
||||
.port_bridge_leave = gswip_port_bridge_leave,
|
||||
.port_fast_age = gswip_port_fast_age,
|
||||
.port_vlan_filtering = gswip_port_vlan_filtering,
|
||||
.port_vlan_add = gswip_port_vlan_add,
|
||||
.port_vlan_del = gswip_port_vlan_del,
|
||||
.port_stp_state_set = gswip_port_stp_state_set,
|
||||
.port_fdb_add = gswip_port_fdb_add,
|
||||
.port_fdb_del = gswip_port_fdb_del,
|
||||
.port_fdb_dump = gswip_port_fdb_dump,
|
||||
.phylink_validate = gswip_xrx300_phylink_validate,
|
||||
.phylink_mac_config = gswip_phylink_mac_config,
|
||||
.phylink_mac_link_down = gswip_phylink_mac_link_down,
|
||||
.phylink_mac_link_up = gswip_phylink_mac_link_up,
|
||||
@ -1865,7 +1940,7 @@ static int gswip_probe(struct platform_device *pdev)
|
||||
priv->ds->dev = dev;
|
||||
priv->ds->num_ports = priv->hw_info->max_ports;
|
||||
priv->ds->priv = priv;
|
||||
priv->ds->ops = &gswip_switch_ops;
|
||||
priv->ds->ops = priv->hw_info->ops;
|
||||
priv->dev = dev;
|
||||
version = gswip_switch_r(priv, GSWIP_VERSION);
|
||||
|
||||
@ -1946,10 +2021,19 @@ static int gswip_remove(struct platform_device *pdev)
|
||||
static const struct gswip_hw_info gswip_xrx200 = {
|
||||
.max_ports = 7,
|
||||
.cpu_port = 6,
|
||||
.ops = &gswip_xrx200_switch_ops,
|
||||
};
|
||||
|
||||
static const struct gswip_hw_info gswip_xrx300 = {
|
||||
.max_ports = 7,
|
||||
.cpu_port = 6,
|
||||
.ops = &gswip_xrx300_switch_ops,
|
||||
};
|
||||
|
||||
static const struct of_device_id gswip_of_match[] = {
|
||||
{ .compatible = "lantiq,xrx200-gswip", .data = &gswip_xrx200 },
|
||||
{ .compatible = "lantiq,xrx300-gswip", .data = &gswip_xrx300 },
|
||||
{ .compatible = "lantiq,xrx330-gswip", .data = &gswip_xrx300 },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, gswip_of_match);
|
||||
|
Loading…
Reference in New Issue
Block a user