Skip to content

Commit 892e091

Browse files
oleremdavem330
authored andcommitted
net: ag71xx: port to phylink
The port to phylink was done as close as possible to initial functionality. Signed-off-by: Oleksij Rempel <[email protected]> Acked-by: Russell King <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b0251fb commit 892e091

File tree

2 files changed

+118
-72
lines changed

2 files changed

+118
-72
lines changed

drivers/net/ethernet/atheros/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ if NET_VENDOR_ATHEROS
2020
config AG71XX
2121
tristate "Atheros AR7XXX/AR9XXX built-in ethernet mac support"
2222
depends on ATH79
23-
select PHYLIB
23+
select PHYLINK
2424
help
2525
If you wish to compile a kernel for AR7XXX/91XXX and enable
2626
ethernet support, then you should always answer Y to this.

drivers/net/ethernet/atheros/ag71xx.c

Lines changed: 117 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <linux/of_mdio.h>
3333
#include <linux/of_net.h>
3434
#include <linux/of_platform.h>
35+
#include <linux/phylink.h>
3536
#include <linux/regmap.h>
3637
#include <linux/reset.h>
3738
#include <linux/clk.h>
@@ -314,6 +315,8 @@ struct ag71xx {
314315
dma_addr_t stop_desc_dma;
315316

316317
phy_interface_t phy_if_mode;
318+
struct phylink *phylink;
319+
struct phylink_config phylink_config;
317320

318321
struct delayed_work restart_work;
319322
struct timer_list oom_timer;
@@ -845,32 +848,99 @@ static void ag71xx_hw_start(struct ag71xx *ag)
845848
netif_wake_queue(ag->ndev);
846849
}
847850

848-
static void ag71xx_link_adjust(struct ag71xx *ag, bool update)
851+
static void ag71xx_mac_config(struct phylink_config *config, unsigned int mode,
852+
const struct phylink_link_state *state)
849853
{
850-
struct phy_device *phydev = ag->ndev->phydev;
851-
u32 cfg2;
852-
u32 ifctl;
853-
u32 fifo5;
854+
struct ag71xx *ag = netdev_priv(to_net_dev(config->dev));
854855

855-
if (!phydev->link && update) {
856-
ag71xx_hw_stop(ag);
856+
if (phylink_autoneg_inband(mode))
857857
return;
858-
}
859858

860859
if (!ag71xx_is(ag, AR7100) && !ag71xx_is(ag, AR9130))
861860
ag71xx_fast_reset(ag);
862861

862+
if (ag->tx_ring.desc_split) {
863+
ag->fifodata[2] &= 0xffff;
864+
ag->fifodata[2] |= ((2048 - ag->tx_ring.desc_split) / 4) << 16;
865+
}
866+
867+
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, ag->fifodata[2]);
868+
}
869+
870+
static void ag71xx_mac_validate(struct phylink_config *config,
871+
unsigned long *supported,
872+
struct phylink_link_state *state)
873+
{
874+
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
875+
876+
if (state->interface != PHY_INTERFACE_MODE_NA &&
877+
state->interface != PHY_INTERFACE_MODE_GMII &&
878+
state->interface != PHY_INTERFACE_MODE_MII) {
879+
bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
880+
return;
881+
}
882+
883+
phylink_set(mask, MII);
884+
885+
phylink_set(mask, Autoneg);
886+
phylink_set(mask, 10baseT_Half);
887+
phylink_set(mask, 10baseT_Full);
888+
phylink_set(mask, 100baseT_Half);
889+
phylink_set(mask, 100baseT_Full);
890+
891+
if (state->interface == PHY_INTERFACE_MODE_NA ||
892+
state->interface == PHY_INTERFACE_MODE_GMII) {
893+
phylink_set(mask, 1000baseT_Full);
894+
phylink_set(mask, 1000baseX_Full);
895+
}
896+
897+
bitmap_and(supported, supported, mask,
898+
__ETHTOOL_LINK_MODE_MASK_NBITS);
899+
bitmap_and(state->advertising, state->advertising, mask,
900+
__ETHTOOL_LINK_MODE_MASK_NBITS);
901+
}
902+
903+
static void ag71xx_mac_pcs_get_state(struct phylink_config *config,
904+
struct phylink_link_state *state)
905+
{
906+
state->link = 0;
907+
}
908+
909+
static void ag71xx_mac_an_restart(struct phylink_config *config)
910+
{
911+
/* Not Supported */
912+
}
913+
914+
static void ag71xx_mac_link_down(struct phylink_config *config,
915+
unsigned int mode, phy_interface_t interface)
916+
{
917+
struct ag71xx *ag = netdev_priv(to_net_dev(config->dev));
918+
919+
ag71xx_hw_stop(ag);
920+
}
921+
922+
static void ag71xx_mac_link_up(struct phylink_config *config,
923+
struct phy_device *phy,
924+
unsigned int mode, phy_interface_t interface,
925+
int speed, int duplex,
926+
bool tx_pause, bool rx_pause)
927+
{
928+
struct ag71xx *ag = netdev_priv(to_net_dev(config->dev));
929+
u32 cfg2;
930+
u32 ifctl;
931+
u32 fifo5;
932+
863933
cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);
864934
cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);
865-
cfg2 |= (phydev->duplex) ? MAC_CFG2_FDX : 0;
935+
cfg2 |= duplex ? MAC_CFG2_FDX : 0;
866936

867937
ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);
868938
ifctl &= ~(MAC_IFCTL_SPEED);
869939

870940
fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);
871941
fifo5 &= ~FIFO_CFG5_BM;
872942

873-
switch (phydev->speed) {
943+
switch (speed) {
874944
case SPEED_1000:
875945
cfg2 |= MAC_CFG2_IF_1000;
876946
fifo5 |= FIFO_CFG5_BM;
@@ -883,72 +953,38 @@ static void ag71xx_link_adjust(struct ag71xx *ag, bool update)
883953
cfg2 |= MAC_CFG2_IF_10_100;
884954
break;
885955
default:
886-
WARN(1, "not supported speed %i\n", phydev->speed);
887956
return;
888957
}
889958

890-
if (ag->tx_ring.desc_split) {
891-
ag->fifodata[2] &= 0xffff;
892-
ag->fifodata[2] |= ((2048 - ag->tx_ring.desc_split) / 4) << 16;
893-
}
894-
895-
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, ag->fifodata[2]);
896-
897959
ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
898960
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
899961
ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
900962

901963
ag71xx_hw_start(ag);
902-
903-
if (update)
904-
phy_print_status(phydev);
905964
}
906965

907-
static void ag71xx_phy_link_adjust(struct net_device *ndev)
908-
{
909-
struct ag71xx *ag = netdev_priv(ndev);
910-
911-
ag71xx_link_adjust(ag, true);
912-
}
966+
static const struct phylink_mac_ops ag71xx_phylink_mac_ops = {
967+
.validate = ag71xx_mac_validate,
968+
.mac_pcs_get_state = ag71xx_mac_pcs_get_state,
969+
.mac_an_restart = ag71xx_mac_an_restart,
970+
.mac_config = ag71xx_mac_config,
971+
.mac_link_down = ag71xx_mac_link_down,
972+
.mac_link_up = ag71xx_mac_link_up,
973+
};
913974

914-
static int ag71xx_phy_connect(struct ag71xx *ag)
975+
static int ag71xx_phylink_setup(struct ag71xx *ag)
915976
{
916-
struct device_node *np = ag->pdev->dev.of_node;
917-
struct net_device *ndev = ag->ndev;
918-
struct device_node *phy_node;
919-
struct phy_device *phydev;
920-
int ret;
921-
922-
if (of_phy_is_fixed_link(np)) {
923-
ret = of_phy_register_fixed_link(np);
924-
if (ret < 0) {
925-
netif_err(ag, probe, ndev, "Failed to register fixed PHY link: %d\n",
926-
ret);
927-
return ret;
928-
}
977+
struct phylink *phylink;
929978

930-
phy_node = of_node_get(np);
931-
} else {
932-
phy_node = of_parse_phandle(np, "phy-handle", 0);
933-
}
979+
ag->phylink_config.dev = &ag->ndev->dev;
980+
ag->phylink_config.type = PHYLINK_NETDEV;
934981

935-
if (!phy_node) {
936-
netif_err(ag, probe, ndev, "Could not find valid phy node\n");
937-
return -ENODEV;
938-
}
939-
940-
phydev = of_phy_connect(ag->ndev, phy_node, ag71xx_phy_link_adjust,
941-
0, ag->phy_if_mode);
942-
943-
of_node_put(phy_node);
944-
945-
if (!phydev) {
946-
netif_err(ag, probe, ndev, "Could not connect to PHY device\n");
947-
return -ENODEV;
948-
}
949-
950-
phy_attached_info(phydev);
982+
phylink = phylink_create(&ag->phylink_config, ag->pdev->dev.fwnode,
983+
ag->phy_if_mode, &ag71xx_phylink_mac_ops);
984+
if (IS_ERR(phylink))
985+
return PTR_ERR(phylink);
951986

987+
ag->phylink = phylink;
952988
return 0;
953989
}
954990

@@ -1239,6 +1275,13 @@ static int ag71xx_open(struct net_device *ndev)
12391275
unsigned int max_frame_len;
12401276
int ret;
12411277

1278+
ret = phylink_of_phy_connect(ag->phylink, ag->pdev->dev.of_node, 0);
1279+
if (ret) {
1280+
netif_err(ag, link, ndev, "phylink_of_phy_connect filed with err: %i\n",
1281+
ret);
1282+
goto err;
1283+
}
1284+
12421285
max_frame_len = ag71xx_max_frame_len(ndev->mtu);
12431286
ag->rx_buf_size =
12441287
SKB_DATA_ALIGN(max_frame_len + NET_SKB_PAD + NET_IP_ALIGN);
@@ -1251,11 +1294,7 @@ static int ag71xx_open(struct net_device *ndev)
12511294
if (ret)
12521295
goto err;
12531296

1254-
ret = ag71xx_phy_connect(ag);
1255-
if (ret)
1256-
goto err;
1257-
1258-
phy_start(ndev->phydev);
1297+
phylink_start(ag->phylink);
12591298

12601299
return 0;
12611300

@@ -1268,8 +1307,8 @@ static int ag71xx_stop(struct net_device *ndev)
12681307
{
12691308
struct ag71xx *ag = netdev_priv(ndev);
12701309

1271-
phy_stop(ndev->phydev);
1272-
phy_disconnect(ndev->phydev);
1310+
phylink_stop(ag->phylink);
1311+
phylink_disconnect_phy(ag->phylink);
12731312
ag71xx_hw_disable(ag);
12741313

12751314
return 0;
@@ -1414,13 +1453,14 @@ static void ag71xx_restart_work_func(struct work_struct *work)
14141453
{
14151454
struct ag71xx *ag = container_of(work, struct ag71xx,
14161455
restart_work.work);
1417-
struct net_device *ndev = ag->ndev;
14181456

14191457
rtnl_lock();
14201458
ag71xx_hw_disable(ag);
14211459
ag71xx_hw_enable(ag);
1422-
if (ndev->phydev->link)
1423-
ag71xx_link_adjust(ag, false);
1460+
1461+
phylink_stop(ag->phylink);
1462+
phylink_start(ag->phylink);
1463+
14241464
rtnl_unlock();
14251465
}
14261466

@@ -1759,6 +1799,12 @@ static int ag71xx_probe(struct platform_device *pdev)
17591799

17601800
platform_set_drvdata(pdev, ndev);
17611801

1802+
err = ag71xx_phylink_setup(ag);
1803+
if (err) {
1804+
netif_err(ag, probe, ndev, "failed to setup phylink (%d)\n", err);
1805+
goto err_mdio_remove;
1806+
}
1807+
17621808
err = register_netdev(ndev);
17631809
if (err) {
17641810
netif_err(ag, probe, ndev, "unable to register net device\n");

0 commit comments

Comments
 (0)