359 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * drivers/net/phy/lxt.c4 *5 * Driver for Intel LXT PHYs6 *7 * Author: Andy Fleming8 *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 0x000237 38#define MII_LXT970_ISR 18 /* Interrupt Status Register */39 40#define MII_LXT970_IRS_MINT BIT(15)41 42#define MII_LXT970_CONFIG 19 /* Configuration Register */43 44/* ------------------------------------------------------------------------- */45/* The Level one LXT971 is used on some of my custom boards */46 47/* register definitions for the 971 */48#define MII_LXT971_IER 18 /* Interrupt Enable Register */49#define MII_LXT971_IER_IEN 0x00f250 51#define MII_LXT971_ISR 19 /* Interrupt Status Register */52#define MII_LXT971_ISR_MASK 0x00f053 54/* register definitions for the 973 */55#define MII_LXT973_PCR 16 /* Port Configuration Register */56#define PCR_FIBER_SELECT 157 58MODULE_DESCRIPTION("Intel LXT PHY driver");59MODULE_AUTHOR("Andy Fleming");60MODULE_LICENSE("GPL");61 62static int lxt970_ack_interrupt(struct phy_device *phydev)63{64 int err;65 66 err = phy_read(phydev, MII_BMSR);67 68 if (err < 0)69 return err;70 71 err = phy_read(phydev, MII_LXT970_ISR);72 73 if (err < 0)74 return err;75 76 return 0;77}78 79static int lxt970_config_intr(struct phy_device *phydev)80{81 int err;82 83 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {84 err = lxt970_ack_interrupt(phydev);85 if (err)86 return err;87 88 err = phy_write(phydev, MII_LXT970_IER, MII_LXT970_IER_IEN);89 } else {90 err = phy_write(phydev, MII_LXT970_IER, 0);91 if (err)92 return err;93 94 err = lxt970_ack_interrupt(phydev);95 }96 97 return err;98}99 100static irqreturn_t lxt970_handle_interrupt(struct phy_device *phydev)101{102 int irq_status;103 104 /* The interrupt status register is cleared by reading BMSR105 * followed by MII_LXT970_ISR106 */107 irq_status = phy_read(phydev, MII_BMSR);108 if (irq_status < 0) {109 phy_error(phydev);110 return IRQ_NONE;111 }112 113 irq_status = phy_read(phydev, MII_LXT970_ISR);114 if (irq_status < 0) {115 phy_error(phydev);116 return IRQ_NONE;117 }118 119 if (!(irq_status & MII_LXT970_IRS_MINT))120 return IRQ_NONE;121 122 phy_trigger_machine(phydev);123 124 return IRQ_HANDLED;125}126 127static int lxt970_config_init(struct phy_device *phydev)128{129 return phy_write(phydev, MII_LXT970_CONFIG, 0);130}131 132 133static int lxt971_ack_interrupt(struct phy_device *phydev)134{135 int err = phy_read(phydev, MII_LXT971_ISR);136 137 if (err < 0)138 return err;139 140 return 0;141}142 143static int lxt971_config_intr(struct phy_device *phydev)144{145 int err;146 147 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {148 err = lxt971_ack_interrupt(phydev);149 if (err)150 return err;151 152 err = phy_write(phydev, MII_LXT971_IER, MII_LXT971_IER_IEN);153 } else {154 err = phy_write(phydev, MII_LXT971_IER, 0);155 if (err)156 return err;157 158 err = lxt971_ack_interrupt(phydev);159 }160 161 return err;162}163 164static irqreturn_t lxt971_handle_interrupt(struct phy_device *phydev)165{166 int irq_status;167 168 irq_status = phy_read(phydev, MII_LXT971_ISR);169 if (irq_status < 0) {170 phy_error(phydev);171 return IRQ_NONE;172 }173 174 if (!(irq_status & MII_LXT971_ISR_MASK))175 return IRQ_NONE;176 177 phy_trigger_machine(phydev);178 179 return IRQ_HANDLED;180}181 182/*183 * A2 version of LXT973 chip has an ERRATA: it randomly return the contents184 * of the previous even register when you read a odd register regularly185 */186 187static int lxt973a2_update_link(struct phy_device *phydev)188{189 int status;190 int control;191 int retry = 8; /* we try 8 times */192 193 /* Do a fake read */194 status = phy_read(phydev, MII_BMSR);195 196 if (status < 0)197 return status;198 199 control = phy_read(phydev, MII_BMCR);200 if (control < 0)201 return control;202 203 do {204 /* Read link and autonegotiation status */205 status = phy_read(phydev, MII_BMSR);206 } while (status >= 0 && retry-- && status == control);207 208 if (status < 0)209 return status;210 211 if ((status & BMSR_LSTATUS) == 0)212 phydev->link = 0;213 else214 phydev->link = 1;215 216 return 0;217}218 219static int lxt973a2_read_status(struct phy_device *phydev)220{221 int adv;222 int err;223 int lpa;224 225 /* Update the link, but return if there was an error */226 err = lxt973a2_update_link(phydev);227 if (err)228 return err;229 230 if (AUTONEG_ENABLE == phydev->autoneg) {231 int retry = 1;232 233 adv = phy_read(phydev, MII_ADVERTISE);234 235 if (adv < 0)236 return adv;237 238 do {239 lpa = phy_read(phydev, MII_LPA);240 241 if (lpa < 0)242 return lpa;243 244 /* If both registers are equal, it is suspect but not245 * impossible, hence a new try246 */247 } while (lpa == adv && retry--);248 249 mii_lpa_to_linkmode_lpa_t(phydev->lp_advertising, lpa);250 251 lpa &= adv;252 253 phydev->speed = SPEED_10;254 phydev->duplex = DUPLEX_HALF;255 phydev->pause = phydev->asym_pause = 0;256 257 if (lpa & (LPA_100FULL | LPA_100HALF)) {258 phydev->speed = SPEED_100;259 260 if (lpa & LPA_100FULL)261 phydev->duplex = DUPLEX_FULL;262 } else {263 if (lpa & LPA_10FULL)264 phydev->duplex = DUPLEX_FULL;265 }266 267 phy_resolve_aneg_pause(phydev);268 } else {269 err = genphy_read_status_fixed(phydev);270 if (err < 0)271 return err;272 273 phydev->pause = phydev->asym_pause = 0;274 linkmode_zero(phydev->lp_advertising);275 }276 277 return 0;278}279 280static int lxt973_probe(struct phy_device *phydev)281{282 int val = phy_read(phydev, MII_LXT973_PCR);283 284 if (val & PCR_FIBER_SELECT) {285 /*286 * If fiber is selected, then the only correct setting287 * is 100Mbps, full duplex, and auto negotiation off.288 */289 val = phy_read(phydev, MII_BMCR);290 val |= (BMCR_SPEED100 | BMCR_FULLDPLX);291 val &= ~BMCR_ANENABLE;292 phy_write(phydev, MII_BMCR, val);293 /* Remember that the port is in fiber mode. */294 phydev->priv = lxt973_probe;295 phydev->port = PORT_FIBRE;296 } else {297 phydev->priv = NULL;298 }299 return 0;300}301 302static int lxt973_config_aneg(struct phy_device *phydev)303{304 /* Do nothing if port is in fiber mode. */305 return phydev->priv ? 0 : genphy_config_aneg(phydev);306}307 308static struct phy_driver lxt97x_driver[] = {309{310 .phy_id = 0x78100000,311 .name = "LXT970",312 .phy_id_mask = 0xfffffff0,313 /* PHY_BASIC_FEATURES */314 .config_init = lxt970_config_init,315 .config_intr = lxt970_config_intr,316 .handle_interrupt = lxt970_handle_interrupt,317}, {318 .phy_id = 0x001378e0,319 .name = "LXT971",320 .phy_id_mask = 0xfffffff0,321 /* PHY_BASIC_FEATURES */322 .config_intr = lxt971_config_intr,323 .handle_interrupt = lxt971_handle_interrupt,324 .suspend = genphy_suspend,325 .resume = genphy_resume,326}, {327 .phy_id = 0x00137a10,328 .name = "LXT973-A2",329 .phy_id_mask = 0xffffffff,330 /* PHY_BASIC_FEATURES */331 .flags = 0,332 .probe = lxt973_probe,333 .config_aneg = lxt973_config_aneg,334 .read_status = lxt973a2_read_status,335 .suspend = genphy_suspend,336 .resume = genphy_resume,337}, {338 .phy_id = 0x00137a10,339 .name = "LXT973",340 .phy_id_mask = 0xfffffff0,341 /* PHY_BASIC_FEATURES */342 .flags = 0,343 .probe = lxt973_probe,344 .config_aneg = lxt973_config_aneg,345 .suspend = genphy_suspend,346 .resume = genphy_resume,347} };348 349module_phy_driver(lxt97x_driver);350 351static struct mdio_device_id __maybe_unused lxt_tbl[] = {352 { 0x78100000, 0xfffffff0 },353 { 0x001378e0, 0xfffffff0 },354 { 0x00137a10, 0xfffffff0 },355 { }356};357 358MODULE_DEVICE_TABLE(mdio, lxt_tbl);359