0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
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
0102 gpcs_phy_write(phy, 0x04, 0x8120);
0103 gpcs_phy_write(phy, 0x07, 0x2801);
0104 gpcs_phy_write(phy, 0x00, 0x0140);
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
0126 phy_write(phy, MII_BMCR, ctl);
0127
0128
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
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
0184 phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
0185
0186
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
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
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
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
0334 phy_write(phy, MII_CIS8201_ACSR,
0335 phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
0336
0337
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
0384
0385
0386
0387
0388 u16 reg_short;
0389
0390 pr_debug("%s: Marvell 88E1112 Ethernet\n", __func__);
0391
0392
0393 phy_write(phy, 0x16, 0x0002);
0394
0395 phy_write(phy, 0x00, 0x0040);
0396 reg_short = (u16)(phy_read(phy, 0x1a));
0397 reg_short |= 0x8000;
0398 phy_write(phy, 0x1a, reg_short);
0399 emac_mii_reset_phy(phy);
0400
0401
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;
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);
0477 phy_write(phy, 0x1e, 0x2d47);
0478 phy_write(phy, 0x1d, 0xb);
0479 phy_write(phy, 0x1e, 0xbc20);
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
0524 if (emac_mii_reset_phy(phy))
0525 return -ENODEV;
0526
0527
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
0533 if (!def)
0534 return -ENODEV;
0535
0536 phy->def = def;
0537
0538
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
0563 phy->advertising = phy->features;
0564
0565 return 0;
0566 }
0567
0568 MODULE_LICENSE("GPL");