Skip to content

Commit

Permalink
Merge branch 'dsa-port-config'
Browse files Browse the repository at this point in the history
Andrew Lunn says:

====================
DSA port configuration and status

This patchset allows various switch port settings to be configured and
port status to be sampled. Some of these patches have been posted
before.

The first three patches provide infrastructure for configuring a
switch ports link speed and duplex from a fixed_link phy.

Patch four then uses this infrastructure to allow the CPU and DSA
ports of a switch to be configured using a fixed-link property in the
device tree.

Patches five and six allow a phy-mode property to be specified in the
device tree, and allow this to be used for configuring RGMII delays.

Patches seven through nine allow link status, for example that of an
SFP module, to be read from a gpio.

Changes since v1:

Rewrite 9/9 so that it hopefully does not regression on
868a421 ("net: phy: fixed_phy: handle link-down case")
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Aug 31, 2015
2 parents 6ea3c9d + bc0f4a8 commit 684511a
Show file tree
Hide file tree
Showing 17 changed files with 255 additions and 39 deletions.
14 changes: 13 additions & 1 deletion Documentation/devicetree/bindings/net/fixed-link.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ properties:
enabled.
* 'asym-pause' (boolean, optional), to indicate that asym_pause should
be enabled.
* 'link-gpios' ('gpio-list', optional), to indicate if a gpio can be read
to determine if the link is up.

Old, deprecated 'fixed-link' binding:

Expand All @@ -30,7 +32,7 @@ Old, deprecated 'fixed-link' binding:
- e: asymmetric pause configuration: 0 for no asymmetric pause, 1 for
asymmetric pause

Example:
Examples:

ethernet@0 {
...
Expand All @@ -40,3 +42,13 @@ ethernet@0 {
};
...
};

ethernet@1 {
...
fixed-link {
speed = <1000>;
pause;
link-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
...
};
2 changes: 1 addition & 1 deletion Documentation/networking/stmmac.txt
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ static struct fixed_phy_status stmmac0_fixed_phy_status = {

During the board's device_init we can configure the first
MAC for fixed_link by calling:
fixed_phy_add(PHY_POLL, 1, &stmmac0_fixed_phy_status));)
fixed_phy_add(PHY_POLL, 1, &stmmac0_fixed_phy_status, -1);
and the second one, with a real PHY device attached to the bus,
by using the stmmac_mdio_bus_data structure (to provide the id, the
reset procedure etc).
Expand Down
2 changes: 1 addition & 1 deletion arch/m68k/coldfire/m5272.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ static struct fixed_phy_status nettel_fixed_phy_status __initdata = {
static int __init init_BSP(void)
{
m5272_uarts_init();
fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status);
fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status, -1);
return 0;
}

Expand Down
5 changes: 3 additions & 2 deletions arch/mips/ar7/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,8 @@ static int __init ar7_register_devices(void)
}

if (ar7_has_high_cpmac()) {
res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
res = fixed_phy_add(PHY_POLL, cpmac_high.id,
&fixed_phy_status, -1);
if (!res) {
cpmac_get_mac(1, cpmac_high_data.dev_addr);

Expand All @@ -692,7 +693,7 @@ static int __init ar7_register_devices(void)
} else
cpmac_low_data.phy_mask = 0xffffffff;

res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status);
res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status, -1);
if (!res) {
cpmac_get_mac(0, cpmac_low_data.dev_addr);
res = platform_device_register(&cpmac_low);
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/bcm47xx/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ static int __init bcm47xx_register_bus_complete(void)
bcm47xx_leds_register();
bcm47xx_workarounds();

fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status, -1);
return 0;
}
device_initcall(bcm47xx_register_bus_complete);
1 change: 1 addition & 0 deletions drivers/net/dsa/mv88e6123_61_65.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
.adjust_link = mv88e6xxx_adjust_link,
#ifdef CONFIG_NET_DSA_HWMON
.get_temp = mv88e6xxx_get_temp,
#endif
Expand Down
1 change: 1 addition & 0 deletions drivers/net/dsa/mv88e6131.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
.adjust_link = mv88e6xxx_adjust_link,
};

MODULE_ALIAS("platform:mv88e6085");
Expand Down
1 change: 1 addition & 0 deletions drivers/net/dsa/mv88e6171.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
.adjust_link = mv88e6xxx_adjust_link,
#ifdef CONFIG_NET_DSA_HWMON
.get_temp = mv88e6xxx_get_temp,
#endif
Expand Down
1 change: 1 addition & 0 deletions drivers/net/dsa/mv88e6352.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
.adjust_link = mv88e6xxx_adjust_link,
.set_eee = mv88e6xxx_set_eee,
.get_eee = mv88e6xxx_get_eee,
#ifdef CONFIG_NET_DSA_HWMON
Expand Down
73 changes: 73 additions & 0 deletions drivers/net/dsa/mv88e6xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if_bridge.h>
#include <linux/jiffies.h>
#include <linux/list.h>
Expand Down Expand Up @@ -394,6 +395,7 @@ void mv88e6xxx_poll_link(struct dsa_switch *ds)
for (i = 0; i < DSA_MAX_PORTS; i++) {
struct net_device *dev;
int uninitialized_var(port_status);
int pcs_ctrl;
int link;
int speed;
int duplex;
Expand All @@ -403,6 +405,10 @@ void mv88e6xxx_poll_link(struct dsa_switch *ds)
if (dev == NULL)
continue;

pcs_ctrl = mv88e6xxx_reg_read(ds, REG_PORT(i), PORT_PCS_CTRL);
if (pcs_ctrl < 0 || pcs_ctrl & PORT_PCS_CTRL_FORCE_LINK)
continue;

link = 0;
if (dev->flags & IFF_UP) {
port_status = mv88e6xxx_reg_read(ds, REG_PORT(i),
Expand Down Expand Up @@ -560,6 +566,73 @@ static bool mv88e6xxx_6352_family(struct dsa_switch *ds)
return false;
}

/* We expect the switch to perform auto negotiation if there is a real
* phy. However, in the case of a fixed link phy, we force the port
* settings from the fixed link settings.
*/
void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
struct phy_device *phydev)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
u32 ret, reg;

if (!phy_is_pseudo_fixed_link(phydev))
return;

mutex_lock(&ps->smi_mutex);

ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_PCS_CTRL);
if (ret < 0)
goto out;

reg = ret & ~(PORT_PCS_CTRL_LINK_UP |
PORT_PCS_CTRL_FORCE_LINK |
PORT_PCS_CTRL_DUPLEX_FULL |
PORT_PCS_CTRL_FORCE_DUPLEX |
PORT_PCS_CTRL_UNFORCED);

reg |= PORT_PCS_CTRL_FORCE_LINK;
if (phydev->link)
reg |= PORT_PCS_CTRL_LINK_UP;

if (mv88e6xxx_6065_family(ds) && phydev->speed > SPEED_100)
goto out;

switch (phydev->speed) {
case SPEED_1000:
reg |= PORT_PCS_CTRL_1000;
break;
case SPEED_100:
reg |= PORT_PCS_CTRL_100;
break;
case SPEED_10:
reg |= PORT_PCS_CTRL_10;
break;
default:
pr_info("Unknown speed");
goto out;
}

reg |= PORT_PCS_CTRL_FORCE_DUPLEX;
if (phydev->duplex == DUPLEX_FULL)
reg |= PORT_PCS_CTRL_DUPLEX_FULL;

if ((mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds)) &&
(port >= ps->num_ports - 2)) {
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
reg |= PORT_PCS_CTRL_RGMII_DELAY_TXCLK;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
reg |= (PORT_PCS_CTRL_RGMII_DELAY_RXCLK |
PORT_PCS_CTRL_RGMII_DELAY_TXCLK);
}
_mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_PCS_CTRL, reg);

out:
mutex_unlock(&ps->smi_mutex);
}

/* Must be called with SMI mutex held */
static int _mv88e6xxx_stats_wait(struct dsa_switch *ds)
{
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/dsa/mv88e6xxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
#define PORT_STATUS_TX_PAUSED BIT(5)
#define PORT_STATUS_FLOW_CTRL BIT(4)
#define PORT_PCS_CTRL 0x01
#define PORT_PCS_CTRL_RGMII_DELAY_RXCLK BIT(15)
#define PORT_PCS_CTRL_RGMII_DELAY_TXCLK BIT(14)
#define PORT_PCS_CTRL_FC BIT(7)
#define PORT_PCS_CTRL_FORCE_FC BIT(6)
#define PORT_PCS_CTRL_LINK_UP BIT(5)
Expand Down Expand Up @@ -446,6 +448,8 @@ void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
uint64_t *data);
int mv88e6xxx_get_sset_count(struct dsa_switch *ds);
int mv88e6xxx_get_sset_count_basic(struct dsa_switch *ds);
void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
struct phy_device *phydev);
int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port);
void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
struct ethtool_regs *regs, void *_p);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/broadcom/genet/bcmmii.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
.asym_pause = 0,
};

phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL);
phydev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
if (!phydev || IS_ERR(phydev)) {
dev_err(kdev, "failed to register fixed PHY device\n");
return -ENODEV;
Expand Down
Loading

0 comments on commit 684511a

Please sign in to comment.