11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PHY drivers for the sungem ethernet driver. 36aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file could be shared with other drivers. 56aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik * 663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt * (c) 2002-2007, Benjamin Herrenscmidt (benh@kernel.crashing.org) 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TODO: 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Add support for PHYs that provide an IRQ line 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Eventually moved the entire polling state machine in 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * there (out of the eth driver), so that it can easily be 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * skipped on PHYs that implement it in hardware. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - On LXT971 & BCM5201, Apple uses some chip specific regs 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to read the link status. Figure out why and if it makes 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sense to do the same (magic aneg ?) 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Apple has some additional power management code for some 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Broadcom PHYs that they "hide" from the OpenSource version 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of darwin, still need to reverse engineer that 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/netdevice.h> 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/etherdevice.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mii.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ethtool.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 323c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt#ifdef CONFIG_PPC_PMAC 333c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt#include <asm/prom.h> 343c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt#endif 353c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt 36ef37d38a1fe78ba627b8178af02df31e59b18896Stephen Rothwell#include <linux/sungem_phy.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Link modes of the BCM5400 PHY */ 39f71e130966ba429dbd24be08ddbcdf263df9a5adArjan van de Venstatic const int phy_BCM5400_link_table[8][3] = { 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0, 0, 0 }, /* No link */ 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0, 0, 0 }, /* 10BT Half Duplex */ 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1, 0, 0 }, /* 10BT Full Duplex */ 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0, 1, 0 }, /* 100BT Half Duplex */ 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0, 1, 0 }, /* 100BT Half Duplex */ 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1, 1, 0 }, /* 100BT Full Duplex*/ 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1, 0, 1 }, /* 1000BT */ 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1, 0, 1 }, /* 1000BT */ 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50abc4da4503bf6cb1864454b464c52959241239bdDavid S. Millerstatic inline int __sungem_phy_read(struct mii_phy* phy, int id, int reg) 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return phy->mdio_read(phy->dev, id, reg); 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55abc4da4503bf6cb1864454b464c52959241239bdDavid S. Millerstatic inline void __sungem_phy_write(struct mii_phy* phy, int id, int reg, int val) 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->mdio_write(phy->dev, id, reg, val); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 60abc4da4503bf6cb1864454b464c52959241239bdDavid S. Millerstatic inline int sungem_phy_read(struct mii_phy* phy, int reg) 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return phy->mdio_read(phy->dev, phy->mii_id, reg); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 65abc4da4503bf6cb1864454b464c52959241239bdDavid S. Millerstatic inline void sungem_phy_write(struct mii_phy* phy, int reg, int val) 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->mdio_write(phy->dev, phy->mii_id, reg, val); 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int reset_one_mii_phy(struct mii_phy* phy, int phy_id) 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 val; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int limit = 10000; 746aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 75abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller val = __sungem_phy_read(phy, phy_id, MII_BMCR); 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val &= ~(BMCR_ISOLATE | BMCR_PDOWN); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= BMCR_RESET; 78abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller __sungem_phy_write(phy, phy_id, MII_BMCR, val); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(100); 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 82ff01b9163655ace76b29b7ff2f56b25c32f795daRoel Kluin while (--limit) { 83abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller val = __sungem_phy_read(phy, phy_id, MII_BMCR); 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((val & BMCR_RESET) == 0) 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(10); 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((val & BMCR_ISOLATE) && limit > 0) 89abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller __sungem_phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE); 906aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 91807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return limit <= 0; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5201_init(struct mii_phy* phy) 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 data; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 98abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5201_MULTIPHY); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE; 100abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5201_MULTIPHY, data); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 102abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5201_INTERRUPT, 0); 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5201_suspend(struct mii_phy* phy) 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 109abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5201_INTERRUPT, 0); 110abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE); 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5221_init(struct mii_phy* phy) 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 data; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 119abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_TEST); 120abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_TEST, 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data | MII_BCM5221_TEST_ENABLE_SHADOWS); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 123abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_STAT2); 124abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_STAT2, 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data | MII_BCM5221_SHDOW_AUX_STAT2_APD); 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 127abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); 128abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data | MII_BCM5221_SHDOW_AUX_MODE4_CLKLOPWR); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_TEST); 132abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_TEST, 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data & ~MII_BCM5221_TEST_ENABLE_SHADOWS); 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5221_suspend(struct mii_phy* phy) 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 data; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 142abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_TEST); 143abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_TEST, 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data | MII_BCM5221_TEST_ENABLE_SHADOWS); 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 146abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); 147abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data | MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic int bcm5241_init(struct mii_phy* phy) 15463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt{ 15563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt u16 data; 15663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 157abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_TEST); 158abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_TEST, 15963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt data | MII_BCM5221_TEST_ENABLE_SHADOWS); 16063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 161abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_STAT2); 162abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_STAT2, 16363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt data | MII_BCM5221_SHDOW_AUX_STAT2_APD); 16463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 165abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); 166abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, 16763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt data & ~MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR); 16863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 169abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_TEST); 170abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_TEST, 17163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt data & ~MII_BCM5221_TEST_ENABLE_SHADOWS); 17263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 17363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt return 0; 17463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt} 17563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 17663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic int bcm5241_suspend(struct mii_phy* phy) 17763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt{ 17863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt u16 data; 17963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 180abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_TEST); 181abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_TEST, 18263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt data | MII_BCM5221_TEST_ENABLE_SHADOWS); 18363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 184abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); 185abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, 18663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt data | MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR); 18763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 18863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt return 0; 18963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt} 19063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5400_init(struct mii_phy* phy) 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 data; 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Configure for gigabit full duplex */ 196abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5400_AUXCONTROL); 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data |= MII_BCM5400_AUXCONTROL_PWR10BASET; 198abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5400_AUXCONTROL, data); 1996aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 200abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5400_GB_CONTROL); 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; 202abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5400_GB_CONTROL, data); 2036aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(100); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reset and configure cascaded 10/100 PHY */ 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void)reset_one_mii_phy(phy, 0x1f); 2086aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 209abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = __sungem_phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data |= MII_BCM5201_MULTIPHY_SERIALMODE; 211abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller __sungem_phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 213abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5400_AUXCONTROL); 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data &= ~MII_BCM5400_AUXCONTROL_PWR10BASET; 215abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5400_AUXCONTROL, data); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5400_suspend(struct mii_phy* phy) 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 /* Commented out in Darwin... someone has those dawn docs ? */ 223abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, BMCR_PDOWN); 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5401_init(struct mii_phy* phy) 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 data; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rev; 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 233abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller rev = sungem_phy_read(phy, MII_PHYSID2) & 0x000f; 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rev == 0 || rev == 3) { 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Some revisions of 5401 appear to need this 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * initialisation sequence to disable, according 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to OF, "tap power management" 2386aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik * 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * WARNING ! OF and Darwin don't agree on the 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * register addresses. OF seem to interpret the 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * register numbers below as decimal 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: This should (and does) match tg3_init_5401phy_dsp 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in the tg3.c driver. -DaveM 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 246abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x18, 0x0c20); 247abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x17, 0x0012); 248abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x15, 0x1804); 249abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x17, 0x0013); 250abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x15, 0x1204); 251abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x17, 0x8006); 252abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x15, 0x0132); 253abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x17, 0x8006); 254abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x15, 0x0232); 255abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x17, 0x201f); 256abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x15, 0x0a20); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2586aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Configure for gigabit full duplex */ 260abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5400_GB_CONTROL); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; 262abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5400_GB_CONTROL, data); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(10); 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reset and configure cascaded 10/100 PHY */ 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void)reset_one_mii_phy(phy, 0x1f); 2686aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 269abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = __sungem_phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data |= MII_BCM5201_MULTIPHY_SERIALMODE; 271abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller __sungem_phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data); 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5401_suspend(struct mii_phy* phy) 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 /* Commented out in Darwin... someone has those dawn docs ? */ 279abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, BMCR_PDOWN); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5411_init(struct mii_phy* phy) 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 data; 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Here's some more Apple black magic to setup 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * some voltage stuffs. 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 291abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1c, 0x8c23); 292abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1c, 0x8ca3); 293abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1c, 0x8c23); 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Here, Apple seems to want to reset it, do 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it as well 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 298abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, BMCR_RESET); 299abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, 0x1340); 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, MII_BCM5400_GB_CONTROL); 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; 303abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BCM5400_GB_CONTROL, data); 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(10); 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reset and configure cascaded 10/100 PHY */ 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void)reset_one_mii_phy(phy, 0x1f); 3096aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 313eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int genmii_setup_aneg(struct mii_phy *phy, u32 advertise) 314eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 315eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp u16 ctl, adv; 316eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 317eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->autoneg = 1; 318eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->speed = SPEED_10; 319eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->duplex = DUPLEX_HALF; 320eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->pause = 0; 321eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->advertising = advertise; 322eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 323eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* Setup standard advertise */ 324abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller adv = sungem_phy_read(phy, MII_ADVERTISE); 325eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 326eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (advertise & ADVERTISED_10baseT_Half) 327eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp adv |= ADVERTISE_10HALF; 328eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (advertise & ADVERTISED_10baseT_Full) 329eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp adv |= ADVERTISE_10FULL; 330eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (advertise & ADVERTISED_100baseT_Half) 331eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp adv |= ADVERTISE_100HALF; 332eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (advertise & ADVERTISED_100baseT_Full) 333eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp adv |= ADVERTISE_100FULL; 334abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_ADVERTISE, adv); 335eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 336eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* Start/Restart aneg */ 337abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller ctl = sungem_phy_read(phy, MII_BMCR); 338eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 339abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, ctl); 340eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 341eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 342eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 343eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 344eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int genmii_setup_forced(struct mii_phy *phy, int speed, int fd) 345eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 346eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp u16 ctl; 347eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 348eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->autoneg = 0; 349eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->speed = speed; 350eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->duplex = fd; 351eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->pause = 0; 352eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 353abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller ctl = sungem_phy_read(phy, MII_BMCR); 354eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE); 355eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 356eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* First reset the PHY */ 357abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, ctl | BMCR_RESET); 358eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 359eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* Select speed & duplex */ 360eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp switch(speed) { 361eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp case SPEED_10: 362eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp break; 363eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp case SPEED_100: 364eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp ctl |= BMCR_SPEED100; 365eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp break; 366eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp case SPEED_1000: 367eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp default: 368eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return -EINVAL; 369eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp } 370eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (fd == DUPLEX_FULL) 371eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp ctl |= BMCR_FULLDPLX; 372abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, ctl); 373eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 374eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 375eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 376eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 377eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int genmii_poll_link(struct mii_phy *phy) 378eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 379eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp u16 status; 380eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 381abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller (void)sungem_phy_read(phy, MII_BMSR); 382abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller status = sungem_phy_read(phy, MII_BMSR); 383eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if ((status & BMSR_LSTATUS) == 0) 384eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 385eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE)) 386eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 387eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 1; 388eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 389eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 390eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int genmii_read_link(struct mii_phy *phy) 391eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 392eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp u16 lpa; 393eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 394eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (phy->autoneg) { 395abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller lpa = sungem_phy_read(phy, MII_LPA); 396eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 397eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (lpa & (LPA_10FULL | LPA_100FULL)) 398eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->duplex = DUPLEX_FULL; 399eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp else 400eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->duplex = DUPLEX_HALF; 401eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (lpa & (LPA_100FULL | LPA_100HALF)) 402eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->speed = SPEED_100; 403eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp else 404eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->speed = SPEED_10; 405eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->pause = 0; 406eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp } 407eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* On non-aneg, we assume what we put in BMCR is the speed, 408eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp * though magic-aneg shouldn't prevent this case from occurring 409eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp */ 410eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 411eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 412eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 413eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 414d47f3640fe2ac4da8a8e713a549e6eaf23ac2084Johannes Bergstatic int generic_suspend(struct mii_phy* phy) 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 416abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, BMCR_PDOWN); 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm5421_init(struct mii_phy* phy) 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 data; 4243c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt unsigned int id; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 426abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller id = (sungem_phy_read(phy, MII_PHYSID1) << 16 | sungem_phy_read(phy, MII_PHYSID2)); 4273c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt 4283c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt /* Revision 0 of 5421 needs some fixups */ 4293c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt if (id == 0x002060e0) { 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This is borrowed from MacOS 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 432abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x18, 0x1007); 433abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, 0x18); 434abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x18, data | 0x0400); 435abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x18, 0x0007); 436abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, 0x18); 437abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x18, data | 0x0800); 438abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x17, 0x000a); 439abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller data = sungem_phy_read(phy, 0x15); 440abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x15, data | 0x0200); 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4433c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt /* Pick up some init code from OF for K2 version */ 4443c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt if ((id & 0xfffffff0) == 0x002062e0) { 445abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 4, 0x01e1); 446abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 9, 0x0300); 4473c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt } 4483c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt 4493c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt /* Check if we can enable automatic low power */ 4503c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt#ifdef CONFIG_PPC_PMAC 4513c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt if (phy->platform_data) { 4523c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt struct device_node *np = of_get_parent(phy->platform_data); 4533c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt int can_low_power = 1; 45440cd3a4564ed6b7bc0279430120ca0e9b83cf486Stephen Rothwell if (np == NULL || of_get_property(np, "no-autolowpower", NULL)) 4553c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt can_low_power = 0; 4563c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt if (can_low_power) { 4573c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt /* Enable automatic low-power */ 458abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1c, 0x9002); 459abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1c, 0xa821); 460abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1c, 0x941d); 4613c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt } 4623c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt } 4633c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt#endif /* CONFIG_PPC_PMAC */ 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise) 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 ctl, adv; 4716aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->autoneg = 1; 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->speed = SPEED_10; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->duplex = DUPLEX_HALF; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->pause = 0; 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->advertising = advertise; 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Setup standard advertise */ 479abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller adv = sungem_phy_read(phy, MII_ADVERTISE); 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & ADVERTISED_10baseT_Half) 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= ADVERTISE_10HALF; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & ADVERTISED_10baseT_Full) 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= ADVERTISE_10FULL; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & ADVERTISED_100baseT_Half) 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= ADVERTISE_100HALF; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & ADVERTISED_100baseT_Full) 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= ADVERTISE_100FULL; 48963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt if (advertise & ADVERTISED_Pause) 49063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt adv |= ADVERTISE_PAUSE_CAP; 49163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt if (advertise & ADVERTISED_Asym_Pause) 49263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt adv |= ADVERTISE_PAUSE_ASYM; 493abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_ADVERTISE, adv); 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Setup 1000BT advertise */ 496abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller adv = sungem_phy_read(phy, MII_1000BASETCONTROL); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP|MII_1000BASETCONTROL_HALFDUPLEXCAP); 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & SUPPORTED_1000baseT_Half) 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & SUPPORTED_1000baseT_Full) 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; 502abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_1000BASETCONTROL, adv); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start/Restart aneg */ 505abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller ctl = sungem_phy_read(phy, MII_BMCR); 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 507abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, ctl); 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm54xx_setup_forced(struct mii_phy *phy, int speed, int fd) 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 ctl; 5156aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->autoneg = 0; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->speed = speed; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->duplex = fd; 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->pause = 0; 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller ctl = sungem_phy_read(phy, MII_BMCR); 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* First reset the PHY */ 525abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, ctl | BMCR_RESET); 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Select speed & duplex */ 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(speed) { 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SPEED_10: 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SPEED_100: 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl |= BMCR_SPEED100; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SPEED_1000: 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl |= BMCR_SPD2; 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fd == DUPLEX_FULL) 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl |= BMCR_FULLDPLX; 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // XXX Should we set the sungem to GII now on 1000BT ? 5416aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 542abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, ctl); 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bcm54xx_read_link(struct mii_phy *phy) 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5496aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik int link_mode; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 val; 5516aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (phy->autoneg) { 553abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller val = sungem_phy_read(phy, MII_BCM5400_AUXSTATUS); 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >> 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT); 55663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt phy->duplex = phy_BCM5400_link_table[link_mode][0] ? 55763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt DUPLEX_FULL : DUPLEX_HALF; 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->speed = phy_BCM5400_link_table[link_mode][2] ? 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SPEED_1000 : 56063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt (phy_BCM5400_link_table[link_mode][1] ? 56163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt SPEED_100 : SPEED_10); 562abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller val = sungem_phy_read(phy, MII_LPA); 56363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt phy->pause = (phy->duplex == DUPLEX_FULL) && 56463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt ((val & LPA_PAUSE) != 0); 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* On non-aneg, we assume what we put in BMCR is the speed, 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * though magic-aneg shouldn't prevent this case from occurring 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 57363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic int marvell88e1111_init(struct mii_phy* phy) 57463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt{ 57563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt u16 rev; 57663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 57763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt /* magic init sequence for rev 0 */ 578abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller rev = sungem_phy_read(phy, MII_PHYSID2) & 0x000f; 57963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt if (rev == 0) { 580abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1d, 0x000a); 581abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1e, 0x0821); 58263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 583abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1d, 0x0006); 584abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1e, 0x8600); 58563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 586abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1d, 0x000b); 587abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1e, 0x0100); 58863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 589abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1d, 0x0004); 590abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x1e, 0x4850); 59163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt } 59263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt return 0; 59363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt} 59463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 595eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp#define BCM5421_MODE_MASK (1 << 5) 596eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 597eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int bcm5421_poll_link(struct mii_phy* phy) 598eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 599eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp u32 phy_reg; 600eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp int mode; 601eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 602eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* find out in what mode we are */ 603abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x1000); 604abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller phy_reg = sungem_phy_read(phy, MII_NCONFIG); 605eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 606eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp mode = (phy_reg & BCM5421_MODE_MASK) >> 5; 607eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 608eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if ( mode == BCM54XX_COPPER) 609eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return genmii_poll_link(phy); 610eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 61148fc7f7e787dd65ffe88521bce31f4062ba273ebAdam Buchbinder /* try to find out whether we have a link */ 612abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x2000); 613abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller phy_reg = sungem_phy_read(phy, MII_NCONFIG); 614eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 615eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (phy_reg & 0x0020) 616eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 617eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp else 618eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 1; 619eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 620eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 621eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int bcm5421_read_link(struct mii_phy* phy) 622eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 623eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp u32 phy_reg; 624eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp int mode; 625eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 626eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* find out in what mode we are */ 627abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x1000); 628abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller phy_reg = sungem_phy_read(phy, MII_NCONFIG); 629eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 630eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp mode = (phy_reg & BCM5421_MODE_MASK ) >> 5; 631eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 632eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if ( mode == BCM54XX_COPPER) 633eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return bcm54xx_read_link(phy); 634eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 635eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->speed = SPEED_1000; 636eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 63748fc7f7e787dd65ffe88521bce31f4062ba273ebAdam Buchbinder /* find out whether we are running half- or full duplex */ 638abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x2000); 639abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller phy_reg = sungem_phy_read(phy, MII_NCONFIG); 640eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 641eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if ( (phy_reg & 0x0080) >> 7) 642eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->duplex |= DUPLEX_HALF; 643eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp else 644eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->duplex |= DUPLEX_FULL; 645eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 646eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 647eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 648eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 649eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int bcm5421_enable_fiber(struct mii_phy* phy, int autoneg) 650eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 651eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* enable fiber mode */ 652abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x9020); 653eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* LEDs active in both modes, autosense prio = fiber */ 654abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x945f); 655eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 656eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (!autoneg) { 657eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* switch off fibre autoneg */ 658abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0xfc01); 659abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, 0x0b, 0x0004); 660eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp } 661eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 662eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->autoneg = autoneg; 663eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 664eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 665eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 666eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 667eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp#define BCM5461_FIBER_LINK (1 << 2) 668eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp#define BCM5461_MODE_MASK (3 << 1) 669eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 670eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int bcm5461_poll_link(struct mii_phy* phy) 671eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 672eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp u32 phy_reg; 673eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp int mode; 674eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 675eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* find out in what mode we are */ 676abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x7c00); 677abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller phy_reg = sungem_phy_read(phy, MII_NCONFIG); 678eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 679eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp mode = (phy_reg & BCM5461_MODE_MASK ) >> 1; 680eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 681eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if ( mode == BCM54XX_COPPER) 682eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return genmii_poll_link(phy); 683eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 68448fc7f7e787dd65ffe88521bce31f4062ba273ebAdam Buchbinder /* find out whether we have a link */ 685abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x7000); 686abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller phy_reg = sungem_phy_read(phy, MII_NCONFIG); 687eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 688eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (phy_reg & BCM5461_FIBER_LINK) 689eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 1; 690eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp else 691eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 692eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 693eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 694eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp#define BCM5461_FIBER_DUPLEX (1 << 3) 695eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 696eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int bcm5461_read_link(struct mii_phy* phy) 697eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 698eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp u32 phy_reg; 699eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp int mode; 700eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 701eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* find out in what mode we are */ 702abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x7c00); 703abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller phy_reg = sungem_phy_read(phy, MII_NCONFIG); 704eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 705eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp mode = (phy_reg & BCM5461_MODE_MASK ) >> 1; 706eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 707eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if ( mode == BCM54XX_COPPER) { 708eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return bcm54xx_read_link(phy); 709eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp } 710eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 711eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->speed = SPEED_1000; 712eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 71348fc7f7e787dd65ffe88521bce31f4062ba273ebAdam Buchbinder /* find out whether we are running half- or full duplex */ 714abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0x7000); 715abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller phy_reg = sungem_phy_read(phy, MII_NCONFIG); 716eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 717eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (phy_reg & BCM5461_FIBER_DUPLEX) 718eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->duplex |= DUPLEX_FULL; 719eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp else 720eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->duplex |= DUPLEX_HALF; 721eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 722eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 723eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 724eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 725eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkampstatic int bcm5461_enable_fiber(struct mii_phy* phy, int autoneg) 726eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp{ 727eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* select fiber mode, enable 1000 base-X registers */ 728abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_NCONFIG, 0xfc0b); 729eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 730eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp if (autoneg) { 731eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* enable fiber with no autonegotiation */ 732abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_ADVERTISE, 0x01e0); 733abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, 0x1140); 734eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp } else { 735eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp /* enable fiber with autonegotiation */ 736abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, 0x0140); 737eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp } 738eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 739eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp phy->autoneg = autoneg; 740eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 741eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp return 0; 742eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp} 743eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int marvell_setup_aneg(struct mii_phy *phy, u32 advertise) 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 ctl, adv; 7476aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->autoneg = 1; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->speed = SPEED_10; 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->duplex = DUPLEX_HALF; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->pause = 0; 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->advertising = advertise; 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Setup standard advertise */ 755abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller adv = sungem_phy_read(phy, MII_ADVERTISE); 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & ADVERTISED_10baseT_Half) 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= ADVERTISE_10HALF; 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & ADVERTISED_10baseT_Full) 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= ADVERTISE_10FULL; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & ADVERTISED_100baseT_Half) 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= ADVERTISE_100HALF; 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & ADVERTISED_100baseT_Full) 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= ADVERTISE_100FULL; 76563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt if (advertise & ADVERTISED_Pause) 76663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt adv |= ADVERTISE_PAUSE_CAP; 76763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt if (advertise & ADVERTISED_Asym_Pause) 76863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt adv |= ADVERTISE_PAUSE_ASYM; 769abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_ADVERTISE, adv); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Setup 1000BT advertise & enable crossover detect 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * XXX How do we advertise 1000BT ? Darwin source is 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * confusing here, they read from specific control and 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * write to control... Someone has specs for those 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * beasts ? 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 777abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller adv = sungem_phy_read(phy, MII_M1011_PHY_SPEC_CONTROL); 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX; 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MII_1000BASETCONTROL_HALFDUPLEXCAP); 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & SUPPORTED_1000baseT_Half) 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (advertise & SUPPORTED_1000baseT_Full) 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; 785abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_1000BASETCONTROL, adv); 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start/Restart aneg */ 788abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller ctl = sungem_phy_read(phy, MII_BMCR); 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 790abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, ctl); 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int marvell_setup_forced(struct mii_phy *phy, int speed, int fd) 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 ctl, ctl2; 7986aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->autoneg = 0; 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->speed = speed; 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->duplex = fd; 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->pause = 0; 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 804abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller ctl = sungem_phy_read(phy, MII_BMCR); 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE); 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl |= BMCR_RESET; 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Select speed & duplex */ 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(speed) { 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SPEED_10: 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SPEED_100: 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl |= BMCR_SPEED100; 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* I'm not sure about the one below, again, Darwin source is 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * quite confusing and I lack chip specs 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SPEED_1000: 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl |= BMCR_SPD2; 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fd == DUPLEX_FULL) 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl |= BMCR_FULLDPLX; 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable crossover. Again, the way Apple does it is strange, 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * though I don't assume they are wrong ;) 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 827abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller ctl2 = sungem_phy_read(phy, MII_M1011_PHY_SPEC_CONTROL); 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl2 &= ~(MII_M1011_PHY_SPEC_CONTROL_MANUAL_MDIX | 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX | 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MII_1000BASETCONTROL_FULLDUPLEXCAP | 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MII_1000BASETCONTROL_HALFDUPLEXCAP); 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (speed == SPEED_1000) 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ctl2 |= (fd == DUPLEX_FULL) ? 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MII_1000BASETCONTROL_FULLDUPLEXCAP : 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MII_1000BASETCONTROL_HALFDUPLEXCAP; 836abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_1000BASETCONTROL, ctl2); 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // XXX Should we set the sungem to GII now on 1000BT ? 8396aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 840abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller sungem_phy_write(phy, MII_BMCR, ctl); 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int marvell_read_link(struct mii_phy *phy) 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 84763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt u16 status, pmask; 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (phy->autoneg) { 850abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller status = sungem_phy_read(phy, MII_M1011_PHY_SPEC_STATUS); 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0) 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EAGAIN; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & MII_M1011_PHY_SPEC_STATUS_1000) 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->speed = SPEED_1000; 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (status & MII_M1011_PHY_SPEC_STATUS_100) 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->speed = SPEED_100; 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->speed = SPEED_10; 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->duplex = DUPLEX_FULL; 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->duplex = DUPLEX_HALF; 86363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt pmask = MII_M1011_PHY_SPEC_STATUS_TX_PAUSE | 86463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt MII_M1011_PHY_SPEC_STATUS_RX_PAUSE; 86563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt phy->pause = (status & pmask) == pmask; 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* On non-aneg, we assume what we put in BMCR is the speed, 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * though magic-aneg shouldn't prevent this case from occurring 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 87463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt#define MII_BASIC_FEATURES \ 87563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ 87663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ 87763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | \ 87863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt SUPPORTED_Pause) 87963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 88063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt/* On gigabit capable PHYs, we advertise Pause support but not asym pause 88163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt * support for now as I'm not sure it's supported and Darwin doesn't do 88263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt * it neither. --BenH. 88363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt */ 88463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt#define MII_GBIT_FEATURES \ 88563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt (MII_BASIC_FEATURES | \ 88663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full) 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Broadcom BCM 5201 */ 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_ops bcm5201_phy_ops = { 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = bcm5201_init, 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .suspend = bcm5201_suspend, 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_aneg = genmii_setup_aneg, 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_forced = genmii_setup_forced, 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll_link = genmii_poll_link, 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_link = genmii_read_link, 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_def bcm5201_phy_def = { 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id = 0x00406210, 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id_mask = 0xfffffff0, 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "BCM5201", 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .features = MII_BASIC_FEATURES, 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .magic_aneg = 1, 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ops = &bcm5201_phy_ops 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Broadcom BCM 5221 */ 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_ops bcm5221_phy_ops = { 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .suspend = bcm5221_suspend, 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = bcm5221_init, 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_aneg = genmii_setup_aneg, 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_forced = genmii_setup_forced, 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll_link = genmii_poll_link, 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_link = genmii_read_link, 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_def bcm5221_phy_def = { 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id = 0x004061e0, 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id_mask = 0xfffffff0, 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "BCM5221", 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .features = MII_BASIC_FEATURES, 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .magic_aneg = 1, 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ops = &bcm5221_phy_ops 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 92663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt/* Broadcom BCM 5241 */ 92763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic struct mii_phy_ops bcm5241_phy_ops = { 92863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .suspend = bcm5241_suspend, 92963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .init = bcm5241_init, 93063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .setup_aneg = genmii_setup_aneg, 93163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .setup_forced = genmii_setup_forced, 93263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .poll_link = genmii_poll_link, 93363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .read_link = genmii_read_link, 93463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt}; 93563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic struct mii_phy_def bcm5241_phy_def = { 93663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .phy_id = 0x0143bc30, 93763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .phy_id_mask = 0xfffffff0, 93863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .name = "BCM5241", 93963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .features = MII_BASIC_FEATURES, 94063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .magic_aneg = 1, 94163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .ops = &bcm5241_phy_ops 94263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt}; 94363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Broadcom BCM 5400 */ 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_ops bcm5400_phy_ops = { 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = bcm5400_init, 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .suspend = bcm5400_suspend, 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_aneg = bcm54xx_setup_aneg, 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_forced = bcm54xx_setup_forced, 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll_link = genmii_poll_link, 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_link = bcm54xx_read_link, 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_def bcm5400_phy_def = { 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id = 0x00206040, 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id_mask = 0xfffffff0, 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "BCM5400", 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .features = MII_GBIT_FEATURES, 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .magic_aneg = 1, 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ops = &bcm5400_phy_ops 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Broadcom BCM 5401 */ 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_ops bcm5401_phy_ops = { 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = bcm5401_init, 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .suspend = bcm5401_suspend, 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_aneg = bcm54xx_setup_aneg, 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_forced = bcm54xx_setup_forced, 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll_link = genmii_poll_link, 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_link = bcm54xx_read_link, 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_def bcm5401_phy_def = { 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id = 0x00206050, 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id_mask = 0xfffffff0, 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "BCM5401", 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .features = MII_GBIT_FEATURES, 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .magic_aneg = 1, 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ops = &bcm5401_phy_ops 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Broadcom BCM 5411 */ 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_ops bcm5411_phy_ops = { 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = bcm5411_init, 985d47f3640fe2ac4da8a8e713a549e6eaf23ac2084Johannes Berg .suspend = generic_suspend, 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_aneg = bcm54xx_setup_aneg, 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_forced = bcm54xx_setup_forced, 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll_link = genmii_poll_link, 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_link = bcm54xx_read_link, 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_def bcm5411_phy_def = { 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id = 0x00206070, 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id_mask = 0xfffffff0, 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "BCM5411", 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .features = MII_GBIT_FEATURES, 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .magic_aneg = 1, 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ops = &bcm5411_phy_ops 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Broadcom BCM 5421 */ 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_ops bcm5421_phy_ops = { 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = bcm5421_init, 1004d47f3640fe2ac4da8a8e713a549e6eaf23ac2084Johannes Berg .suspend = generic_suspend, 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_aneg = bcm54xx_setup_aneg, 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_forced = bcm54xx_setup_forced, 1007eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp .poll_link = bcm5421_poll_link, 1008eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp .read_link = bcm5421_read_link, 10098ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .enable_fiber = bcm5421_enable_fiber, 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_def bcm5421_phy_def = { 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id = 0x002060e0, 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id_mask = 0xfffffff0, 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "BCM5421", 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .features = MII_GBIT_FEATURES, 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .magic_aneg = 1, 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ops = &bcm5421_phy_ops 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Broadcom BCM 5421 built-in K2 */ 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_ops bcm5421k2_phy_ops = { 10233c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .init = bcm5421_init, 1024d47f3640fe2ac4da8a8e713a549e6eaf23ac2084Johannes Berg .suspend = generic_suspend, 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_aneg = bcm54xx_setup_aneg, 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_forced = bcm54xx_setup_forced, 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll_link = genmii_poll_link, 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_link = bcm54xx_read_link, 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_def bcm5421k2_phy_def = { 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id = 0x002062e0, 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id_mask = 0xfffffff0, 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "BCM5421-K2", 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .features = MII_GBIT_FEATURES, 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .magic_aneg = 1, 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ops = &bcm5421k2_phy_ops 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10408ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkampstatic struct mii_phy_ops bcm5461_phy_ops = { 10418ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .init = bcm5421_init, 10428ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .suspend = generic_suspend, 10438ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .setup_aneg = bcm54xx_setup_aneg, 10448ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .setup_forced = bcm54xx_setup_forced, 1045eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp .poll_link = bcm5461_poll_link, 1046eb5b5b2ff96e8f3a42a46378968a166bb56bd900Jens Osterkamp .read_link = bcm5461_read_link, 10478ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .enable_fiber = bcm5461_enable_fiber, 10488ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp}; 10498ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp 10508ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkampstatic struct mii_phy_def bcm5461_phy_def = { 10518ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .phy_id = 0x002060c0, 10528ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .phy_id_mask = 0xfffffff0, 10538ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .name = "BCM5461", 10548ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .features = MII_GBIT_FEATURES, 10558ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .magic_aneg = 1, 10568ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp .ops = &bcm5461_phy_ops 10578ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp}; 10588ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp 10593c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt/* Broadcom BCM 5462 built-in Vesta */ 10603c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidtstatic struct mii_phy_ops bcm5462V_phy_ops = { 10613c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .init = bcm5421_init, 1062d47f3640fe2ac4da8a8e713a549e6eaf23ac2084Johannes Berg .suspend = generic_suspend, 10633c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .setup_aneg = bcm54xx_setup_aneg, 10643c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .setup_forced = bcm54xx_setup_forced, 10653c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .poll_link = genmii_poll_link, 10663c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .read_link = bcm54xx_read_link, 10673c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt}; 10683c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt 10693c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidtstatic struct mii_phy_def bcm5462V_phy_def = { 10703c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .phy_id = 0x002060d0, 10713c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .phy_id_mask = 0xfffffff0, 10723c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .name = "BCM5462-Vesta", 10733c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .features = MII_GBIT_FEATURES, 10743c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .magic_aneg = 1, 10753c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt .ops = &bcm5462V_phy_ops 10763c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt}; 10773c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt 107863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt/* Marvell 88E1101 amd 88E1111 */ 107963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic struct mii_phy_ops marvell88e1101_phy_ops = { 1080d47f3640fe2ac4da8a8e713a549e6eaf23ac2084Johannes Berg .suspend = generic_suspend, 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_aneg = marvell_setup_aneg, 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_forced = marvell_setup_forced, 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll_link = genmii_poll_link, 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_link = marvell_read_link 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 108763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic struct mii_phy_ops marvell88e1111_phy_ops = { 108863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .init = marvell88e1111_init, 108963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .suspend = generic_suspend, 109063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .setup_aneg = marvell_setup_aneg, 109163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .setup_forced = marvell_setup_forced, 109263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .poll_link = genmii_poll_link, 109363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .read_link = marvell_read_link 109463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt}; 109563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt 109663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt/* two revs in darwin for the 88e1101 ... I could use a datasheet 109763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt * to get the proper names... 109863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt */ 109963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic struct mii_phy_def marvell88e1101v1_phy_def = { 110063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .phy_id = 0x01410c20, 110163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .phy_id_mask = 0xfffffff0, 110263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .name = "Marvell 88E1101v1", 110363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .features = MII_GBIT_FEATURES, 110463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .magic_aneg = 1, 110563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .ops = &marvell88e1101_phy_ops 110663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt}; 110763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic struct mii_phy_def marvell88e1101v2_phy_def = { 110863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .phy_id = 0x01410c60, 110963ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .phy_id_mask = 0xfffffff0, 111063ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .name = "Marvell 88E1101v2", 111163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .features = MII_GBIT_FEATURES, 111263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .magic_aneg = 1, 111363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .ops = &marvell88e1101_phy_ops 111463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt}; 111563ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidtstatic struct mii_phy_def marvell88e1111_phy_def = { 111663ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .phy_id = 0x01410cc0, 111763ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .phy_id_mask = 0xfffffff0, 111863ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .name = "Marvell 88E1111", 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .features = MII_GBIT_FEATURES, 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .magic_aneg = 1, 112163ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt .ops = &marvell88e1111_phy_ops 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Generic implementation for most 10/100 PHYs */ 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_ops generic_phy_ops = { 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_aneg = genmii_setup_aneg, 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_forced = genmii_setup_forced, 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll_link = genmii_poll_link, 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_link = genmii_read_link 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_def genmii_phy_def = { 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id = 0x00000000, 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phy_id_mask = 0x00000000, 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "Generic MII", 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .features = MII_BASIC_FEATURES, 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .magic_aneg = 0, 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ops = &generic_phy_ops 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mii_phy_def* mii_phy_table[] = { 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &bcm5201_phy_def, 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &bcm5221_phy_def, 114463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt &bcm5241_phy_def, 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &bcm5400_phy_def, 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &bcm5401_phy_def, 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &bcm5411_phy_def, 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &bcm5421_phy_def, 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &bcm5421k2_phy_def, 11508ec93459655a3618dedec6360bb28d63f0010ef6Jens Osterkamp &bcm5461_phy_def, 11513c326fe9cb7ae022f7589a6f5781e49ceab82e64Benjamin Herrenschmidt &bcm5462V_phy_def, 115263ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt &marvell88e1101v1_phy_def, 115363ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt &marvell88e1101v2_phy_def, 115463ea998a26d4e03d390fbe31818cc552994d16fdBenjamin Herrenschmidt &marvell88e1111_phy_def, 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &genmii_phy_def, 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 115919e2f6fe9601ca5c846b7163e6d6d00f87b34760David S. Millerint sungem_phy_probe(struct mii_phy *phy, int mii_id) 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc; 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 id; 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mii_phy_def* def; 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We do not reset the mii_phy structure as the driver 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * may re-probe the PHY regulary 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->mii_id = mii_id; 11706aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Take PHY out of isloate mode and reset it. */ 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = reset_one_mii_phy(phy, mii_id); 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rc) 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto fail; 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11766aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik /* Read ID and find matching entry */ 1177abc4da4503bf6cb1864454b464c52959241239bdDavid S. Miller id = (sungem_phy_read(phy, MII_PHYSID1) << 16 | sungem_phy_read(phy, MII_PHYSID2)); 1178c6c759884b05c7449a19d39c763a7482180e2defJoe Perches printk(KERN_DEBUG KBUILD_MODNAME ": " "PHY ID: %x, addr: %x\n", 1179c6c759884b05c7449a19d39c763a7482180e2defJoe Perches id, mii_id); 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0; (def = mii_phy_table[i]) != NULL; i++) 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((id & def->phy_id_mask) == def->phy_id) 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Should never be NULL (we have a generic entry), but... */ 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (def == NULL) 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto fail; 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->def = def; 11886aa20a2235535605db6d6d2bd850298b2fe7f31eJeff Garzik 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfail: 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->speed = 0; 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->duplex = 0; 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->pause = 0; 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phy->advertising = 0; 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 119819e2f6fe9601ca5c846b7163e6d6d00f87b34760David S. MillerEXPORT_SYMBOL(sungem_phy_probe); 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 1200