mirror of
https://github.com/torvalds/linux.git
synced 2024-12-09 04:31:39 +00:00
Merge branch 'axienet-pcs-modernize'
Russell King says: ==================== net: axienet: modernise pcs implementation These two patches modernise the Xilinx axienet PCS implementation to use the phylink split PCS support. The first patch adds split PCS support and makes use of the newly introduced mac_select_pcs() function, which is the preferred way to conditionally attach a PCS. The second patch cleans up the use of mdiobus_write() since we now have bus accessors for mdio devices. There should be no functional change to the driver. This series was previously sent CFT on the 16th December (message ID Ybs1cdM3KUTsq4Vx@shell.armlinux.org.uk), and feedback addressed. CFT v2 sent 4th January (message ID YdQlI8gcVwg2sR+5@shell.armlinux.org.uk). ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
098db2f0ed
@ -386,6 +386,7 @@ struct axidma_bd {
|
||||
* @phylink: Pointer to phylink instance
|
||||
* @phylink_config: phylink configuration settings
|
||||
* @pcs_phy: Reference to PCS/PMA PHY if used
|
||||
* @pcs: phylink pcs structure for PCS PHY
|
||||
* @switch_x_sgmii: Whether switchable 1000BaseX/SGMII mode is enabled in the core
|
||||
* @axi_clk: AXI4-Lite bus clock
|
||||
* @misc_clks: Misc ethernet clocks (AXI4-Stream, Ref, MGT clocks)
|
||||
@ -434,6 +435,7 @@ struct axienet_local {
|
||||
struct phylink_config phylink_config;
|
||||
|
||||
struct mdio_device *pcs_phy;
|
||||
struct phylink_pcs pcs;
|
||||
|
||||
bool switch_x_sgmii;
|
||||
|
||||
|
@ -1537,78 +1537,78 @@ static const struct ethtool_ops axienet_ethtool_ops = {
|
||||
.nway_reset = axienet_ethtools_nway_reset,
|
||||
};
|
||||
|
||||
static void axienet_mac_pcs_get_state(struct phylink_config *config,
|
||||
struct phylink_link_state *state)
|
||||
static struct axienet_local *pcs_to_axienet_local(struct phylink_pcs *pcs)
|
||||
{
|
||||
struct net_device *ndev = to_net_dev(config->dev);
|
||||
struct axienet_local *lp = netdev_priv(ndev);
|
||||
|
||||
switch (state->interface) {
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
phylink_mii_c22_pcs_get_state(lp->pcs_phy, state);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return container_of(pcs, struct axienet_local, pcs);
|
||||
}
|
||||
|
||||
static void axienet_mac_an_restart(struct phylink_config *config)
|
||||
static void axienet_pcs_get_state(struct phylink_pcs *pcs,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
struct net_device *ndev = to_net_dev(config->dev);
|
||||
struct axienet_local *lp = netdev_priv(ndev);
|
||||
struct mdio_device *pcs_phy = pcs_to_axienet_local(pcs)->pcs_phy;
|
||||
|
||||
phylink_mii_c22_pcs_an_restart(lp->pcs_phy);
|
||||
phylink_mii_c22_pcs_get_state(pcs_phy, state);
|
||||
}
|
||||
|
||||
static int axienet_mac_prepare(struct phylink_config *config, unsigned int mode,
|
||||
phy_interface_t iface)
|
||||
static void axienet_pcs_an_restart(struct phylink_pcs *pcs)
|
||||
{
|
||||
struct net_device *ndev = to_net_dev(config->dev);
|
||||
struct mdio_device *pcs_phy = pcs_to_axienet_local(pcs)->pcs_phy;
|
||||
|
||||
phylink_mii_c22_pcs_an_restart(pcs_phy);
|
||||
}
|
||||
|
||||
static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
const unsigned long *advertising,
|
||||
bool permit_pause_to_mac)
|
||||
{
|
||||
struct mdio_device *pcs_phy = pcs_to_axienet_local(pcs)->pcs_phy;
|
||||
struct net_device *ndev = pcs_to_axienet_local(pcs)->ndev;
|
||||
struct axienet_local *lp = netdev_priv(ndev);
|
||||
int ret;
|
||||
|
||||
switch (iface) {
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
if (!lp->switch_x_sgmii)
|
||||
return 0;
|
||||
|
||||
ret = mdiobus_write(lp->pcs_phy->bus,
|
||||
lp->pcs_phy->addr,
|
||||
XLNX_MII_STD_SELECT_REG,
|
||||
iface == PHY_INTERFACE_MODE_SGMII ?
|
||||
if (lp->switch_x_sgmii) {
|
||||
ret = mdiodev_write(pcs_phy, XLNX_MII_STD_SELECT_REG,
|
||||
interface == PHY_INTERFACE_MODE_SGMII ?
|
||||
XLNX_MII_STD_SELECT_SGMII : 0);
|
||||
if (ret < 0)
|
||||
netdev_warn(ndev, "Failed to switch PHY interface: %d\n",
|
||||
if (ret < 0) {
|
||||
netdev_warn(ndev,
|
||||
"Failed to switch PHY interface: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
default:
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = phylink_mii_c22_pcs_config(pcs_phy, mode, interface, advertising);
|
||||
if (ret < 0)
|
||||
netdev_warn(ndev, "Failed to configure PCS: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct phylink_pcs_ops axienet_pcs_ops = {
|
||||
.pcs_get_state = axienet_pcs_get_state,
|
||||
.pcs_config = axienet_pcs_config,
|
||||
.pcs_an_restart = axienet_pcs_an_restart,
|
||||
};
|
||||
|
||||
static struct phylink_pcs *axienet_mac_select_pcs(struct phylink_config *config,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
struct net_device *ndev = to_net_dev(config->dev);
|
||||
struct axienet_local *lp = netdev_priv(ndev);
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_1000BASEX ||
|
||||
interface == PHY_INTERFACE_MODE_SGMII)
|
||||
return &lp->pcs;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void axienet_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
struct net_device *ndev = to_net_dev(config->dev);
|
||||
struct axienet_local *lp = netdev_priv(ndev);
|
||||
int ret;
|
||||
|
||||
switch (state->interface) {
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
ret = phylink_mii_c22_pcs_config(lp->pcs_phy, mode,
|
||||
state->interface,
|
||||
state->advertising);
|
||||
if (ret < 0)
|
||||
netdev_warn(ndev, "Failed to configure PCS: %d\n",
|
||||
ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* nothing meaningful to do */
|
||||
}
|
||||
|
||||
static void axienet_mac_link_down(struct phylink_config *config,
|
||||
@ -1663,9 +1663,7 @@ static void axienet_mac_link_up(struct phylink_config *config,
|
||||
|
||||
static const struct phylink_mac_ops axienet_phylink_ops = {
|
||||
.validate = phylink_generic_validate,
|
||||
.mac_pcs_get_state = axienet_mac_pcs_get_state,
|
||||
.mac_an_restart = axienet_mac_an_restart,
|
||||
.mac_prepare = axienet_mac_prepare,
|
||||
.mac_select_pcs = axienet_mac_select_pcs,
|
||||
.mac_config = axienet_mac_config,
|
||||
.mac_link_down = axienet_mac_link_down,
|
||||
.mac_link_up = axienet_mac_link_up,
|
||||
@ -2079,12 +2077,12 @@ static int axienet_probe(struct platform_device *pdev)
|
||||
ret = -EPROBE_DEFER;
|
||||
goto cleanup_mdio;
|
||||
}
|
||||
lp->phylink_config.pcs_poll = true;
|
||||
lp->pcs.ops = &axienet_pcs_ops;
|
||||
lp->pcs.poll = true;
|
||||
}
|
||||
|
||||
lp->phylink_config.dev = &ndev->dev;
|
||||
lp->phylink_config.type = PHYLINK_NETDEV;
|
||||
lp->phylink_config.legacy_pre_march2020 = true;
|
||||
lp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
|
||||
MAC_10FD | MAC_100FD | MAC_1000FD;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user