Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.14 661 lines 17 kB view raw
1/* 2 * drivers/net/gianfar_phy.c 3 * 4 * Gianfar Ethernet Driver -- PHY handling 5 * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560 6 * Based on 8260_io/fcc_enet.c 7 * 8 * Author: Andy Fleming 9 * Maintainer: Kumar Gala (kumar.gala@freescale.com) 10 * 11 * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. 12 * 13 * This program is free software; you can redistribute it and/or modify it 14 * under the terms of the GNU General Public License as published by the 15 * Free Software Foundation; either version 2 of the License, or (at your 16 * option) any later version. 17 * 18 */ 19 20#include <linux/config.h> 21#include <linux/kernel.h> 22#include <linux/sched.h> 23#include <linux/string.h> 24#include <linux/errno.h> 25#include <linux/slab.h> 26#include <linux/interrupt.h> 27#include <linux/init.h> 28#include <linux/delay.h> 29#include <linux/netdevice.h> 30#include <linux/etherdevice.h> 31#include <linux/skbuff.h> 32#include <linux/spinlock.h> 33#include <linux/mm.h> 34 35#include <asm/io.h> 36#include <asm/irq.h> 37#include <asm/uaccess.h> 38#include <linux/module.h> 39#include <linux/version.h> 40#include <linux/crc32.h> 41#include <linux/mii.h> 42 43#include "gianfar.h" 44#include "gianfar_phy.h" 45 46static void config_genmii_advert(struct gfar_mii_info *mii_info); 47static void genmii_setup_forced(struct gfar_mii_info *mii_info); 48static void genmii_restart_aneg(struct gfar_mii_info *mii_info); 49static int gbit_config_aneg(struct gfar_mii_info *mii_info); 50static int genmii_config_aneg(struct gfar_mii_info *mii_info); 51static int genmii_update_link(struct gfar_mii_info *mii_info); 52static int genmii_read_status(struct gfar_mii_info *mii_info); 53u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum); 54void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val); 55 56/* Write value to the PHY for this device to the register at regnum, */ 57/* waiting until the write is done before it returns. All PHY */ 58/* configuration has to be done through the TSEC1 MIIM regs */ 59void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) 60{ 61 struct gfar_private *priv = netdev_priv(dev); 62 struct gfar *regbase = priv->phyregs; 63 64 /* Set the PHY address and the register address we want to write */ 65 gfar_write(&regbase->miimadd, (mii_id << 8) | regnum); 66 67 /* Write out the value we want */ 68 gfar_write(&regbase->miimcon, value); 69 70 /* Wait for the transaction to finish */ 71 while (gfar_read(&regbase->miimind) & MIIMIND_BUSY) 72 cpu_relax(); 73} 74 75/* Reads from register regnum in the PHY for device dev, */ 76/* returning the value. Clears miimcom first. All PHY */ 77/* configuration has to be done through the TSEC1 MIIM regs */ 78int read_phy_reg(struct net_device *dev, int mii_id, int regnum) 79{ 80 struct gfar_private *priv = netdev_priv(dev); 81 struct gfar *regbase = priv->phyregs; 82 u16 value; 83 84 /* Set the PHY address and the register address we want to read */ 85 gfar_write(&regbase->miimadd, (mii_id << 8) | regnum); 86 87 /* Clear miimcom, and then initiate a read */ 88 gfar_write(&regbase->miimcom, 0); 89 gfar_write(&regbase->miimcom, MII_READ_COMMAND); 90 91 /* Wait for the transaction to finish */ 92 while (gfar_read(&regbase->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY)) 93 cpu_relax(); 94 95 /* Grab the value of the register from miimstat */ 96 value = gfar_read(&regbase->miimstat); 97 98 return value; 99} 100 101void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info) 102{ 103 if(mii_info->phyinfo->ack_interrupt) 104 mii_info->phyinfo->ack_interrupt(mii_info); 105} 106 107 108void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts) 109{ 110 mii_info->interrupts = interrupts; 111 if(mii_info->phyinfo->config_intr) 112 mii_info->phyinfo->config_intr(mii_info); 113} 114 115 116/* Writes MII_ADVERTISE with the appropriate values, after 117 * sanitizing advertise to make sure only supported features 118 * are advertised 119 */ 120static void config_genmii_advert(struct gfar_mii_info *mii_info) 121{ 122 u32 advertise; 123 u16 adv; 124 125 /* Only allow advertising what this PHY supports */ 126 mii_info->advertising &= mii_info->phyinfo->features; 127 advertise = mii_info->advertising; 128 129 /* Setup standard advertisement */ 130 adv = phy_read(mii_info, MII_ADVERTISE); 131 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 132 if (advertise & ADVERTISED_10baseT_Half) 133 adv |= ADVERTISE_10HALF; 134 if (advertise & ADVERTISED_10baseT_Full) 135 adv |= ADVERTISE_10FULL; 136 if (advertise & ADVERTISED_100baseT_Half) 137 adv |= ADVERTISE_100HALF; 138 if (advertise & ADVERTISED_100baseT_Full) 139 adv |= ADVERTISE_100FULL; 140 phy_write(mii_info, MII_ADVERTISE, adv); 141} 142 143static void genmii_setup_forced(struct gfar_mii_info *mii_info) 144{ 145 u16 ctrl; 146 u32 features = mii_info->phyinfo->features; 147 148 ctrl = phy_read(mii_info, MII_BMCR); 149 150 ctrl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPEED1000|BMCR_ANENABLE); 151 ctrl |= BMCR_RESET; 152 153 switch(mii_info->speed) { 154 case SPEED_1000: 155 if(features & (SUPPORTED_1000baseT_Half 156 | SUPPORTED_1000baseT_Full)) { 157 ctrl |= BMCR_SPEED1000; 158 break; 159 } 160 mii_info->speed = SPEED_100; 161 case SPEED_100: 162 if (features & (SUPPORTED_100baseT_Half 163 | SUPPORTED_100baseT_Full)) { 164 ctrl |= BMCR_SPEED100; 165 break; 166 } 167 mii_info->speed = SPEED_10; 168 case SPEED_10: 169 if (features & (SUPPORTED_10baseT_Half 170 | SUPPORTED_10baseT_Full)) 171 break; 172 default: /* Unsupported speed! */ 173 printk(KERN_ERR "%s: Bad speed!\n", 174 mii_info->dev->name); 175 break; 176 } 177 178 phy_write(mii_info, MII_BMCR, ctrl); 179} 180 181 182/* Enable and Restart Autonegotiation */ 183static void genmii_restart_aneg(struct gfar_mii_info *mii_info) 184{ 185 u16 ctl; 186 187 ctl = phy_read(mii_info, MII_BMCR); 188 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 189 phy_write(mii_info, MII_BMCR, ctl); 190} 191 192 193static int gbit_config_aneg(struct gfar_mii_info *mii_info) 194{ 195 u16 adv; 196 u32 advertise; 197 198 if(mii_info->autoneg) { 199 /* Configure the ADVERTISE register */ 200 config_genmii_advert(mii_info); 201 advertise = mii_info->advertising; 202 203 adv = phy_read(mii_info, MII_1000BASETCONTROL); 204 adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | 205 MII_1000BASETCONTROL_HALFDUPLEXCAP); 206 if (advertise & SUPPORTED_1000baseT_Half) 207 adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; 208 if (advertise & SUPPORTED_1000baseT_Full) 209 adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; 210 phy_write(mii_info, MII_1000BASETCONTROL, adv); 211 212 /* Start/Restart aneg */ 213 genmii_restart_aneg(mii_info); 214 } else 215 genmii_setup_forced(mii_info); 216 217 return 0; 218} 219 220static int marvell_config_aneg(struct gfar_mii_info *mii_info) 221{ 222 /* The Marvell PHY has an errata which requires 223 * that certain registers get written in order 224 * to restart autonegotiation */ 225 phy_write(mii_info, MII_BMCR, BMCR_RESET); 226 227 phy_write(mii_info, 0x1d, 0x1f); 228 phy_write(mii_info, 0x1e, 0x200c); 229 phy_write(mii_info, 0x1d, 0x5); 230 phy_write(mii_info, 0x1e, 0); 231 phy_write(mii_info, 0x1e, 0x100); 232 233 gbit_config_aneg(mii_info); 234 235 return 0; 236} 237static int genmii_config_aneg(struct gfar_mii_info *mii_info) 238{ 239 if (mii_info->autoneg) { 240 config_genmii_advert(mii_info); 241 genmii_restart_aneg(mii_info); 242 } else 243 genmii_setup_forced(mii_info); 244 245 return 0; 246} 247 248 249static int genmii_update_link(struct gfar_mii_info *mii_info) 250{ 251 u16 status; 252 253 /* Do a fake read */ 254 phy_read(mii_info, MII_BMSR); 255 256 /* Read link and autonegotiation status */ 257 status = phy_read(mii_info, MII_BMSR); 258 if ((status & BMSR_LSTATUS) == 0) 259 mii_info->link = 0; 260 else 261 mii_info->link = 1; 262 263 /* If we are autonegotiating, and not done, 264 * return an error */ 265 if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE)) 266 return -EAGAIN; 267 268 return 0; 269} 270 271static int genmii_read_status(struct gfar_mii_info *mii_info) 272{ 273 u16 status; 274 int err; 275 276 /* Update the link, but return if there 277 * was an error */ 278 err = genmii_update_link(mii_info); 279 if (err) 280 return err; 281 282 if (mii_info->autoneg) { 283 status = phy_read(mii_info, MII_LPA); 284 285 if (status & (LPA_10FULL | LPA_100FULL)) 286 mii_info->duplex = DUPLEX_FULL; 287 else 288 mii_info->duplex = DUPLEX_HALF; 289 if (status & (LPA_100FULL | LPA_100HALF)) 290 mii_info->speed = SPEED_100; 291 else 292 mii_info->speed = SPEED_10; 293 mii_info->pause = 0; 294 } 295 /* On non-aneg, we assume what we put in BMCR is the speed, 296 * though magic-aneg shouldn't prevent this case from occurring 297 */ 298 299 return 0; 300} 301static int marvell_read_status(struct gfar_mii_info *mii_info) 302{ 303 u16 status; 304 int err; 305 306 /* Update the link, but return if there 307 * was an error */ 308 err = genmii_update_link(mii_info); 309 if (err) 310 return err; 311 312 /* If the link is up, read the speed and duplex */ 313 /* If we aren't autonegotiating, assume speeds 314 * are as set */ 315 if (mii_info->autoneg && mii_info->link) { 316 int speed; 317 status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS); 318 319#if 0 320 /* If speed and duplex aren't resolved, 321 * return an error. Isn't this handled 322 * by checking aneg? 323 */ 324 if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0) 325 return -EAGAIN; 326#endif 327 328 /* Get the duplexity */ 329 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) 330 mii_info->duplex = DUPLEX_FULL; 331 else 332 mii_info->duplex = DUPLEX_HALF; 333 334 /* Get the speed */ 335 speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK; 336 switch(speed) { 337 case MII_M1011_PHY_SPEC_STATUS_1000: 338 mii_info->speed = SPEED_1000; 339 break; 340 case MII_M1011_PHY_SPEC_STATUS_100: 341 mii_info->speed = SPEED_100; 342 break; 343 default: 344 mii_info->speed = SPEED_10; 345 break; 346 } 347 mii_info->pause = 0; 348 } 349 350 return 0; 351} 352 353 354static int cis820x_read_status(struct gfar_mii_info *mii_info) 355{ 356 u16 status; 357 int err; 358 359 /* Update the link, but return if there 360 * was an error */ 361 err = genmii_update_link(mii_info); 362 if (err) 363 return err; 364 365 /* If the link is up, read the speed and duplex */ 366 /* If we aren't autonegotiating, assume speeds 367 * are as set */ 368 if (mii_info->autoneg && mii_info->link) { 369 int speed; 370 371 status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT); 372 if (status & MII_CIS8201_AUXCONSTAT_DUPLEX) 373 mii_info->duplex = DUPLEX_FULL; 374 else 375 mii_info->duplex = DUPLEX_HALF; 376 377 speed = status & MII_CIS8201_AUXCONSTAT_SPEED; 378 379 switch (speed) { 380 case MII_CIS8201_AUXCONSTAT_GBIT: 381 mii_info->speed = SPEED_1000; 382 break; 383 case MII_CIS8201_AUXCONSTAT_100: 384 mii_info->speed = SPEED_100; 385 break; 386 default: 387 mii_info->speed = SPEED_10; 388 break; 389 } 390 } 391 392 return 0; 393} 394 395static int marvell_ack_interrupt(struct gfar_mii_info *mii_info) 396{ 397 /* Clear the interrupts by reading the reg */ 398 phy_read(mii_info, MII_M1011_IEVENT); 399 400 return 0; 401} 402 403static int marvell_config_intr(struct gfar_mii_info *mii_info) 404{ 405 if(mii_info->interrupts == MII_INTERRUPT_ENABLED) 406 phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 407 else 408 phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); 409 410 return 0; 411} 412 413static int cis820x_init(struct gfar_mii_info *mii_info) 414{ 415 phy_write(mii_info, MII_CIS8201_AUX_CONSTAT, 416 MII_CIS8201_AUXCONSTAT_INIT); 417 phy_write(mii_info, MII_CIS8201_EXT_CON1, 418 MII_CIS8201_EXTCON1_INIT); 419 420 return 0; 421} 422 423static int cis820x_ack_interrupt(struct gfar_mii_info *mii_info) 424{ 425 phy_read(mii_info, MII_CIS8201_ISTAT); 426 427 return 0; 428} 429 430static int cis820x_config_intr(struct gfar_mii_info *mii_info) 431{ 432 if(mii_info->interrupts == MII_INTERRUPT_ENABLED) 433 phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK); 434 else 435 phy_write(mii_info, MII_CIS8201_IMASK, 0); 436 437 return 0; 438} 439 440#define DM9161_DELAY 10 441 442static int dm9161_read_status(struct gfar_mii_info *mii_info) 443{ 444 u16 status; 445 int err; 446 447 /* Update the link, but return if there 448 * was an error */ 449 err = genmii_update_link(mii_info); 450 if (err) 451 return err; 452 453 /* If the link is up, read the speed and duplex */ 454 /* If we aren't autonegotiating, assume speeds 455 * are as set */ 456 if (mii_info->autoneg && mii_info->link) { 457 status = phy_read(mii_info, MII_DM9161_SCSR); 458 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) 459 mii_info->speed = SPEED_100; 460 else 461 mii_info->speed = SPEED_10; 462 463 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F)) 464 mii_info->duplex = DUPLEX_FULL; 465 else 466 mii_info->duplex = DUPLEX_HALF; 467 } 468 469 return 0; 470} 471 472 473static int dm9161_config_aneg(struct gfar_mii_info *mii_info) 474{ 475 struct dm9161_private *priv = mii_info->priv; 476 477 if(0 == priv->resetdone) 478 return -EAGAIN; 479 480 return 0; 481} 482 483static void dm9161_timer(unsigned long data) 484{ 485 struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data; 486 struct dm9161_private *priv = mii_info->priv; 487 u16 status = phy_read(mii_info, MII_BMSR); 488 489 if (status & BMSR_ANEGCOMPLETE) { 490 priv->resetdone = 1; 491 } else 492 mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ); 493} 494 495static int dm9161_init(struct gfar_mii_info *mii_info) 496{ 497 struct dm9161_private *priv; 498 499 /* Allocate the private data structure */ 500 priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL); 501 502 if (NULL == priv) 503 return -ENOMEM; 504 505 mii_info->priv = priv; 506 507 /* Reset is not done yet */ 508 priv->resetdone = 0; 509 510 /* Isolate the PHY */ 511 phy_write(mii_info, MII_BMCR, BMCR_ISOLATE); 512 513 /* Do not bypass the scrambler/descrambler */ 514 phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT); 515 516 /* Clear 10BTCSR to default */ 517 phy_write(mii_info, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT); 518 519 /* Reconnect the PHY, and enable Autonegotiation */ 520 phy_write(mii_info, MII_BMCR, BMCR_ANENABLE); 521 522 /* Start a timer for DM9161_DELAY seconds to wait 523 * for the PHY to be ready */ 524 init_timer(&priv->timer); 525 priv->timer.function = &dm9161_timer; 526 priv->timer.data = (unsigned long) mii_info; 527 mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ); 528 529 return 0; 530} 531 532static void dm9161_close(struct gfar_mii_info *mii_info) 533{ 534 struct dm9161_private *priv = mii_info->priv; 535 536 del_timer_sync(&priv->timer); 537 kfree(priv); 538} 539 540#if 0 541static int dm9161_ack_interrupt(struct gfar_mii_info *mii_info) 542{ 543 phy_read(mii_info, MII_DM9161_INTR); 544 545 return 0; 546} 547#endif 548 549/* Cicada 820x */ 550static struct phy_info phy_info_cis820x = { 551 0x000fc440, 552 "Cicada Cis8204", 553 0x000fffc0, 554 .features = MII_GBIT_FEATURES, 555 .init = &cis820x_init, 556 .config_aneg = &gbit_config_aneg, 557 .read_status = &cis820x_read_status, 558 .ack_interrupt = &cis820x_ack_interrupt, 559 .config_intr = &cis820x_config_intr, 560}; 561 562static struct phy_info phy_info_dm9161 = { 563 .phy_id = 0x0181b880, 564 .name = "Davicom DM9161E", 565 .phy_id_mask = 0x0ffffff0, 566 .init = dm9161_init, 567 .config_aneg = dm9161_config_aneg, 568 .read_status = dm9161_read_status, 569 .close = dm9161_close, 570}; 571 572static struct phy_info phy_info_marvell = { 573 .phy_id = 0x01410c00, 574 .phy_id_mask = 0xffffff00, 575 .name = "Marvell 88E1101/88E1111", 576 .features = MII_GBIT_FEATURES, 577 .config_aneg = &marvell_config_aneg, 578 .read_status = &marvell_read_status, 579 .ack_interrupt = &marvell_ack_interrupt, 580 .config_intr = &marvell_config_intr, 581}; 582 583static struct phy_info phy_info_genmii= { 584 .phy_id = 0x00000000, 585 .phy_id_mask = 0x00000000, 586 .name = "Generic MII", 587 .features = MII_BASIC_FEATURES, 588 .config_aneg = genmii_config_aneg, 589 .read_status = genmii_read_status, 590}; 591 592static struct phy_info *phy_info[] = { 593 &phy_info_cis820x, 594 &phy_info_marvell, 595 &phy_info_dm9161, 596 &phy_info_genmii, 597 NULL 598}; 599 600u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum) 601{ 602 u16 retval; 603 unsigned long flags; 604 605 spin_lock_irqsave(&mii_info->mdio_lock, flags); 606 retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum); 607 spin_unlock_irqrestore(&mii_info->mdio_lock, flags); 608 609 return retval; 610} 611 612void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val) 613{ 614 unsigned long flags; 615 616 spin_lock_irqsave(&mii_info->mdio_lock, flags); 617 mii_info->mdio_write(mii_info->dev, 618 mii_info->mii_id, 619 regnum, val); 620 spin_unlock_irqrestore(&mii_info->mdio_lock, flags); 621} 622 623/* Use the PHY ID registers to determine what type of PHY is attached 624 * to device dev. return a struct phy_info structure describing that PHY 625 */ 626struct phy_info * get_phy_info(struct gfar_mii_info *mii_info) 627{ 628 u16 phy_reg; 629 u32 phy_ID; 630 int i; 631 struct phy_info *theInfo = NULL; 632 struct net_device *dev = mii_info->dev; 633 634 /* Grab the bits from PHYIR1, and put them in the upper half */ 635 phy_reg = phy_read(mii_info, MII_PHYSID1); 636 phy_ID = (phy_reg & 0xffff) << 16; 637 638 /* Grab the bits from PHYIR2, and put them in the lower half */ 639 phy_reg = phy_read(mii_info, MII_PHYSID2); 640 phy_ID |= (phy_reg & 0xffff); 641 642 /* loop through all the known PHY types, and find one that */ 643 /* matches the ID we read from the PHY. */ 644 for (i = 0; phy_info[i]; i++) 645 if (phy_info[i]->phy_id == 646 (phy_ID & phy_info[i]->phy_id_mask)) { 647 theInfo = phy_info[i]; 648 break; 649 } 650 651 /* This shouldn't happen, as we have generic PHY support */ 652 if (theInfo == NULL) { 653 printk("%s: PHY id %x is not supported!\n", dev->name, phy_ID); 654 return NULL; 655 } else { 656 printk("%s: PHY is %s (%x)\n", dev->name, theInfo->name, 657 phy_ID); 658 } 659 660 return theInfo; 661}