Skip to content

Commit 64e09d0

Browse files
committed
Merge branch 'rswitch-SERDES-PHY-init'
Yoshihiro Shimoda says: ==================== net: renesas: rswitch: Modify initialization for SERDES and PHY - My platform has the 88x2110. - The MACTYPE setting of strap pin on the platform is SXGMII. - However, we realized that the SoC cannot communicate the PHY with SXGMII because of mismatching hardware specification. - We have a lot of boards which mismatch the MACTYPE setting. So, I would like to change the MACTYPE as SGMII by software for the platform. The patch [1/5] sets phydev->host_interfaces by phylink for Marvell PHY driver (marvell10g) to initialize the MACTYPE. - The patch [1/5] siplifies the rswitch driver. - The patch [2/5] converts to phy_device from phylink. - The patch [3/5] sets phydev->host_interfaces from this driver without any new functions of phylib. - The patch [4/5] adds phy_power_on() calling to initialize the Ethernet SERDES PHY driver (r8a779f0-eth-serdes) for each channel. - The patch [5/5] adds "max-speed" handling. Changes from v4: https://lore.kernel.org/all/20230127142621.1761278-1-yoshihiro.shimoda.uh@renesas.com/ - No modification of phylink API. - Convert to phylib instead of phylink. - Add "max-speed" handling. Changes from v3: https://lore.kernel.org/all/20230127014812.1656340-1-yoshihiro.shimoda.uh@renesas.com/ - Keep a pointer of "port" and more simplify the code. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 2798e36 + 04c77d9 commit 64e09d0

File tree

2 files changed

+111
-124
lines changed

2 files changed

+111
-124
lines changed

drivers/net/ethernet/renesas/rswitch.c

Lines changed: 109 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <linux/of_irq.h>
1717
#include <linux/of_mdio.h>
1818
#include <linux/of_net.h>
19-
#include <linux/phylink.h>
2019
#include <linux/phy/phy.h>
2120
#include <linux/pm_runtime.h>
2221
#include <linux/rtnetlink.h>
@@ -1071,33 +1070,25 @@ static struct device_node *rswitch_get_port_node(struct rswitch_device *rdev)
10711070
return port;
10721071
}
10731072

1074-
/* Call of_node_put(mdio) after done */
1075-
static struct device_node *rswitch_get_mdio_node(struct rswitch_device *rdev)
1076-
{
1077-
struct device_node *port, *mdio;
1078-
1079-
port = rswitch_get_port_node(rdev);
1080-
if (!port)
1081-
return NULL;
1082-
1083-
mdio = of_get_child_by_name(port, "mdio");
1084-
of_node_put(port);
1085-
1086-
return mdio;
1087-
}
1088-
10891073
static int rswitch_etha_get_params(struct rswitch_device *rdev)
10901074
{
1091-
struct device_node *port;
1075+
u32 max_speed;
10921076
int err;
10931077

1094-
port = rswitch_get_port_node(rdev);
1095-
if (!port)
1078+
if (!rdev->np_port)
10961079
return 0; /* ignored */
10971080

1098-
err = of_get_phy_mode(port, &rdev->etha->phy_interface);
1099-
of_node_put(port);
1081+
err = of_get_phy_mode(rdev->np_port, &rdev->etha->phy_interface);
1082+
if (err)
1083+
return err;
11001084

1085+
err = of_property_read_u32(rdev->np_port, "max-speed", &max_speed);
1086+
if (!err) {
1087+
rdev->etha->speed = max_speed;
1088+
return 0;
1089+
}
1090+
1091+
/* if no "max-speed" property, let's use default speed */
11011092
switch (rdev->etha->phy_interface) {
11021093
case PHY_INTERFACE_MODE_MII:
11031094
rdev->etha->speed = SPEED_100;
@@ -1109,11 +1100,10 @@ static int rswitch_etha_get_params(struct rswitch_device *rdev)
11091100
rdev->etha->speed = SPEED_2500;
11101101
break;
11111102
default:
1112-
err = -EINVAL;
1113-
break;
1103+
return -EINVAL;
11141104
}
11151105

1116-
return err;
1106+
return 0;
11171107
}
11181108

11191109
static int rswitch_mii_register(struct rswitch_device *rdev)
@@ -1133,7 +1123,7 @@ static int rswitch_mii_register(struct rswitch_device *rdev)
11331123
mii_bus->write_c45 = rswitch_etha_mii_write_c45;
11341124
mii_bus->parent = &rdev->priv->pdev->dev;
11351125

1136-
mdio_np = rswitch_get_mdio_node(rdev);
1126+
mdio_np = of_get_child_by_name(rdev->np_port, "mdio");
11371127
err = of_mdiobus_register(mii_bus, mdio_np);
11381128
if (err < 0) {
11391129
mdiobus_free(mii_bus);
@@ -1157,114 +1147,107 @@ static void rswitch_mii_unregister(struct rswitch_device *rdev)
11571147
}
11581148
}
11591149

1160-
static void rswitch_mac_config(struct phylink_config *config,
1161-
unsigned int mode,
1162-
const struct phylink_link_state *state)
1150+
static void rswitch_adjust_link(struct net_device *ndev)
11631151
{
1164-
}
1152+
struct rswitch_device *rdev = netdev_priv(ndev);
1153+
struct phy_device *phydev = ndev->phydev;
11651154

1166-
static void rswitch_mac_link_down(struct phylink_config *config,
1167-
unsigned int mode,
1168-
phy_interface_t interface)
1169-
{
1155+
/* Current hardware has a restriction not to change speed at runtime */
1156+
if (phydev->link != rdev->etha->link) {
1157+
phy_print_status(phydev);
1158+
if (phydev->link)
1159+
phy_power_on(rdev->serdes);
1160+
else
1161+
phy_power_off(rdev->serdes);
1162+
1163+
rdev->etha->link = phydev->link;
1164+
}
11701165
}
11711166

1172-
static void rswitch_mac_link_up(struct phylink_config *config,
1173-
struct phy_device *phydev, unsigned int mode,
1174-
phy_interface_t interface, int speed,
1175-
int duplex, bool tx_pause, bool rx_pause)
1167+
static void rswitch_phy_remove_link_mode(struct rswitch_device *rdev,
1168+
struct phy_device *phydev)
11761169
{
1177-
/* Current hardware cannot change speed at runtime */
1178-
}
1170+
/* Current hardware has a restriction not to change speed at runtime */
1171+
switch (rdev->etha->speed) {
1172+
case SPEED_2500:
1173+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Full_BIT);
1174+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT);
1175+
break;
1176+
case SPEED_1000:
1177+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
1178+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT);
1179+
break;
1180+
case SPEED_100:
1181+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
1182+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Full_BIT);
1183+
break;
1184+
default:
1185+
break;
1186+
}
11791187

1180-
static const struct phylink_mac_ops rswitch_phylink_ops = {
1181-
.mac_config = rswitch_mac_config,
1182-
.mac_link_down = rswitch_mac_link_down,
1183-
.mac_link_up = rswitch_mac_link_up,
1184-
};
1188+
phy_set_max_speed(phydev, rdev->etha->speed);
1189+
}
11851190

1186-
static int rswitch_phylink_init(struct rswitch_device *rdev)
1191+
static int rswitch_phy_device_init(struct rswitch_device *rdev)
11871192
{
1188-
struct device_node *port;
1189-
struct phylink *phylink;
1190-
int err;
1193+
struct phy_device *phydev;
1194+
struct device_node *phy;
1195+
int err = -ENOENT;
11911196

1192-
port = rswitch_get_port_node(rdev);
1193-
if (!port)
1197+
if (!rdev->np_port)
11941198
return -ENODEV;
11951199

1196-
rdev->phylink_config.dev = &rdev->ndev->dev;
1197-
rdev->phylink_config.type = PHYLINK_NETDEV;
1198-
__set_bit(PHY_INTERFACE_MODE_SGMII, rdev->phylink_config.supported_interfaces);
1199-
__set_bit(PHY_INTERFACE_MODE_USXGMII, rdev->phylink_config.supported_interfaces);
1200-
rdev->phylink_config.mac_capabilities = MAC_100FD | MAC_1000FD | MAC_2500FD;
1200+
phy = of_parse_phandle(rdev->np_port, "phy-handle", 0);
1201+
if (!phy)
1202+
return -ENODEV;
12011203

1202-
phylink = phylink_create(&rdev->phylink_config, &port->fwnode,
1203-
rdev->etha->phy_interface, &rswitch_phylink_ops);
1204-
if (IS_ERR(phylink)) {
1205-
err = PTR_ERR(phylink);
1204+
/* Set phydev->host_interfaces before calling of_phy_connect() to
1205+
* configure the PHY with the information of host_interfaces.
1206+
*/
1207+
phydev = of_phy_find_device(phy);
1208+
if (!phydev)
12061209
goto out;
1207-
}
1210+
__set_bit(rdev->etha->phy_interface, phydev->host_interfaces);
12081211

1209-
rdev->phylink = phylink;
1210-
err = phylink_of_phy_connect(rdev->phylink, port, rdev->etha->phy_interface);
1212+
phydev = of_phy_connect(rdev->ndev, phy, rswitch_adjust_link, 0,
1213+
rdev->etha->phy_interface);
1214+
if (!phydev)
1215+
goto out;
1216+
1217+
phy_set_max_speed(phydev, SPEED_2500);
1218+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
1219+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
1220+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
1221+
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
1222+
rswitch_phy_remove_link_mode(rdev, phydev);
1223+
1224+
phy_attached_info(phydev);
1225+
1226+
err = 0;
12111227
out:
1212-
of_node_put(port);
1228+
of_node_put(phy);
12131229

12141230
return err;
12151231
}
12161232

1217-
static void rswitch_phylink_deinit(struct rswitch_device *rdev)
1233+
static void rswitch_phy_device_deinit(struct rswitch_device *rdev)
12181234
{
1219-
rtnl_lock();
1220-
phylink_disconnect_phy(rdev->phylink);
1221-
rtnl_unlock();
1222-
phylink_destroy(rdev->phylink);
1235+
if (rdev->ndev->phydev) {
1236+
phy_disconnect(rdev->ndev->phydev);
1237+
rdev->ndev->phydev = NULL;
1238+
}
12231239
}
12241240

12251241
static int rswitch_serdes_set_params(struct rswitch_device *rdev)
12261242
{
1227-
struct device_node *port = rswitch_get_port_node(rdev);
1228-
struct phy *serdes;
12291243
int err;
12301244

1231-
serdes = devm_of_phy_get(&rdev->priv->pdev->dev, port, NULL);
1232-
of_node_put(port);
1233-
if (IS_ERR(serdes))
1234-
return PTR_ERR(serdes);
1235-
1236-
err = phy_set_mode_ext(serdes, PHY_MODE_ETHERNET,
1245+
err = phy_set_mode_ext(rdev->serdes, PHY_MODE_ETHERNET,
12371246
rdev->etha->phy_interface);
12381247
if (err < 0)
12391248
return err;
12401249

1241-
return phy_set_speed(serdes, rdev->etha->speed);
1242-
}
1243-
1244-
static int rswitch_serdes_init(struct rswitch_device *rdev)
1245-
{
1246-
struct device_node *port = rswitch_get_port_node(rdev);
1247-
struct phy *serdes;
1248-
1249-
serdes = devm_of_phy_get(&rdev->priv->pdev->dev, port, NULL);
1250-
of_node_put(port);
1251-
if (IS_ERR(serdes))
1252-
return PTR_ERR(serdes);
1253-
1254-
return phy_init(serdes);
1255-
}
1256-
1257-
static int rswitch_serdes_deinit(struct rswitch_device *rdev)
1258-
{
1259-
struct device_node *port = rswitch_get_port_node(rdev);
1260-
struct phy *serdes;
1261-
1262-
serdes = devm_of_phy_get(&rdev->priv->pdev->dev, port, NULL);
1263-
of_node_put(port);
1264-
if (IS_ERR(serdes))
1265-
return PTR_ERR(serdes);
1266-
1267-
return phy_exit(serdes);
1250+
return phy_set_speed(rdev->serdes, rdev->etha->speed);
12681251
}
12691252

12701253
static int rswitch_ether_port_init_one(struct rswitch_device *rdev)
@@ -1282,9 +1265,15 @@ static int rswitch_ether_port_init_one(struct rswitch_device *rdev)
12821265
if (err < 0)
12831266
return err;
12841267

1285-
err = rswitch_phylink_init(rdev);
1268+
err = rswitch_phy_device_init(rdev);
12861269
if (err < 0)
1287-
goto err_phylink_init;
1270+
goto err_phy_device_init;
1271+
1272+
rdev->serdes = devm_of_phy_get(&rdev->priv->pdev->dev, rdev->np_port, NULL);
1273+
if (IS_ERR(rdev->serdes)) {
1274+
err = PTR_ERR(rdev->serdes);
1275+
goto err_serdes_phy_get;
1276+
}
12881277

12891278
err = rswitch_serdes_set_params(rdev);
12901279
if (err < 0)
@@ -1293,17 +1282,18 @@ static int rswitch_ether_port_init_one(struct rswitch_device *rdev)
12931282
return 0;
12941283

12951284
err_serdes_set_params:
1296-
rswitch_phylink_deinit(rdev);
1285+
err_serdes_phy_get:
1286+
rswitch_phy_device_deinit(rdev);
12971287

1298-
err_phylink_init:
1288+
err_phy_device_init:
12991289
rswitch_mii_unregister(rdev);
13001290

13011291
return err;
13021292
}
13031293

13041294
static void rswitch_ether_port_deinit_one(struct rswitch_device *rdev)
13051295
{
1306-
rswitch_phylink_deinit(rdev);
1296+
rswitch_phy_device_deinit(rdev);
13071297
rswitch_mii_unregister(rdev);
13081298
}
13091299

@@ -1318,7 +1308,7 @@ static int rswitch_ether_port_init_all(struct rswitch_private *priv)
13181308
}
13191309

13201310
rswitch_for_each_enabled_port(priv, i) {
1321-
err = rswitch_serdes_init(priv->rdev[i]);
1311+
err = phy_init(priv->rdev[i]->serdes);
13221312
if (err)
13231313
goto err_serdes;
13241314
}
@@ -1327,7 +1317,7 @@ static int rswitch_ether_port_init_all(struct rswitch_private *priv)
13271317

13281318
err_serdes:
13291319
rswitch_for_each_enabled_port_continue_reverse(priv, i)
1330-
rswitch_serdes_deinit(priv->rdev[i]);
1320+
phy_exit(priv->rdev[i]->serdes);
13311321
i = RSWITCH_NUM_PORTS;
13321322

13331323
err_init_one:
@@ -1342,7 +1332,7 @@ static void rswitch_ether_port_deinit_all(struct rswitch_private *priv)
13421332
int i;
13431333

13441334
for (i = 0; i < RSWITCH_NUM_PORTS; i++) {
1345-
rswitch_serdes_deinit(priv->rdev[i]);
1335+
phy_exit(priv->rdev[i]->serdes);
13461336
rswitch_ether_port_deinit_one(priv->rdev[i]);
13471337
}
13481338
}
@@ -1351,7 +1341,7 @@ static int rswitch_open(struct net_device *ndev)
13511341
{
13521342
struct rswitch_device *rdev = netdev_priv(ndev);
13531343

1354-
phylink_start(rdev->phylink);
1344+
phy_start(ndev->phydev);
13551345

13561346
napi_enable(&rdev->napi);
13571347
netif_start_queue(ndev);
@@ -1371,7 +1361,7 @@ static int rswitch_stop(struct net_device *ndev)
13711361
rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, false);
13721362
rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, false);
13731363

1374-
phylink_stop(rdev->phylink);
1364+
phy_stop(ndev->phydev);
13751365
napi_disable(&rdev->napi);
13761366

13771367
return 0;
@@ -1499,8 +1489,6 @@ static int rswitch_hwstamp_set(struct net_device *ndev, struct ifreq *req)
14991489

15001490
static int rswitch_eth_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
15011491
{
1502-
struct rswitch_device *rdev = netdev_priv(ndev);
1503-
15041492
if (!netif_running(ndev))
15051493
return -EINVAL;
15061494

@@ -1510,7 +1498,7 @@ static int rswitch_eth_ioctl(struct net_device *ndev, struct ifreq *req, int cmd
15101498
case SIOCSHWTSTAMP:
15111499
return rswitch_hwstamp_set(ndev, req);
15121500
default:
1513-
return phylink_mii_ioctl(rdev->phylink, req, cmd);
1501+
return phy_mii_ioctl(ndev->phydev, req, cmd);
15141502
}
15151503
}
15161504

@@ -1565,7 +1553,6 @@ static int rswitch_device_alloc(struct rswitch_private *priv, int index)
15651553
{
15661554
struct platform_device *pdev = priv->pdev;
15671555
struct rswitch_device *rdev;
1568-
struct device_node *port;
15691556
struct net_device *ndev;
15701557
int err;
15711558

@@ -1594,10 +1581,10 @@ static int rswitch_device_alloc(struct rswitch_private *priv, int index)
15941581

15951582
netif_napi_add(ndev, &rdev->napi, rswitch_poll);
15961583

1597-
port = rswitch_get_port_node(rdev);
1598-
rdev->disabled = !port;
1599-
err = of_get_ethdev_address(port, ndev);
1600-
of_node_put(port);
1584+
rdev->np_port = rswitch_get_port_node(rdev);
1585+
rdev->disabled = !rdev->np_port;
1586+
err = of_get_ethdev_address(rdev->np_port, ndev);
1587+
of_node_put(rdev->np_port);
16011588
if (err) {
16021589
if (is_valid_ether_addr(rdev->etha->mac_addr))
16031590
eth_hw_addr_set(ndev, rdev->etha->mac_addr);
@@ -1798,7 +1785,7 @@ static void rswitch_deinit(struct rswitch_private *priv)
17981785
for (i = 0; i < RSWITCH_NUM_PORTS; i++) {
17991786
struct rswitch_device *rdev = priv->rdev[i];
18001787

1801-
rswitch_serdes_deinit(rdev);
1788+
phy_exit(priv->rdev[i]->serdes);
18021789
rswitch_ether_port_deinit_one(rdev);
18031790
unregister_netdev(rdev->ndev);
18041791
rswitch_device_free(priv, i);

0 commit comments

Comments
 (0)