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 if (phydev->duplex == DUPLEX_FULL) { 194 phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; 195 phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; 196 } 197 } else { 198 int bmcr = phy_read(phydev, MII_BMCR); 199 200 if (bmcr < 0) 201 return bmcr; 202 203 if (bmcr & BMCR_FULLDPLX) 204 phydev->duplex = DUPLEX_FULL; 205 else 206 phydev->duplex = DUPLEX_HALF; 207 208 if (bmcr & BMCR_SPEED1000) 209 phydev->speed = SPEED_1000; 210 else if (bmcr & BMCR_SPEED100) 211 phydev->speed = SPEED_100; 212 else 213 phydev->speed = SPEED_10; 214 215 phydev->pause = phydev->asym_pause = 0; 216 linkmode_zero(phydev->lp_advertising); 217 } 218 219 return 0; 220 } 221 222 static int lxt973_probe(struct phy_device *phydev) 223 { 224 int val = phy_read(phydev, MII_LXT973_PCR); 225 226 if (val & PCR_FIBER_SELECT) { 227 /* 228 * If fiber is selected, then the only correct setting 229 * is 100Mbps, full duplex, and auto negotiation off. 230 */ 231 val = phy_read(phydev, MII_BMCR); 232 val |= (BMCR_SPEED100 | BMCR_FULLDPLX); 233 val &= ~BMCR_ANENABLE; 234 phy_write(phydev, MII_BMCR, val); 235 /* Remember that the port is in fiber mode. */ 236 phydev->priv = lxt973_probe; 237 } else { 238 phydev->priv = NULL; 239 } 240 return 0; 241 } 242 243 static int lxt973_config_aneg(struct phy_device *phydev) 244 { 245 /* Do nothing if port is in fiber mode. */ 246 return phydev->priv ? 0 : genphy_config_aneg(phydev); 247 } 248 249 static struct phy_driver lxt97x_driver[] = { 250 { 251 .phy_id = 0x78100000, 252 .name = "LXT970", 253 .phy_id_mask = 0xfffffff0, 254 .features = PHY_BASIC_FEATURES, 255 .config_init = lxt970_config_init, 256 .ack_interrupt = lxt970_ack_interrupt, 257 .config_intr = lxt970_config_intr, 258 }, { 259 .phy_id = 0x001378e0, 260 .name = "LXT971", 261 .phy_id_mask = 0xfffffff0, 262 .features = PHY_BASIC_FEATURES, 263 .ack_interrupt = lxt971_ack_interrupt, 264 .config_intr = lxt971_config_intr, 265 }, { 266 .phy_id = 0x00137a10, 267 .name = "LXT973-A2", 268 .phy_id_mask = 0xffffffff, 269 .features = PHY_BASIC_FEATURES, 270 .flags = 0, 271 .probe = lxt973_probe, 272 .config_aneg = lxt973_config_aneg, 273 .read_status = lxt973a2_read_status, 274 }, { 275 .phy_id = 0x00137a10, 276 .name = "LXT973", 277 .phy_id_mask = 0xfffffff0, 278 .features = PHY_BASIC_FEATURES, 279 .flags = 0, 280 .probe = lxt973_probe, 281 .config_aneg = lxt973_config_aneg, 282 } }; 283 284 module_phy_driver(lxt97x_driver); 285 286 static struct mdio_device_id __maybe_unused lxt_tbl[] = { 287 { 0x78100000, 0xfffffff0 }, 288 { 0x001378e0, 0xfffffff0 }, 289 { 0x00137a10, 0xfffffff0 }, 290 { } 291 }; 292 293 MODULE_DEVICE_TABLE(mdio, lxt_tbl); 294