1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * drivers/net/phy/lxt.c 4 * 5 * Driver for Intel LXT PHYs 6 * 7 * Author: Andy Fleming 8 * 9 * Copyright (c) 2004 Freescale Semiconductor, Inc. 10 */ 11 #include <linux/kernel.h> 12 #include <linux/string.h> 13 #include <linux/errno.h> 14 #include <linux/unistd.h> 15 #include <linux/interrupt.h> 16 #include <linux/init.h> 17 #include <linux/delay.h> 18 #include <linux/netdevice.h> 19 #include <linux/etherdevice.h> 20 #include <linux/skbuff.h> 21 #include <linux/spinlock.h> 22 #include <linux/mm.h> 23 #include <linux/module.h> 24 #include <linux/mii.h> 25 #include <linux/ethtool.h> 26 #include <linux/phy.h> 27 28 #include <asm/io.h> 29 #include <asm/irq.h> 30 #include <linux/uaccess.h> 31 32 /* The Level one LXT970 is used by many boards */ 33 34 #define MII_LXT970_IER 17 /* Interrupt Enable Register */ 35 36 #define MII_LXT970_IER_IEN 0x0002 37 38 #define MII_LXT970_ISR 18 /* Interrupt Status Register */ 39 40 #define MII_LXT970_CONFIG 19 /* Configuration Register */ 41 42 /* ------------------------------------------------------------------------- */ 43 /* The Level one LXT971 is used on some of my custom boards */ 44 45 /* register definitions for the 971 */ 46 #define MII_LXT971_IER 18 /* Interrupt Enable Register */ 47 #define MII_LXT971_IER_IEN 0x00f2 48 49 #define MII_LXT971_ISR 19 /* Interrupt Status Register */ 50 51 /* register definitions for the 973 */ 52 #define MII_LXT973_PCR 16 /* Port Configuration Register */ 53 #define PCR_FIBER_SELECT 1 54 55 MODULE_DESCRIPTION("Intel LXT PHY driver"); 56 MODULE_AUTHOR("Andy Fleming"); 57 MODULE_LICENSE("GPL"); 58 59 static int lxt970_ack_interrupt(struct phy_device *phydev) 60 { 61 int err; 62 63 err = phy_read(phydev, MII_BMSR); 64 65 if (err < 0) 66 return err; 67 68 err = phy_read(phydev, MII_LXT970_ISR); 69 70 if (err < 0) 71 return err; 72 73 return 0; 74 } 75 76 static int lxt970_config_intr(struct phy_device *phydev) 77 { 78 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 79 return phy_write(phydev, MII_LXT970_IER, MII_LXT970_IER_IEN); 80 else 81 return phy_write(phydev, MII_LXT970_IER, 0); 82 } 83 84 static int lxt970_config_init(struct phy_device *phydev) 85 { 86 return phy_write(phydev, MII_LXT970_CONFIG, 0); 87 } 88 89 90 static int lxt971_ack_interrupt(struct phy_device *phydev) 91 { 92 int err = phy_read(phydev, MII_LXT971_ISR); 93 94 if (err < 0) 95 return err; 96 97 return 0; 98 } 99 100 static int lxt971_config_intr(struct phy_device *phydev) 101 { 102 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 103 return phy_write(phydev, MII_LXT971_IER, MII_LXT971_IER_IEN); 104 else 105 return phy_write(phydev, MII_LXT971_IER, 0); 106 } 107 108 /* 109 * A2 version of LXT973 chip has an ERRATA: it randomly return the contents 110 * of the previous even register when you read a odd register regularly 111 */ 112 113 static int lxt973a2_update_link(struct phy_device *phydev) 114 { 115 int status; 116 int control; 117 int retry = 8; /* we try 8 times */ 118 119 /* Do a fake read */ 120 status = phy_read(phydev, MII_BMSR); 121 122 if (status < 0) 123 return status; 124 125 control = phy_read(phydev, MII_BMCR); 126 if (control < 0) 127 return control; 128 129 do { 130 /* Read link and autonegotiation status */ 131 status = phy_read(phydev, MII_BMSR); 132 } while (status >= 0 && retry-- && status == control); 133 134 if (status < 0) 135 return status; 136 137 if ((status & BMSR_LSTATUS) == 0) 138 phydev->link = 0; 139 else 140 phydev->link = 1; 141 142 return 0; 143 } 144 145 static int lxt973a2_read_status(struct phy_device *phydev) 146 { 147 int adv; 148 int err; 149 int lpa; 150 151 /* Update the link, but return if there was an error */ 152 err = lxt973a2_update_link(phydev); 153 if (err) 154 return err; 155 156 if (AUTONEG_ENABLE == phydev->autoneg) { 157 int retry = 1; 158 159 adv = phy_read(phydev, MII_ADVERTISE); 160 161 if (adv < 0) 162 return adv; 163 164 do { 165 lpa = phy_read(phydev, MII_LPA); 166 167 if (lpa < 0) 168 return lpa; 169 170 /* If both registers are equal, it is suspect but not 171 * impossible, hence a new try 172 */ 173 } while (lpa == adv && retry--); 174 175 mii_lpa_to_linkmode_lpa_t(phydev->lp_advertising, lpa); 176 177 lpa &= adv; 178 179 phydev->speed = SPEED_10; 180 phydev->duplex = DUPLEX_HALF; 181 phydev->pause = phydev->asym_pause = 0; 182 183 if (lpa & (LPA_100FULL | LPA_100HALF)) { 184 phydev->speed = SPEED_100; 185 186 if (lpa & LPA_100FULL) 187 phydev->duplex = DUPLEX_FULL; 188 } else { 189 if (lpa & LPA_10FULL) 190 phydev->duplex = DUPLEX_FULL; 191 } 192 193 phy_resolve_aneg_pause(phydev); 194 } else { 195 int bmcr = phy_read(phydev, MII_BMCR); 196 197 if (bmcr < 0) 198 return bmcr; 199 200 if (bmcr & BMCR_FULLDPLX) 201 phydev->duplex = DUPLEX_FULL; 202 else 203 phydev->duplex = DUPLEX_HALF; 204 205 if (bmcr & BMCR_SPEED1000) 206 phydev->speed = SPEED_1000; 207 else if (bmcr & BMCR_SPEED100) 208 phydev->speed = SPEED_100; 209 else 210 phydev->speed = SPEED_10; 211 212 phydev->pause = phydev->asym_pause = 0; 213 linkmode_zero(phydev->lp_advertising); 214 } 215 216 return 0; 217 } 218 219 static int lxt973_probe(struct phy_device *phydev) 220 { 221 int val = phy_read(phydev, MII_LXT973_PCR); 222 223 if (val & PCR_FIBER_SELECT) { 224 /* 225 * If fiber is selected, then the only correct setting 226 * is 100Mbps, full duplex, and auto negotiation off. 227 */ 228 val = phy_read(phydev, MII_BMCR); 229 val |= (BMCR_SPEED100 | BMCR_FULLDPLX); 230 val &= ~BMCR_ANENABLE; 231 phy_write(phydev, MII_BMCR, val); 232 /* Remember that the port is in fiber mode. */ 233 phydev->priv = lxt973_probe; 234 } else { 235 phydev->priv = NULL; 236 } 237 return 0; 238 } 239 240 static int lxt973_config_aneg(struct phy_device *phydev) 241 { 242 /* Do nothing if port is in fiber mode. */ 243 return phydev->priv ? 0 : genphy_config_aneg(phydev); 244 } 245 246 static struct phy_driver lxt97x_driver[] = { 247 { 248 .phy_id = 0x78100000, 249 .name = "LXT970", 250 .phy_id_mask = 0xfffffff0, 251 /* PHY_BASIC_FEATURES */ 252 .config_init = lxt970_config_init, 253 .ack_interrupt = lxt970_ack_interrupt, 254 .config_intr = lxt970_config_intr, 255 }, { 256 .phy_id = 0x001378e0, 257 .name = "LXT971", 258 .phy_id_mask = 0xfffffff0, 259 /* PHY_BASIC_FEATURES */ 260 .ack_interrupt = lxt971_ack_interrupt, 261 .config_intr = lxt971_config_intr, 262 .suspend = genphy_suspend, 263 .resume = genphy_resume, 264 }, { 265 .phy_id = 0x00137a10, 266 .name = "LXT973-A2", 267 .phy_id_mask = 0xffffffff, 268 /* PHY_BASIC_FEATURES */ 269 .flags = 0, 270 .probe = lxt973_probe, 271 .config_aneg = lxt973_config_aneg, 272 .read_status = lxt973a2_read_status, 273 .suspend = genphy_suspend, 274 .resume = genphy_resume, 275 }, { 276 .phy_id = 0x00137a10, 277 .name = "LXT973", 278 .phy_id_mask = 0xfffffff0, 279 /* PHY_BASIC_FEATURES */ 280 .flags = 0, 281 .probe = lxt973_probe, 282 .config_aneg = lxt973_config_aneg, 283 .suspend = genphy_suspend, 284 .resume = genphy_resume, 285 } }; 286 287 module_phy_driver(lxt97x_driver); 288 289 static struct mdio_device_id __maybe_unused lxt_tbl[] = { 290 { 0x78100000, 0xfffffff0 }, 291 { 0x001378e0, 0xfffffff0 }, 292 { 0x00137a10, 0xfffffff0 }, 293 { } 294 }; 295 296 MODULE_DEVICE_TABLE(mdio, lxt_tbl); 297