1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Marvell 88Q2XXX automotive 100BASE-T1/1000BASE-T1 PHY driver 4 */ 5 #include <linux/ethtool_netlink.h> 6 #include <linux/marvell_phy.h> 7 #include <linux/phy.h> 8 9 #define MDIO_MMD_AN_MV_STAT 32769 10 #define MDIO_MMD_AN_MV_STAT_ANEG 0x0100 11 #define MDIO_MMD_AN_MV_STAT_LOCAL_RX 0x1000 12 #define MDIO_MMD_AN_MV_STAT_REMOTE_RX 0x2000 13 #define MDIO_MMD_AN_MV_STAT_LOCAL_MASTER 0x4000 14 #define MDIO_MMD_AN_MV_STAT_MS_CONF_FAULT 0x8000 15 16 #define MDIO_MMD_PCS_MV_100BT1_STAT1 33032 17 #define MDIO_MMD_PCS_MV_100BT1_STAT1_IDLE_ERROR 0x00FF 18 #define MDIO_MMD_PCS_MV_100BT1_STAT1_JABBER 0x0100 19 #define MDIO_MMD_PCS_MV_100BT1_STAT1_LINK 0x0200 20 #define MDIO_MMD_PCS_MV_100BT1_STAT1_LOCAL_RX 0x1000 21 #define MDIO_MMD_PCS_MV_100BT1_STAT1_REMOTE_RX 0x2000 22 #define MDIO_MMD_PCS_MV_100BT1_STAT1_LOCAL_MASTER 0x4000 23 24 #define MDIO_MMD_PCS_MV_100BT1_STAT2 33033 25 #define MDIO_MMD_PCS_MV_100BT1_STAT2_JABBER 0x0001 26 #define MDIO_MMD_PCS_MV_100BT1_STAT2_POL 0x0002 27 #define MDIO_MMD_PCS_MV_100BT1_STAT2_LINK 0x0004 28 #define MDIO_MMD_PCS_MV_100BT1_STAT2_ANGE 0x0008 29 30 static int mv88q2xxx_soft_reset(struct phy_device *phydev) 31 { 32 int ret; 33 int val; 34 35 ret = phy_write_mmd(phydev, MDIO_MMD_PCS, 36 MDIO_PCS_1000BT1_CTRL, MDIO_PCS_1000BT1_CTRL_RESET); 37 if (ret < 0) 38 return ret; 39 40 return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PCS, 41 MDIO_PCS_1000BT1_CTRL, val, 42 !(val & MDIO_PCS_1000BT1_CTRL_RESET), 43 50000, 600000, true); 44 } 45 46 static int mv88q2xxx_read_link_gbit(struct phy_device *phydev) 47 { 48 int ret; 49 bool link = false; 50 51 /* Read vendor specific Auto-Negotiation status register to get local 52 * and remote receiver status according to software initialization 53 * guide. 54 */ 55 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_MMD_AN_MV_STAT); 56 if (ret < 0) { 57 return ret; 58 } else if ((ret & MDIO_MMD_AN_MV_STAT_LOCAL_RX) && 59 (ret & MDIO_MMD_AN_MV_STAT_REMOTE_RX)) { 60 /* The link state is latched low so that momentary link 61 * drops can be detected. Do not double-read the status 62 * in polling mode to detect such short link drops except 63 * the link was already down. 64 */ 65 if (!phy_polling_mode(phydev) || !phydev->link) { 66 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_1000BT1_STAT); 67 if (ret < 0) 68 return ret; 69 else if (ret & MDIO_PCS_1000BT1_STAT_LINK) 70 link = true; 71 } 72 73 if (!link) { 74 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_1000BT1_STAT); 75 if (ret < 0) 76 return ret; 77 else if (ret & MDIO_PCS_1000BT1_STAT_LINK) 78 link = true; 79 } 80 } 81 82 phydev->link = link; 83 84 return 0; 85 } 86 87 static int mv88q2xxx_read_link_100m(struct phy_device *phydev) 88 { 89 int ret; 90 91 /* The link state is latched low so that momentary link 92 * drops can be detected. Do not double-read the status 93 * in polling mode to detect such short link drops except 94 * the link was already down. In case we are not polling, 95 * we always read the realtime status. 96 */ 97 if (!phy_polling_mode(phydev) || !phydev->link) { 98 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_100BT1_STAT1); 99 if (ret < 0) 100 return ret; 101 else if (ret & MDIO_MMD_PCS_MV_100BT1_STAT1_LINK) 102 goto out; 103 } 104 105 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_100BT1_STAT1); 106 if (ret < 0) 107 return ret; 108 109 out: 110 /* Check if we have link and if the remote and local receiver are ok */ 111 if ((ret & MDIO_MMD_PCS_MV_100BT1_STAT1_LINK) && 112 (ret & MDIO_MMD_PCS_MV_100BT1_STAT1_LOCAL_RX) && 113 (ret & MDIO_MMD_PCS_MV_100BT1_STAT1_REMOTE_RX)) 114 phydev->link = true; 115 else 116 phydev->link = false; 117 118 return 0; 119 } 120 121 static int mv88q2xxx_read_link(struct phy_device *phydev) 122 { 123 int ret; 124 125 /* The 88Q2XXX PHYs do not have the PMA/PMD status register available, 126 * therefore we need to read the link status from the vendor specific 127 * registers depending on the speed. 128 */ 129 if (phydev->speed == SPEED_1000) 130 ret = mv88q2xxx_read_link_gbit(phydev); 131 else 132 ret = mv88q2xxx_read_link_100m(phydev); 133 134 return ret; 135 } 136 137 static int mv88q2xxx_read_status(struct phy_device *phydev) 138 { 139 int ret; 140 141 ret = mv88q2xxx_read_link(phydev); 142 if (ret < 0) 143 return ret; 144 145 return genphy_c45_read_pma(phydev); 146 } 147 148 static int mv88q2xxx_get_features(struct phy_device *phydev) 149 { 150 int ret; 151 152 ret = genphy_c45_pma_read_abilities(phydev); 153 if (ret) 154 return ret; 155 156 /* We need to read the baset1 extended abilities manually because the 157 * PHY does not signalize it has the extended abilities register 158 * available. 159 */ 160 ret = genphy_c45_pma_baset1_read_abilities(phydev); 161 if (ret) 162 return ret; 163 164 /* The PHY signalizes it supports autonegotiation. Unfortunately, so 165 * far it was not possible to get a link even when following the init 166 * sequence provided by Marvell. Disable it for now until a proper 167 * workaround is found or a new PHY revision is released. 168 */ 169 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported); 170 171 return 0; 172 } 173 174 static int mv88q2xxx_config_aneg(struct phy_device *phydev) 175 { 176 int ret; 177 178 ret = genphy_c45_config_aneg(phydev); 179 if (ret) 180 return ret; 181 182 return mv88q2xxx_soft_reset(phydev); 183 } 184 185 static int mv88q2xxx_config_init(struct phy_device *phydev) 186 { 187 int ret; 188 189 /* The 88Q2XXX PHYs do have the extended ability register available, but 190 * register MDIO_PMA_EXTABLE where they should signalize it does not 191 * work according to specification. Therefore, we force it here. 192 */ 193 phydev->pma_extable = MDIO_PMA_EXTABLE_BT1; 194 195 /* Read the current PHY configuration */ 196 ret = genphy_c45_read_pma(phydev); 197 if (ret) 198 return ret; 199 200 return mv88q2xxx_config_aneg(phydev); 201 } 202 203 static int mv88q2xxxx_get_sqi(struct phy_device *phydev) 204 { 205 int ret; 206 207 if (phydev->speed == SPEED_100) { 208 /* Read the SQI from the vendor specific receiver status 209 * register 210 */ 211 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, 0x8230); 212 if (ret < 0) 213 return ret; 214 215 ret = ret >> 12; 216 } else { 217 /* Read from vendor specific registers, they are not documented 218 * but can be found in the Software Initialization Guide. Only 219 * revisions >= A0 are supported. 220 */ 221 ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, 0xFC5D, 0x00FF, 0x00AC); 222 if (ret < 0) 223 return ret; 224 225 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, 0xfc88); 226 if (ret < 0) 227 return ret; 228 } 229 230 return ret & 0x0F; 231 } 232 233 static int mv88q2xxxx_get_sqi_max(struct phy_device *phydev) 234 { 235 return 15; 236 } 237 238 static struct phy_driver mv88q2xxx_driver[] = { 239 { 240 .phy_id = MARVELL_PHY_ID_88Q2110, 241 .phy_id_mask = MARVELL_PHY_ID_MASK, 242 .name = "mv88q2110", 243 .get_features = mv88q2xxx_get_features, 244 .config_aneg = mv88q2xxx_config_aneg, 245 .config_init = mv88q2xxx_config_init, 246 .read_status = mv88q2xxx_read_status, 247 .soft_reset = mv88q2xxx_soft_reset, 248 .set_loopback = genphy_c45_loopback, 249 .get_sqi = mv88q2xxxx_get_sqi, 250 .get_sqi_max = mv88q2xxxx_get_sqi_max, 251 }, 252 }; 253 254 module_phy_driver(mv88q2xxx_driver); 255 256 static struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = { 257 { MARVELL_PHY_ID_88Q2110, MARVELL_PHY_ID_MASK }, 258 { /*sentinel*/ } 259 }; 260 MODULE_DEVICE_TABLE(mdio, mv88q2xxx_tbl); 261 262 MODULE_DESCRIPTION("Marvell 88Q2XXX 100/1000BASE-T1 Automotive Ethernet PHY driver"); 263 MODULE_LICENSE("GPL"); 264