mirror of https://gitee.com/openkylin/linux.git
mscc.c: Add support for additional VSC PHYs
Add support for the following VSC PHYs VSC8504, VSC8552, VSC8572 VSC8562, VSC8564, VSC8575, VSC8582 Updates for v2: Checked for NULL on input to container_of Changed a large if else series to a switch statement. Added a WARN_ON to make sure lowest nibble of mask is 0 Signed-off-by: Bryan Whitehead <Bryan.Whitehead@microchip.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
945fe45759
commit
75a1ccfe6c
|
@ -252,13 +252,21 @@ enum rgmii_rx_clock_delay {
|
|||
#define MSCC_PHY_TR_LSB 17
|
||||
#define MSCC_PHY_TR_MSB 18
|
||||
|
||||
/* Microsemi PHY ID's */
|
||||
/* Microsemi PHY ID's
|
||||
* Code assumes lowest nibble is 0
|
||||
*/
|
||||
#define PHY_ID_VSC8504 0x000704c0
|
||||
#define PHY_ID_VSC8514 0x00070670
|
||||
#define PHY_ID_VSC8530 0x00070560
|
||||
#define PHY_ID_VSC8531 0x00070570
|
||||
#define PHY_ID_VSC8540 0x00070760
|
||||
#define PHY_ID_VSC8541 0x00070770
|
||||
#define PHY_ID_VSC8552 0x000704e0
|
||||
#define PHY_ID_VSC856X 0x000707e0
|
||||
#define PHY_ID_VSC8572 0x000704d0
|
||||
#define PHY_ID_VSC8574 0x000704a0
|
||||
#define PHY_ID_VSC8575 0x000707d0
|
||||
#define PHY_ID_VSC8582 0x000707b0
|
||||
#define PHY_ID_VSC8584 0x000707c0
|
||||
|
||||
#define MSCC_VDDMAC_1500 1500
|
||||
|
@ -1595,6 +1603,9 @@ static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed)
|
|||
else
|
||||
addr = vsc8531->base_addr + i;
|
||||
|
||||
if (!map[addr])
|
||||
continue;
|
||||
|
||||
phy = container_of(map[addr], struct phy_device, mdio);
|
||||
|
||||
if ((phy->phy_id & phydev->drv->phy_id_mask) !=
|
||||
|
@ -1647,14 +1658,29 @@ static int vsc8584_config_init(struct phy_device *phydev)
|
|||
* in this pre-init function.
|
||||
*/
|
||||
if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0)) {
|
||||
if ((phydev->phy_id & phydev->drv->phy_id_mask) ==
|
||||
(PHY_ID_VSC8574 & phydev->drv->phy_id_mask))
|
||||
/* The following switch statement assumes that the lowest
|
||||
* nibble of the phy_id_mask is always 0. This works because
|
||||
* the lowest nibble of the PHY_ID's below are also 0.
|
||||
*/
|
||||
WARN_ON(phydev->drv->phy_id_mask & 0xf);
|
||||
|
||||
switch (phydev->phy_id & phydev->drv->phy_id_mask) {
|
||||
case PHY_ID_VSC8504:
|
||||
case PHY_ID_VSC8552:
|
||||
case PHY_ID_VSC8572:
|
||||
case PHY_ID_VSC8574:
|
||||
ret = vsc8574_config_pre_init(phydev);
|
||||
else if ((phydev->phy_id & phydev->drv->phy_id_mask) ==
|
||||
(PHY_ID_VSC8584 & phydev->drv->phy_id_mask))
|
||||
break;
|
||||
case PHY_ID_VSC856X:
|
||||
case PHY_ID_VSC8575:
|
||||
case PHY_ID_VSC8582:
|
||||
case PHY_ID_VSC8584:
|
||||
ret = vsc8584_config_pre_init(phydev);
|
||||
else
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
};
|
||||
|
||||
if (ret)
|
||||
goto err;
|
||||
|
@ -2321,6 +2347,32 @@ static int vsc85xx_probe(struct phy_device *phydev)
|
|||
|
||||
/* Microsemi VSC85xx PHYs */
|
||||
static struct phy_driver vsc85xx_driver[] = {
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8504,
|
||||
.name = "Microsemi GE VSC8504 SyncE",
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
/* PHY_GBIT_FEATURES */
|
||||
.soft_reset = &genphy_soft_reset,
|
||||
.config_init = &vsc8584_config_init,
|
||||
.config_aneg = &vsc85xx_config_aneg,
|
||||
.aneg_done = &genphy_aneg_done,
|
||||
.read_status = &vsc85xx_read_status,
|
||||
.ack_interrupt = &vsc85xx_ack_interrupt,
|
||||
.config_intr = &vsc85xx_config_intr,
|
||||
.did_interrupt = &vsc8584_did_interrupt,
|
||||
.suspend = &genphy_suspend,
|
||||
.resume = &genphy_resume,
|
||||
.probe = &vsc8574_probe,
|
||||
.set_wol = &vsc85xx_wol_set,
|
||||
.get_wol = &vsc85xx_wol_get,
|
||||
.get_tunable = &vsc85xx_get_tunable,
|
||||
.set_tunable = &vsc85xx_set_tunable,
|
||||
.read_page = &vsc85xx_phy_read_page,
|
||||
.write_page = &vsc85xx_phy_write_page,
|
||||
.get_sset_count = &vsc85xx_get_sset_count,
|
||||
.get_strings = &vsc85xx_get_strings,
|
||||
.get_stats = &vsc85xx_get_stats,
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8514,
|
||||
.name = "Microsemi GE VSC8514 SyncE",
|
||||
|
@ -2444,6 +2496,82 @@ static struct phy_driver vsc85xx_driver[] = {
|
|||
.get_strings = &vsc85xx_get_strings,
|
||||
.get_stats = &vsc85xx_get_stats,
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8552,
|
||||
.name = "Microsemi GE VSC8552 SyncE",
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
/* PHY_GBIT_FEATURES */
|
||||
.soft_reset = &genphy_soft_reset,
|
||||
.config_init = &vsc8584_config_init,
|
||||
.config_aneg = &vsc85xx_config_aneg,
|
||||
.aneg_done = &genphy_aneg_done,
|
||||
.read_status = &vsc85xx_read_status,
|
||||
.ack_interrupt = &vsc85xx_ack_interrupt,
|
||||
.config_intr = &vsc85xx_config_intr,
|
||||
.did_interrupt = &vsc8584_did_interrupt,
|
||||
.suspend = &genphy_suspend,
|
||||
.resume = &genphy_resume,
|
||||
.probe = &vsc8574_probe,
|
||||
.set_wol = &vsc85xx_wol_set,
|
||||
.get_wol = &vsc85xx_wol_get,
|
||||
.get_tunable = &vsc85xx_get_tunable,
|
||||
.set_tunable = &vsc85xx_set_tunable,
|
||||
.read_page = &vsc85xx_phy_read_page,
|
||||
.write_page = &vsc85xx_phy_write_page,
|
||||
.get_sset_count = &vsc85xx_get_sset_count,
|
||||
.get_strings = &vsc85xx_get_strings,
|
||||
.get_stats = &vsc85xx_get_stats,
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_VSC856X,
|
||||
.name = "Microsemi GE VSC856X SyncE",
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
/* PHY_GBIT_FEATURES */
|
||||
.soft_reset = &genphy_soft_reset,
|
||||
.config_init = &vsc8584_config_init,
|
||||
.config_aneg = &vsc85xx_config_aneg,
|
||||
.aneg_done = &genphy_aneg_done,
|
||||
.read_status = &vsc85xx_read_status,
|
||||
.ack_interrupt = &vsc85xx_ack_interrupt,
|
||||
.config_intr = &vsc85xx_config_intr,
|
||||
.did_interrupt = &vsc8584_did_interrupt,
|
||||
.suspend = &genphy_suspend,
|
||||
.resume = &genphy_resume,
|
||||
.probe = &vsc8584_probe,
|
||||
.get_tunable = &vsc85xx_get_tunable,
|
||||
.set_tunable = &vsc85xx_set_tunable,
|
||||
.read_page = &vsc85xx_phy_read_page,
|
||||
.write_page = &vsc85xx_phy_write_page,
|
||||
.get_sset_count = &vsc85xx_get_sset_count,
|
||||
.get_strings = &vsc85xx_get_strings,
|
||||
.get_stats = &vsc85xx_get_stats,
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8572,
|
||||
.name = "Microsemi GE VSC8572 SyncE",
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
/* PHY_GBIT_FEATURES */
|
||||
.soft_reset = &genphy_soft_reset,
|
||||
.config_init = &vsc8584_config_init,
|
||||
.config_aneg = &vsc85xx_config_aneg,
|
||||
.aneg_done = &genphy_aneg_done,
|
||||
.read_status = &vsc85xx_read_status,
|
||||
.ack_interrupt = &vsc85xx_ack_interrupt,
|
||||
.config_intr = &vsc85xx_config_intr,
|
||||
.did_interrupt = &vsc8584_did_interrupt,
|
||||
.suspend = &genphy_suspend,
|
||||
.resume = &genphy_resume,
|
||||
.probe = &vsc8574_probe,
|
||||
.set_wol = &vsc85xx_wol_set,
|
||||
.get_wol = &vsc85xx_wol_get,
|
||||
.get_tunable = &vsc85xx_get_tunable,
|
||||
.set_tunable = &vsc85xx_set_tunable,
|
||||
.read_page = &vsc85xx_phy_read_page,
|
||||
.write_page = &vsc85xx_phy_write_page,
|
||||
.get_sset_count = &vsc85xx_get_sset_count,
|
||||
.get_strings = &vsc85xx_get_strings,
|
||||
.get_stats = &vsc85xx_get_stats,
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8574,
|
||||
.name = "Microsemi GE VSC8574 SyncE",
|
||||
|
@ -2470,6 +2598,54 @@ static struct phy_driver vsc85xx_driver[] = {
|
|||
.get_strings = &vsc85xx_get_strings,
|
||||
.get_stats = &vsc85xx_get_stats,
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8575,
|
||||
.name = "Microsemi GE VSC8575 SyncE",
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
/* PHY_GBIT_FEATURES */
|
||||
.soft_reset = &genphy_soft_reset,
|
||||
.config_init = &vsc8584_config_init,
|
||||
.config_aneg = &vsc85xx_config_aneg,
|
||||
.aneg_done = &genphy_aneg_done,
|
||||
.read_status = &vsc85xx_read_status,
|
||||
.ack_interrupt = &vsc85xx_ack_interrupt,
|
||||
.config_intr = &vsc85xx_config_intr,
|
||||
.did_interrupt = &vsc8584_did_interrupt,
|
||||
.suspend = &genphy_suspend,
|
||||
.resume = &genphy_resume,
|
||||
.probe = &vsc8584_probe,
|
||||
.get_tunable = &vsc85xx_get_tunable,
|
||||
.set_tunable = &vsc85xx_set_tunable,
|
||||
.read_page = &vsc85xx_phy_read_page,
|
||||
.write_page = &vsc85xx_phy_write_page,
|
||||
.get_sset_count = &vsc85xx_get_sset_count,
|
||||
.get_strings = &vsc85xx_get_strings,
|
||||
.get_stats = &vsc85xx_get_stats,
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8582,
|
||||
.name = "Microsemi GE VSC8582 SyncE",
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
/* PHY_GBIT_FEATURES */
|
||||
.soft_reset = &genphy_soft_reset,
|
||||
.config_init = &vsc8584_config_init,
|
||||
.config_aneg = &vsc85xx_config_aneg,
|
||||
.aneg_done = &genphy_aneg_done,
|
||||
.read_status = &vsc85xx_read_status,
|
||||
.ack_interrupt = &vsc85xx_ack_interrupt,
|
||||
.config_intr = &vsc85xx_config_intr,
|
||||
.did_interrupt = &vsc8584_did_interrupt,
|
||||
.suspend = &genphy_suspend,
|
||||
.resume = &genphy_resume,
|
||||
.probe = &vsc8584_probe,
|
||||
.get_tunable = &vsc85xx_get_tunable,
|
||||
.set_tunable = &vsc85xx_set_tunable,
|
||||
.read_page = &vsc85xx_phy_read_page,
|
||||
.write_page = &vsc85xx_phy_write_page,
|
||||
.get_sset_count = &vsc85xx_get_sset_count,
|
||||
.get_strings = &vsc85xx_get_strings,
|
||||
.get_stats = &vsc85xx_get_stats,
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8584,
|
||||
.name = "Microsemi GE VSC8584 SyncE",
|
||||
|
@ -2500,12 +2676,18 @@ static struct phy_driver vsc85xx_driver[] = {
|
|||
module_phy_driver(vsc85xx_driver);
|
||||
|
||||
static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
|
||||
{ PHY_ID_VSC8504, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8514, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8530, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8531, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8540, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8541, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8552, 0xfffffff0, },
|
||||
{ PHY_ID_VSC856X, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8572, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8574, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8575, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8582, 0xfffffff0, },
|
||||
{ PHY_ID_VSC8584, 0xfffffff0, },
|
||||
{ }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue