Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * drivers/net/ethernet/ibm/emac/phy.c
0004  *
0005  * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
0006  * Borrowed from sungem_phy.c, though I only kept the generic MII
0007  * driver for now.
0008  *
0009  * This file should be shared with other drivers or eventually
0010  * merged as the "low level" part of miilib
0011  *
0012  * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
0013  *                <benh@kernel.crashing.org>
0014  *
0015  * Based on the arch/ppc version of the driver:
0016  *
0017  * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
0018  * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
0019  *
0020  */
0021 #include <linux/module.h>
0022 #include <linux/kernel.h>
0023 #include <linux/types.h>
0024 #include <linux/netdevice.h>
0025 #include <linux/mii.h>
0026 #include <linux/ethtool.h>
0027 #include <linux/delay.h>
0028 
0029 #include "emac.h"
0030 #include "phy.h"
0031 
0032 #define phy_read _phy_read
0033 #define phy_write _phy_write
0034 
0035 static inline int _phy_read(struct mii_phy *phy, int reg)
0036 {
0037     return phy->mdio_read(phy->dev, phy->address, reg);
0038 }
0039 
0040 static inline void _phy_write(struct mii_phy *phy, int reg, int val)
0041 {
0042     phy->mdio_write(phy->dev, phy->address, reg, val);
0043 }
0044 
0045 static inline int gpcs_phy_read(struct mii_phy *phy, int reg)
0046 {
0047     return phy->mdio_read(phy->dev, phy->gpcs_address, reg);
0048 }
0049 
0050 static inline void gpcs_phy_write(struct mii_phy *phy, int reg, int val)
0051 {
0052     phy->mdio_write(phy->dev, phy->gpcs_address, reg, val);
0053 }
0054 
0055 int emac_mii_reset_phy(struct mii_phy *phy)
0056 {
0057     int val;
0058     int limit = 10000;
0059 
0060     val = phy_read(phy, MII_BMCR);
0061     val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
0062     val |= BMCR_RESET;
0063     phy_write(phy, MII_BMCR, val);
0064 
0065     udelay(300);
0066 
0067     while (--limit) {
0068         val = phy_read(phy, MII_BMCR);
0069         if (val >= 0 && (val & BMCR_RESET) == 0)
0070             break;
0071         udelay(10);
0072     }
0073     if ((val & BMCR_ISOLATE) && limit > 0)
0074         phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
0075 
0076     return limit <= 0;
0077 }
0078 
0079 int emac_mii_reset_gpcs(struct mii_phy *phy)
0080 {
0081     int val;
0082     int limit = 10000;
0083 
0084     val = gpcs_phy_read(phy, MII_BMCR);
0085     val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
0086     val |= BMCR_RESET;
0087     gpcs_phy_write(phy, MII_BMCR, val);
0088 
0089     udelay(300);
0090 
0091     while (--limit) {
0092         val = gpcs_phy_read(phy, MII_BMCR);
0093         if (val >= 0 && (val & BMCR_RESET) == 0)
0094             break;
0095         udelay(10);
0096     }
0097     if ((val & BMCR_ISOLATE) && limit > 0)
0098         gpcs_phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
0099 
0100     if (limit > 0 && phy->mode == PHY_INTERFACE_MODE_SGMII) {
0101         /* Configure GPCS interface to recommended setting for SGMII */
0102         gpcs_phy_write(phy, 0x04, 0x8120); /* AsymPause, FDX */
0103         gpcs_phy_write(phy, 0x07, 0x2801); /* msg_pg, toggle */
0104         gpcs_phy_write(phy, 0x00, 0x0140); /* 1Gbps, FDX     */
0105     }
0106 
0107     return limit <= 0;
0108 }
0109 
0110 static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
0111 {
0112     int ctl, adv;
0113 
0114     phy->autoneg = AUTONEG_ENABLE;
0115     phy->speed = SPEED_10;
0116     phy->duplex = DUPLEX_HALF;
0117     phy->pause = phy->asym_pause = 0;
0118     phy->advertising = advertise;
0119 
0120     ctl = phy_read(phy, MII_BMCR);
0121     if (ctl < 0)
0122         return ctl;
0123     ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
0124 
0125     /* First clear the PHY */
0126     phy_write(phy, MII_BMCR, ctl);
0127 
0128     /* Setup standard advertise */
0129     adv = phy_read(phy, MII_ADVERTISE);
0130     if (adv < 0)
0131         return adv;
0132     adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
0133          ADVERTISE_PAUSE_ASYM);
0134     if (advertise & ADVERTISED_10baseT_Half)
0135         adv |= ADVERTISE_10HALF;
0136     if (advertise & ADVERTISED_10baseT_Full)
0137         adv |= ADVERTISE_10FULL;
0138     if (advertise & ADVERTISED_100baseT_Half)
0139         adv |= ADVERTISE_100HALF;
0140     if (advertise & ADVERTISED_100baseT_Full)
0141         adv |= ADVERTISE_100FULL;
0142     if (advertise & ADVERTISED_Pause)
0143         adv |= ADVERTISE_PAUSE_CAP;
0144     if (advertise & ADVERTISED_Asym_Pause)
0145         adv |= ADVERTISE_PAUSE_ASYM;
0146     phy_write(phy, MII_ADVERTISE, adv);
0147 
0148     if (phy->features &
0149         (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
0150         adv = phy_read(phy, MII_CTRL1000);
0151         if (adv < 0)
0152             return adv;
0153         adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
0154         if (advertise & ADVERTISED_1000baseT_Full)
0155             adv |= ADVERTISE_1000FULL;
0156         if (advertise & ADVERTISED_1000baseT_Half)
0157             adv |= ADVERTISE_1000HALF;
0158         phy_write(phy, MII_CTRL1000, adv);
0159     }
0160 
0161     /* Start/Restart aneg */
0162     ctl = phy_read(phy, MII_BMCR);
0163     ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
0164     phy_write(phy, MII_BMCR, ctl);
0165 
0166     return 0;
0167 }
0168 
0169 static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
0170 {
0171     int ctl;
0172 
0173     phy->autoneg = AUTONEG_DISABLE;
0174     phy->speed = speed;
0175     phy->duplex = fd;
0176     phy->pause = phy->asym_pause = 0;
0177 
0178     ctl = phy_read(phy, MII_BMCR);
0179     if (ctl < 0)
0180         return ctl;
0181     ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
0182 
0183     /* First clear the PHY */
0184     phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
0185 
0186     /* Select speed & duplex */
0187     switch (speed) {
0188     case SPEED_10:
0189         break;
0190     case SPEED_100:
0191         ctl |= BMCR_SPEED100;
0192         break;
0193     case SPEED_1000:
0194         ctl |= BMCR_SPEED1000;
0195         break;
0196     default:
0197         return -EINVAL;
0198     }
0199     if (fd == DUPLEX_FULL)
0200         ctl |= BMCR_FULLDPLX;
0201     phy_write(phy, MII_BMCR, ctl);
0202 
0203     return 0;
0204 }
0205 
0206 static int genmii_poll_link(struct mii_phy *phy)
0207 {
0208     int status;
0209 
0210     /* Clear latched value with dummy read */
0211     phy_read(phy, MII_BMSR);
0212     status = phy_read(phy, MII_BMSR);
0213     if (status < 0 || (status & BMSR_LSTATUS) == 0)
0214         return 0;
0215     if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
0216         return 0;
0217     return 1;
0218 }
0219 
0220 static int genmii_read_link(struct mii_phy *phy)
0221 {
0222     if (phy->autoneg == AUTONEG_ENABLE) {
0223         int glpa = 0;
0224         int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
0225         if (lpa < 0)
0226             return lpa;
0227 
0228         if (phy->features &
0229             (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
0230             int adv = phy_read(phy, MII_CTRL1000);
0231             glpa = phy_read(phy, MII_STAT1000);
0232 
0233             if (glpa < 0 || adv < 0)
0234                 return adv;
0235 
0236             glpa &= adv << 2;
0237         }
0238 
0239         phy->speed = SPEED_10;
0240         phy->duplex = DUPLEX_HALF;
0241         phy->pause = phy->asym_pause = 0;
0242 
0243         if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
0244             phy->speed = SPEED_1000;
0245             if (glpa & LPA_1000FULL)
0246                 phy->duplex = DUPLEX_FULL;
0247         } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
0248             phy->speed = SPEED_100;
0249             if (lpa & LPA_100FULL)
0250                 phy->duplex = DUPLEX_FULL;
0251         } else if (lpa & LPA_10FULL)
0252             phy->duplex = DUPLEX_FULL;
0253 
0254         if (phy->duplex == DUPLEX_FULL) {
0255             phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
0256             phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
0257         }
0258     } else {
0259         int bmcr = phy_read(phy, MII_BMCR);
0260         if (bmcr < 0)
0261             return bmcr;
0262 
0263         if (bmcr & BMCR_FULLDPLX)
0264             phy->duplex = DUPLEX_FULL;
0265         else
0266             phy->duplex = DUPLEX_HALF;
0267         if (bmcr & BMCR_SPEED1000)
0268             phy->speed = SPEED_1000;
0269         else if (bmcr & BMCR_SPEED100)
0270             phy->speed = SPEED_100;
0271         else
0272             phy->speed = SPEED_10;
0273 
0274         phy->pause = phy->asym_pause = 0;
0275     }
0276     return 0;
0277 }
0278 
0279 /* Generic implementation for most 10/100/1000 PHYs */
0280 static const struct mii_phy_ops generic_phy_ops = {
0281     .setup_aneg = genmii_setup_aneg,
0282     .setup_forced   = genmii_setup_forced,
0283     .poll_link  = genmii_poll_link,
0284     .read_link  = genmii_read_link
0285 };
0286 
0287 static struct mii_phy_def genmii_phy_def = {
0288     .phy_id     = 0x00000000,
0289     .phy_id_mask    = 0x00000000,
0290     .name       = "Generic MII",
0291     .ops        = &generic_phy_ops
0292 };
0293 
0294 /* CIS8201 */
0295 #define MII_CIS8201_10BTCSR 0x16
0296 #define  TENBTCSR_ECHO_DISABLE  0x2000
0297 #define MII_CIS8201_EPCR    0x17
0298 #define  EPCR_MODE_MASK     0x3000
0299 #define  EPCR_GMII_MODE     0x0000
0300 #define  EPCR_RGMII_MODE    0x1000
0301 #define  EPCR_TBI_MODE      0x2000
0302 #define  EPCR_RTBI_MODE     0x3000
0303 #define MII_CIS8201_ACSR    0x1c
0304 #define  ACSR_PIN_PRIO_SELECT   0x0004
0305 
0306 static int cis8201_init(struct mii_phy *phy)
0307 {
0308     int epcr;
0309 
0310     epcr = phy_read(phy, MII_CIS8201_EPCR);
0311     if (epcr < 0)
0312         return epcr;
0313 
0314     epcr &= ~EPCR_MODE_MASK;
0315 
0316     switch (phy->mode) {
0317     case PHY_INTERFACE_MODE_TBI:
0318         epcr |= EPCR_TBI_MODE;
0319         break;
0320     case PHY_INTERFACE_MODE_RTBI:
0321         epcr |= EPCR_RTBI_MODE;
0322         break;
0323     case PHY_INTERFACE_MODE_GMII:
0324         epcr |= EPCR_GMII_MODE;
0325         break;
0326     case PHY_INTERFACE_MODE_RGMII:
0327     default:
0328         epcr |= EPCR_RGMII_MODE;
0329     }
0330 
0331     phy_write(phy, MII_CIS8201_EPCR, epcr);
0332 
0333     /* MII regs override strap pins */
0334     phy_write(phy, MII_CIS8201_ACSR,
0335           phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
0336 
0337     /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
0338     phy_write(phy, MII_CIS8201_10BTCSR,
0339           phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
0340 
0341     return 0;
0342 }
0343 
0344 static const struct mii_phy_ops cis8201_phy_ops = {
0345     .init       = cis8201_init,
0346     .setup_aneg = genmii_setup_aneg,
0347     .setup_forced   = genmii_setup_forced,
0348     .poll_link  = genmii_poll_link,
0349     .read_link  = genmii_read_link
0350 };
0351 
0352 static struct mii_phy_def cis8201_phy_def = {
0353     .phy_id     = 0x000fc410,
0354     .phy_id_mask    = 0x000ffff0,
0355     .name       = "CIS8201 Gigabit Ethernet",
0356     .ops        = &cis8201_phy_ops
0357 };
0358 
0359 static struct mii_phy_def bcm5248_phy_def = {
0360 
0361     .phy_id     = 0x0143bc00,
0362     .phy_id_mask    = 0x0ffffff0,
0363     .name       = "BCM5248 10/100 SMII Ethernet",
0364     .ops        = &generic_phy_ops
0365 };
0366 
0367 static int m88e1111_init(struct mii_phy *phy)
0368 {
0369     pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__);
0370     phy_write(phy, 0x14, 0x0ce3);
0371     phy_write(phy, 0x18, 0x4101);
0372     phy_write(phy, 0x09, 0x0e00);
0373     phy_write(phy, 0x04, 0x01e1);
0374     phy_write(phy, 0x00, 0x9140);
0375     phy_write(phy, 0x00, 0x1140);
0376 
0377     return  0;
0378 }
0379 
0380 static int m88e1112_init(struct mii_phy *phy)
0381 {
0382     /*
0383      * Marvell 88E1112 PHY needs to have the SGMII MAC
0384      * interace (page 2) properly configured to
0385      * communicate with the 460EX/GT GPCS interface.
0386      */
0387 
0388     u16 reg_short;
0389 
0390     pr_debug("%s: Marvell 88E1112 Ethernet\n", __func__);
0391 
0392     /* Set access to Page 2 */
0393     phy_write(phy, 0x16, 0x0002);
0394 
0395     phy_write(phy, 0x00, 0x0040); /* 1Gbps */
0396     reg_short = (u16)(phy_read(phy, 0x1a));
0397     reg_short |= 0x8000; /* bypass Auto-Negotiation */
0398     phy_write(phy, 0x1a, reg_short);
0399     emac_mii_reset_phy(phy); /* reset MAC interface */
0400 
0401     /* Reset access to Page 0 */
0402     phy_write(phy, 0x16, 0x0000);
0403 
0404     return  0;
0405 }
0406 
0407 static int et1011c_init(struct mii_phy *phy)
0408 {
0409     u16 reg_short;
0410 
0411     reg_short = (u16)(phy_read(phy, 0x16));
0412     reg_short &= ~(0x7);
0413     reg_short |= 0x6;   /* RGMII Trace Delay*/
0414     phy_write(phy, 0x16, reg_short);
0415 
0416     reg_short = (u16)(phy_read(phy, 0x17));
0417     reg_short &= ~(0x40);
0418     phy_write(phy, 0x17, reg_short);
0419 
0420     phy_write(phy, 0x1c, 0x74f0);
0421     return 0;
0422 }
0423 
0424 static const struct mii_phy_ops et1011c_phy_ops = {
0425     .init       = et1011c_init,
0426     .setup_aneg = genmii_setup_aneg,
0427     .setup_forced   = genmii_setup_forced,
0428     .poll_link  = genmii_poll_link,
0429     .read_link  = genmii_read_link
0430 };
0431 
0432 static struct mii_phy_def et1011c_phy_def = {
0433     .phy_id     = 0x0282f000,
0434     .phy_id_mask    = 0x0fffff00,
0435     .name       = "ET1011C Gigabit Ethernet",
0436     .ops        = &et1011c_phy_ops
0437 };
0438 
0439 
0440 
0441 
0442 
0443 static const struct mii_phy_ops m88e1111_phy_ops = {
0444     .init       = m88e1111_init,
0445     .setup_aneg = genmii_setup_aneg,
0446     .setup_forced   = genmii_setup_forced,
0447     .poll_link  = genmii_poll_link,
0448     .read_link  = genmii_read_link
0449 };
0450 
0451 static struct mii_phy_def m88e1111_phy_def = {
0452 
0453     .phy_id     = 0x01410CC0,
0454     .phy_id_mask    = 0x0ffffff0,
0455     .name       = "Marvell 88E1111 Ethernet",
0456     .ops        = &m88e1111_phy_ops,
0457 };
0458 
0459 static const struct mii_phy_ops m88e1112_phy_ops = {
0460     .init       = m88e1112_init,
0461     .setup_aneg = genmii_setup_aneg,
0462     .setup_forced   = genmii_setup_forced,
0463     .poll_link  = genmii_poll_link,
0464     .read_link  = genmii_read_link
0465 };
0466 
0467 static struct mii_phy_def m88e1112_phy_def = {
0468     .phy_id     = 0x01410C90,
0469     .phy_id_mask    = 0x0ffffff0,
0470     .name       = "Marvell 88E1112 Ethernet",
0471     .ops        = &m88e1112_phy_ops,
0472 };
0473 
0474 static int ar8035_init(struct mii_phy *phy)
0475 {
0476     phy_write(phy, 0x1d, 0x5); /* Address debug register 5 */
0477     phy_write(phy, 0x1e, 0x2d47); /* Value copied from u-boot */
0478     phy_write(phy, 0x1d, 0xb);    /* Address hib ctrl */
0479     phy_write(phy, 0x1e, 0xbc20); /* Value copied from u-boot */
0480 
0481     return 0;
0482 }
0483 
0484 static const struct mii_phy_ops ar8035_phy_ops = {
0485     .init       = ar8035_init,
0486     .setup_aneg = genmii_setup_aneg,
0487     .setup_forced   = genmii_setup_forced,
0488     .poll_link  = genmii_poll_link,
0489     .read_link  = genmii_read_link,
0490 };
0491 
0492 static struct mii_phy_def ar8035_phy_def = {
0493     .phy_id     = 0x004dd070,
0494     .phy_id_mask    = 0xfffffff0,
0495     .name       = "Atheros 8035 Gigabit Ethernet",
0496     .ops        = &ar8035_phy_ops,
0497 };
0498 
0499 static struct mii_phy_def *mii_phy_table[] = {
0500     &et1011c_phy_def,
0501     &cis8201_phy_def,
0502     &bcm5248_phy_def,
0503     &m88e1111_phy_def,
0504     &m88e1112_phy_def,
0505     &ar8035_phy_def,
0506     &genmii_phy_def,
0507     NULL
0508 };
0509 
0510 int emac_mii_phy_probe(struct mii_phy *phy, int address)
0511 {
0512     struct mii_phy_def *def;
0513     int i;
0514     u32 id;
0515 
0516     phy->autoneg = AUTONEG_DISABLE;
0517     phy->advertising = 0;
0518     phy->address = address;
0519     phy->speed = SPEED_10;
0520     phy->duplex = DUPLEX_HALF;
0521     phy->pause = phy->asym_pause = 0;
0522 
0523     /* Take PHY out of isolate mode and reset it. */
0524     if (emac_mii_reset_phy(phy))
0525         return -ENODEV;
0526 
0527     /* Read ID and find matching entry */
0528     id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
0529     for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
0530         if ((id & def->phy_id_mask) == def->phy_id)
0531             break;
0532     /* Should never be NULL (we have a generic entry), but... */
0533     if (!def)
0534         return -ENODEV;
0535 
0536     phy->def = def;
0537 
0538     /* Determine PHY features if needed */
0539     phy->features = def->features;
0540     if (!phy->features) {
0541         u16 bmsr = phy_read(phy, MII_BMSR);
0542         if (bmsr & BMSR_ANEGCAPABLE)
0543             phy->features |= SUPPORTED_Autoneg;
0544         if (bmsr & BMSR_10HALF)
0545             phy->features |= SUPPORTED_10baseT_Half;
0546         if (bmsr & BMSR_10FULL)
0547             phy->features |= SUPPORTED_10baseT_Full;
0548         if (bmsr & BMSR_100HALF)
0549             phy->features |= SUPPORTED_100baseT_Half;
0550         if (bmsr & BMSR_100FULL)
0551             phy->features |= SUPPORTED_100baseT_Full;
0552         if (bmsr & BMSR_ESTATEN) {
0553             u16 esr = phy_read(phy, MII_ESTATUS);
0554             if (esr & ESTATUS_1000_TFULL)
0555                 phy->features |= SUPPORTED_1000baseT_Full;
0556             if (esr & ESTATUS_1000_THALF)
0557                 phy->features |= SUPPORTED_1000baseT_Half;
0558         }
0559         phy->features |= SUPPORTED_MII;
0560     }
0561 
0562     /* Setup default advertising */
0563     phy->advertising = phy->features;
0564 
0565     return 0;
0566 }
0567 
0568 MODULE_LICENSE("GPL");