Commit 84f29264 authored by David S. Miller's avatar David S. Miller

Merge branch 'net-phy-marvell10g-Add-2-5GBaseT-support'

Maxime Chevallier says:

====================
net: phy: marvell10g: Add 2.5GBaseT support

This series adds the missing bits necessary to fully support 2.5GBaseT
in the Marvell Alaska PHYs.

The main points for that support are :

 - Making use of the .get_features call, recently introduced by Heiner
   and Andrew, that allows having a fully populated list of supported
   modes, including 2500BaseT.

 - Configuring the MII to 2500BaseX when establishing a link at 2.5G

 - Adding a small quirk to take into account the fact that some PHYs in
   the family won't report the correct supported abilities

The rest of the series consists of small cosmetic improvements such as
using the correct helper to set a linkmode bit and adding macros for the
PHY ids.

We also add support for the 88E2110 PHY, which doesn't require the
quirk, and support for 2500BaseT in the PPv2 driver, in order to have a
fully working setup on the MacchiatoBin board.

Changes since V1 : Fixed formatting issue in patch 01, rebased.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c1164bb1 62d01535
......@@ -4403,6 +4403,7 @@ static void mvpp2_phylink_validate(struct net_device *dev,
case PHY_INTERFACE_MODE_2500BASEX:
phylink_set(mask, 1000baseT_Full);
phylink_set(mask, 1000baseX_Full);
phylink_set(mask, 2500baseT_Full);
phylink_set(mask, 2500baseX_Full);
break;
default:
......
......@@ -27,6 +27,9 @@
#include <linux/marvell_phy.h>
#include <linux/phy.h>
#define MV_PHY_ALASKA_NBT_QUIRK_MASK 0xfffffffe
#define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
enum {
MV_PCS_BASE_T = 0x0000,
MV_PCS_BASE_R = 0x1000,
......@@ -231,31 +234,69 @@ static int mv3310_resume(struct phy_device *phydev)
return mv3310_hwmon_config(phydev, true);
}
static int mv3310_config_init(struct phy_device *phydev)
/* Some PHYs in the Alaska family such as the 88X3310 and the 88E2010
* don't set bit 14 in PMA Extended Abilities (1.11), although they do
* support 2.5GBASET and 5GBASET. For these models, we can still read their
* 2.5G/5G extended abilities register (1.21). We detect these models based on
* the PMA device identifier, with a mask matching models known to have this
* issue
*/
static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev)
{
int ret, val;
if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_PMAPMD))
return false;
/* Only some revisions of the 88X3310 family PMA seem to be impacted */
return (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
}
static int mv3310_config_init(struct phy_device *phydev)
{
/* Check that the PHY interface type is compatible */
if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
phydev->interface != PHY_INTERFACE_MODE_XAUI &&
phydev->interface != PHY_INTERFACE_MODE_RXAUI &&
phydev->interface != PHY_INTERFACE_MODE_10GKR)
return -ENODEV;
return 0;
}
static int mv3310_get_features(struct phy_device *phydev)
{
int ret, val;
if (phydev->c45_ids.devices_in_package & MDIO_DEVS_AN) {
val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
if (val < 0)
return val;
if (val & MDIO_AN_STAT1_ABLE)
__set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
phydev->supported);
linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
phydev->supported);
}
ret = genphy_c45_pma_read_abilities(phydev);
if (ret)
return ret;
if (mv3310_has_pma_ngbaset_quirk(phydev)) {
val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
MDIO_PMA_NG_EXTABLE);
if (val < 0)
return val;
linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
phydev->supported,
val & MDIO_PMA_NG_EXTABLE_2_5GBT);
linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
phydev->supported,
val & MDIO_PMA_NG_EXTABLE_5GBT);
}
return 0;
}
......@@ -308,18 +349,29 @@ static int mv3310_aneg_done(struct phy_device *phydev)
static void mv3310_update_interface(struct phy_device *phydev)
{
if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
phydev->interface == PHY_INTERFACE_MODE_10GKR) && phydev->link) {
/* The PHY automatically switches its serdes interface (and
* active PHYXS instance) between Cisco SGMII and 10GBase-KR
* modes according to the speed. Florian suggests setting
* phydev->interface to communicate this to the MAC. Only do
* this if we are already in either SGMII or 10GBase-KR mode.
* active PHYXS instance) between Cisco SGMII, 10GBase-KR and
* 2500BaseX modes according to the speed. Florian suggests
* setting phydev->interface to communicate this to the MAC.
* Only do this if we are already in one of the above modes.
*/
if (phydev->speed == SPEED_10000)
switch (phydev->speed) {
case SPEED_10000:
phydev->interface = PHY_INTERFACE_MODE_10GKR;
else if (phydev->speed >= SPEED_10 &&
phydev->speed < SPEED_10000)
break;
case SPEED_2500:
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
break;
case SPEED_1000:
case SPEED_100:
case SPEED_10:
phydev->interface = PHY_INTERFACE_MODE_SGMII;
break;
default:
break;
}
}
}
......@@ -413,10 +465,10 @@ static int mv3310_read_status(struct phy_device *phydev)
static struct phy_driver mv3310_drivers[] = {
{
.phy_id = 0x002b09aa,
.phy_id = MARVELL_PHY_ID_88X3310,
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "mv88x3310",
.features = PHY_10GBIT_FEATURES,
.get_features = mv3310_get_features,
.soft_reset = gen10g_no_soft_reset,
.config_init = mv3310_config_init,
.probe = mv3310_probe,
......@@ -426,12 +478,25 @@ static struct phy_driver mv3310_drivers[] = {
.aneg_done = mv3310_aneg_done,
.read_status = mv3310_read_status,
},
{
.phy_id = MARVELL_PHY_ID_88E2110,
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "mv88x2110",
.features = PHY_10GBIT_FEATURES,
.probe = mv3310_probe,
.soft_reset = gen10g_no_soft_reset,
.config_init = mv3310_config_init,
.config_aneg = mv3310_config_aneg,
.aneg_done = mv3310_aneg_done,
.read_status = mv3310_read_status,
},
};
module_phy_driver(mv3310_drivers);
static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
{ 0x002b09aa, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
{ },
};
MODULE_DEVICE_TABLE(mdio, mv3310_tbl);
......
......@@ -20,6 +20,8 @@
#define MARVELL_PHY_ID_88E1540 0x01410eb0
#define MARVELL_PHY_ID_88E1545 0x01410ea0
#define MARVELL_PHY_ID_88E3016 0x01410e60
#define MARVELL_PHY_ID_88X3310 0x002b09a0
#define MARVELL_PHY_ID_88E2110 0x002b09b0
/* The MV88e6390 Ethernet switch contains embedded PHYs. These PHYs do
* not have a model ID. So the switch driver traps reads to the ID2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment