Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: phy: mscc: Fix the VSC 8531/41 Chip Init sequence

- Turn on Broadcast writes
- UNH 1.8.1 clear bias for UNH 1000BT distortion
- UNH 1.8.7 optimize pre-emphasis for 100BasTx UNH 100W fix
- Enable Token-ring during 'Coma Mode'

Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Raju Lakkaraju and committed by
David S. Miller
7b98f63e 29d3c047

+54 -1
+54 -1
drivers/net/phy/mscc.c
··· 853 853 __phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr)); 854 854 } 855 855 856 + static int vsc8531_pre_init_seq_set(struct phy_device *phydev) 857 + { 858 + int rc; 859 + const struct reg_val init_seq[] = { 860 + {0x0f90, 0x00688980}, 861 + {0x0696, 0x00000003}, 862 + {0x07fa, 0x0050100f}, 863 + {0x1686, 0x00000004}, 864 + }; 865 + unsigned int i; 866 + int oldpage; 867 + 868 + rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD, 869 + MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN, 870 + SMI_BROADCAST_WR_EN); 871 + if (rc < 0) 872 + return rc; 873 + rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST, 874 + MSCC_PHY_TEST_PAGE_24, 0, 0x0400); 875 + if (rc < 0) 876 + return rc; 877 + rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST, 878 + MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00); 879 + if (rc < 0) 880 + return rc; 881 + rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST, 882 + MSCC_PHY_TEST_PAGE_8, 0x8000, 0x8000); 883 + if (rc < 0) 884 + return rc; 885 + 886 + mutex_lock(&phydev->lock); 887 + oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR); 888 + if (oldpage < 0) 889 + goto out_unlock; 890 + 891 + for (i = 0; i < ARRAY_SIZE(init_seq); i++) 892 + vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val); 893 + 894 + out_unlock: 895 + oldpage = phy_restore_page(phydev, oldpage, oldpage); 896 + mutex_unlock(&phydev->lock); 897 + 898 + return oldpage; 899 + } 900 + 856 901 static int vsc85xx_eee_init_seq_set(struct phy_device *phydev) 857 902 { 858 903 const struct reg_val init_eee[] = { ··· 1695 1650 1696 1651 static int vsc85xx_config_init(struct phy_device *phydev) 1697 1652 { 1698 - int rc, i; 1653 + int rc, i, phy_id; 1699 1654 struct vsc8531_private *vsc8531 = phydev->priv; 1700 1655 1701 1656 rc = vsc85xx_default_config(phydev); ··· 1709 1664 rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic); 1710 1665 if (rc) 1711 1666 return rc; 1667 + 1668 + phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask; 1669 + if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id || 1670 + PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) { 1671 + rc = vsc8531_pre_init_seq_set(phydev); 1672 + if (rc) 1673 + return rc; 1674 + } 1712 1675 1713 1676 rc = vsc85xx_eee_init_seq_set(phydev); 1714 1677 if (rc)