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