Skip to content

Commit

Permalink
staging: octeon-ethernet: fix incorrect PHY mode
Browse files Browse the repository at this point in the history
When connecting PHY, we set the mode to PHY_INTERFACE_MODE_GMII which is
not always correct. Specifically on boards where RGMII_RXID is needed
networking now longer works with at803x after commit 6d4cd04
("net: phy: at803x: disable delay only for RGMII mode").

Fix by passing the correct mode. Tested on EdgeRouter Lite
(RGMII_RXID, at803x PHY) and D-Link DSR-500N (RGMII, broadcom PHY).

Fixes: 6d4cd04 ("net: phy: at803x: disable delay only for RGMII mode")
Signed-off-by: Aaro Koskinen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
aakoskin authored and gregkh committed Mar 25, 2019
1 parent 9b9c87c commit 9498da4
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
2 changes: 1 addition & 1 deletion drivers/staging/octeon/ethernet-mdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
goto no_phy;

phydev = of_phy_connect(dev, phy_node, cvm_oct_adjust_link, 0,
PHY_INTERFACE_MODE_GMII);
priv->phy_mode);
of_node_put(phy_node);

if (!phydev)
Expand Down
40 changes: 35 additions & 5 deletions drivers/staging/octeon/ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,14 +653,37 @@ static struct device_node *cvm_oct_node_for_port(struct device_node *pip,
return np;
}

static void cvm_set_rgmii_delay(struct device_node *np, int iface, int port)
static void cvm_set_rgmii_delay(struct octeon_ethernet *priv, int iface,
int port)
{
struct device_node *np = priv->of_node;
u32 delay_value;
bool rx_delay;
bool tx_delay;

if (!of_property_read_u32(np, "rx-delay", &delay_value))
/* By default, both RX/TX delay is enabled in
* __cvmx_helper_rgmii_enable().
*/
rx_delay = true;
tx_delay = true;

if (!of_property_read_u32(np, "rx-delay", &delay_value)) {
cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, iface), delay_value);
if (!of_property_read_u32(np, "tx-delay", &delay_value))
rx_delay = delay_value > 0;
}
if (!of_property_read_u32(np, "tx-delay", &delay_value)) {
cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, iface), delay_value);
tx_delay = delay_value > 0;
}

if (!rx_delay && !tx_delay)
priv->phy_mode = PHY_INTERFACE_MODE_RGMII_ID;
else if (!rx_delay)
priv->phy_mode = PHY_INTERFACE_MODE_RGMII_RXID;
else if (!tx_delay)
priv->phy_mode = PHY_INTERFACE_MODE_RGMII_TXID;
else
priv->phy_mode = PHY_INTERFACE_MODE_RGMII;
}

static int cvm_oct_probe(struct platform_device *pdev)
Expand Down Expand Up @@ -825,6 +848,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
priv->port = port;
priv->queue = cvmx_pko_get_base_queue(priv->port);
priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
priv->phy_mode = PHY_INTERFACE_MODE_NA;
for (qos = 0; qos < 16; qos++)
skb_queue_head_init(&priv->tx_free_list[qos]);
for (qos = 0; qos < cvmx_pko_get_num_queues(port);
Expand Down Expand Up @@ -856,6 +880,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
break;

case CVMX_HELPER_INTERFACE_MODE_SGMII:
priv->phy_mode = PHY_INTERFACE_MODE_SGMII;
dev->netdev_ops = &cvm_oct_sgmii_netdev_ops;
strcpy(dev->name, "eth%d");
break;
Expand All @@ -865,11 +890,16 @@ static int cvm_oct_probe(struct platform_device *pdev)
strcpy(dev->name, "spi%d");
break;

case CVMX_HELPER_INTERFACE_MODE_RGMII:
case CVMX_HELPER_INTERFACE_MODE_GMII:
priv->phy_mode = PHY_INTERFACE_MODE_GMII;
dev->netdev_ops = &cvm_oct_rgmii_netdev_ops;
strcpy(dev->name, "eth%d");
break;

case CVMX_HELPER_INTERFACE_MODE_RGMII:
dev->netdev_ops = &cvm_oct_rgmii_netdev_ops;
strcpy(dev->name, "eth%d");
cvm_set_rgmii_delay(priv->of_node, interface,
cvm_set_rgmii_delay(priv, interface,
port_index);
break;
}
Expand Down
4 changes: 3 additions & 1 deletion drivers/staging/octeon/octeon-ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#define OCTEON_ETHERNET_H

#include <linux/of.h>

#include <linux/phy.h>
#include <asm/octeon/cvmx-helper-board.h>

/**
Expand All @@ -33,6 +33,8 @@ struct octeon_ethernet {
* cvmx_helper_interface_mode_t
*/
int imode;
/* PHY mode */
phy_interface_t phy_mode;
/* List of outstanding tx buffers per queue */
struct sk_buff_head tx_free_list[16];
unsigned int last_speed;
Expand Down

0 comments on commit 9498da4

Please sign in to comment.