aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2008-08-26 07:34:19 -0400
committerLennert Buytenhek <buytenh@marvell.com>2008-09-19 13:34:00 -0400
commited94493fb38a665cebcf750dfabe8a6dd13e136f (patch)
treec02a9e722bb32232ef975548cbb1291d9ccc92c6 /drivers/net
parent4fd5f812c23c7deee6425f4a318e85c317cd1d6c (diff)
mv643xx_eth: convert to phylib
Switch mv643xx_eth from using drivers/net/mii.c to using phylib. Since the mv643xx_eth hardware does all the link state handling and PHY polling, the driver will use phylib in the "Doing it all yourself" mode described in the phylib documentation. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Acked-by: Andy Fleming <afleming@freescale.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/mv643xx_eth.c248
2 files changed, 105 insertions, 145 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4a11296a951..d85d76019af 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2262,7 +2262,7 @@ config UGETH_TX_ON_DEMAND
2262config MV643XX_ETH 2262config MV643XX_ETH
2263 tristate "Marvell Discovery (643XX) and Orion ethernet support" 2263 tristate "Marvell Discovery (643XX) and Orion ethernet support"
2264 depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION 2264 depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
2265 select MII 2265 select PHYLIB
2266 help 2266 help
2267 This driver supports the gigabit ethernet MACs in the 2267 This driver supports the gigabit ethernet MACs in the
2268 Marvell Discovery PPC/MIPS chipset family (MV643XX) and 2268 Marvell Discovery PPC/MIPS chipset family (MV643XX) and
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index d0ecc440aac..1f944a23f53 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -48,7 +48,7 @@
48#include <linux/kernel.h> 48#include <linux/kernel.h>
49#include <linux/spinlock.h> 49#include <linux/spinlock.h>
50#include <linux/workqueue.h> 50#include <linux/workqueue.h>
51#include <linux/mii.h> 51#include <linux/phy.h>
52#include <linux/mv643xx_eth.h> 52#include <linux/mv643xx_eth.h>
53#include <asm/io.h> 53#include <asm/io.h>
54#include <asm/types.h> 54#include <asm/types.h>
@@ -248,9 +248,9 @@ struct mv643xx_eth_shared_private {
248 struct mv643xx_eth_shared_private *smi; 248 struct mv643xx_eth_shared_private *smi;
249 249
250 /* 250 /*
251 * Protects access to SMI_REG, which is shared between ports. 251 * Provides access to local SMI interface.
252 */ 252 */
253 struct mutex phy_lock; 253 struct mii_bus smi_bus;
254 254
255 /* 255 /*
256 * If we have access to the error interrupt pin (which is 256 * If we have access to the error interrupt pin (which is
@@ -354,14 +354,13 @@ struct mv643xx_eth_private {
354 354
355 struct net_device *dev; 355 struct net_device *dev;
356 356
357 int phy_addr; 357 struct phy_device *phy;
358 358
359 struct timer_list mib_counters_timer; 359 struct timer_list mib_counters_timer;
360 spinlock_t mib_counters_lock; 360 spinlock_t mib_counters_lock;
361 struct mib_counters mib_counters; 361 struct mib_counters mib_counters;
362 362
363 struct work_struct tx_timeout_task; 363 struct work_struct tx_timeout_task;
364 struct mii_if_info mii;
365 364
366 struct napi_struct napi; 365 struct napi_struct napi;
367 u8 work_link; 366 u8 work_link;
@@ -1076,62 +1075,50 @@ static int smi_wait_ready(struct mv643xx_eth_shared_private *msp)
1076 return 0; 1075 return 0;
1077} 1076}
1078 1077
1079static int smi_reg_read(struct mv643xx_eth_private *mp, 1078static int smi_bus_read(struct mii_bus *bus, int addr, int reg)
1080 unsigned int addr, unsigned int reg)
1081{ 1079{
1082 struct mv643xx_eth_shared_private *msp = mp->shared->smi; 1080 struct mv643xx_eth_shared_private *msp = bus->priv;
1083 void __iomem *smi_reg = msp->base + SMI_REG; 1081 void __iomem *smi_reg = msp->base + SMI_REG;
1084 int ret; 1082 int ret;
1085 1083
1086 mutex_lock(&msp->phy_lock);
1087
1088 if (smi_wait_ready(msp)) { 1084 if (smi_wait_ready(msp)) {
1089 printk("%s: SMI bus busy timeout\n", mp->dev->name); 1085 printk("mv643xx_eth: SMI bus busy timeout\n");
1090 ret = -ETIMEDOUT; 1086 return -ETIMEDOUT;
1091 goto out;
1092 } 1087 }
1093 1088
1094 writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg); 1089 writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg);
1095 1090
1096 if (smi_wait_ready(msp)) { 1091 if (smi_wait_ready(msp)) {
1097 printk("%s: SMI bus busy timeout\n", mp->dev->name); 1092 printk("mv643xx_eth: SMI bus busy timeout\n");
1098 ret = -ETIMEDOUT; 1093 return -ETIMEDOUT;
1099 goto out;
1100 } 1094 }
1101 1095
1102 ret = readl(smi_reg); 1096 ret = readl(smi_reg);
1103 if (!(ret & SMI_READ_VALID)) { 1097 if (!(ret & SMI_READ_VALID)) {
1104 printk("%s: SMI bus read not valid\n", mp->dev->name); 1098 printk("mv643xx_eth: SMI bus read not valid\n");
1105 ret = -ENODEV; 1099 return -ENODEV;
1106 goto out;
1107 } 1100 }
1108 1101
1109 ret &= 0xffff; 1102 return ret & 0xffff;
1110
1111out:
1112 mutex_unlock(&msp->phy_lock);
1113
1114 return ret;
1115} 1103}
1116 1104
1117static int smi_reg_write(struct mv643xx_eth_private *mp, unsigned int addr, 1105static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val)
1118 unsigned int reg, unsigned int value)
1119{ 1106{
1120 struct mv643xx_eth_shared_private *msp = mp->shared->smi; 1107 struct mv643xx_eth_shared_private *msp = bus->priv;
1121 void __iomem *smi_reg = msp->base + SMI_REG; 1108 void __iomem *smi_reg = msp->base + SMI_REG;
1122 1109
1123 mutex_lock(&msp->phy_lock);
1124
1125 if (smi_wait_ready(msp)) { 1110 if (smi_wait_ready(msp)) {
1126 printk("%s: SMI bus busy timeout\n", mp->dev->name); 1111 printk("mv643xx_eth: SMI bus busy timeout\n");
1127 mutex_unlock(&msp->phy_lock);
1128 return -ETIMEDOUT; 1112 return -ETIMEDOUT;
1129 } 1113 }
1130 1114
1131 writel(SMI_OPCODE_WRITE | (reg << 21) | 1115 writel(SMI_OPCODE_WRITE | (reg << 21) |
1132 (addr << 16) | (value & 0xffff), smi_reg); 1116 (addr << 16) | (val & 0xffff), smi_reg);
1133 1117
1134 mutex_unlock(&msp->phy_lock); 1118 if (smi_wait_ready(msp)) {
1119 printk("mv643xx_eth: SMI bus busy timeout\n");
1120 return -ETIMEDOUT;
1121 }
1135 1122
1136 return 0; 1123 return 0;
1137} 1124}
@@ -1287,7 +1274,9 @@ static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *
1287 struct mv643xx_eth_private *mp = netdev_priv(dev); 1274 struct mv643xx_eth_private *mp = netdev_priv(dev);
1288 int err; 1275 int err;
1289 1276
1290 err = mii_ethtool_gset(&mp->mii, cmd); 1277 err = phy_read_status(mp->phy);
1278 if (err == 0)
1279 err = phy_ethtool_gset(mp->phy, cmd);
1291 1280
1292 /* 1281 /*
1293 * The MAC does not support 1000baseT_Half. 1282 * The MAC does not support 1000baseT_Half.
@@ -1341,7 +1330,7 @@ static int mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *
1341 */ 1330 */
1342 cmd->advertising &= ~ADVERTISED_1000baseT_Half; 1331 cmd->advertising &= ~ADVERTISED_1000baseT_Half;
1343 1332
1344 return mii_ethtool_sset(&mp->mii, cmd); 1333 return phy_ethtool_sset(mp->phy, cmd);
1345} 1334}
1346 1335
1347static int mv643xx_eth_set_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd) 1336static int mv643xx_eth_set_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -1363,7 +1352,7 @@ static int mv643xx_eth_nway_reset(struct net_device *dev)
1363{ 1352{
1364 struct mv643xx_eth_private *mp = netdev_priv(dev); 1353 struct mv643xx_eth_private *mp = netdev_priv(dev);
1365 1354
1366 return mii_nway_restart(&mp->mii); 1355 return genphy_restart_aneg(mp->phy);
1367} 1356}
1368 1357
1369static int mv643xx_eth_nway_reset_phyless(struct net_device *dev) 1358static int mv643xx_eth_nway_reset_phyless(struct net_device *dev)
@@ -1373,14 +1362,7 @@ static int mv643xx_eth_nway_reset_phyless(struct net_device *dev)
1373 1362
1374static u32 mv643xx_eth_get_link(struct net_device *dev) 1363static u32 mv643xx_eth_get_link(struct net_device *dev)
1375{ 1364{
1376 struct mv643xx_eth_private *mp = netdev_priv(dev); 1365 return !!netif_carrier_ok(dev);
1377
1378 return mii_link_ok(&mp->mii);
1379}
1380
1381static u32 mv643xx_eth_get_link_phyless(struct net_device *dev)
1382{
1383 return 1;
1384} 1366}
1385 1367
1386static void mv643xx_eth_get_strings(struct net_device *dev, 1368static void mv643xx_eth_get_strings(struct net_device *dev,
@@ -1448,7 +1430,7 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops_phyless = {
1448 .set_settings = mv643xx_eth_set_settings_phyless, 1430 .set_settings = mv643xx_eth_set_settings_phyless,
1449 .get_drvinfo = mv643xx_eth_get_drvinfo, 1431 .get_drvinfo = mv643xx_eth_get_drvinfo,
1450 .nway_reset = mv643xx_eth_nway_reset_phyless, 1432 .nway_reset = mv643xx_eth_nway_reset_phyless,
1451 .get_link = mv643xx_eth_get_link_phyless, 1433 .get_link = mv643xx_eth_get_link,
1452 .set_sg = ethtool_op_set_sg, 1434 .set_sg = ethtool_op_set_sg,
1453 .get_strings = mv643xx_eth_get_strings, 1435 .get_strings = mv643xx_eth_get_strings,
1454 .get_ethtool_stats = mv643xx_eth_get_ethtool_stats, 1436 .get_ethtool_stats = mv643xx_eth_get_ethtool_stats,
@@ -1941,16 +1923,16 @@ static void phy_reset(struct mv643xx_eth_private *mp)
1941{ 1923{
1942 int data; 1924 int data;
1943 1925
1944 data = smi_reg_read(mp, mp->phy_addr, MII_BMCR); 1926 data = phy_read(mp->phy, MII_BMCR);
1945 if (data < 0) 1927 if (data < 0)
1946 return; 1928 return;
1947 1929
1948 data |= BMCR_RESET; 1930 data |= BMCR_RESET;
1949 if (smi_reg_write(mp, mp->phy_addr, MII_BMCR, data) < 0) 1931 if (phy_write(mp->phy, MII_BMCR, data) < 0)
1950 return; 1932 return;
1951 1933
1952 do { 1934 do {
1953 data = smi_reg_read(mp, mp->phy_addr, MII_BMCR); 1935 data = phy_read(mp->phy, MII_BMCR);
1954 } while (data >= 0 && data & BMCR_RESET); 1936 } while (data >= 0 && data & BMCR_RESET);
1955} 1937}
1956 1938
@@ -1962,7 +1944,7 @@ static void port_start(struct mv643xx_eth_private *mp)
1962 /* 1944 /*
1963 * Perform PHY reset, if there is a PHY. 1945 * Perform PHY reset, if there is a PHY.
1964 */ 1946 */
1965 if (mp->phy_addr != -1) { 1947 if (mp->phy != NULL) {
1966 struct ethtool_cmd cmd; 1948 struct ethtool_cmd cmd;
1967 1949
1968 mv643xx_eth_get_settings(mp->dev, &cmd); 1950 mv643xx_eth_get_settings(mp->dev, &cmd);
@@ -1979,7 +1961,7 @@ static void port_start(struct mv643xx_eth_private *mp)
1979 wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); 1961 wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
1980 1962
1981 pscr |= DO_NOT_FORCE_LINK_FAIL; 1963 pscr |= DO_NOT_FORCE_LINK_FAIL;
1982 if (mp->phy_addr == -1) 1964 if (mp->phy == NULL)
1983 pscr |= FORCE_LINK_PASS; 1965 pscr |= FORCE_LINK_PASS;
1984 wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); 1966 wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
1985 1967
@@ -2188,8 +2170,8 @@ static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2188{ 2170{
2189 struct mv643xx_eth_private *mp = netdev_priv(dev); 2171 struct mv643xx_eth_private *mp = netdev_priv(dev);
2190 2172
2191 if (mp->phy_addr != -1) 2173 if (mp->phy != NULL)
2192 return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL); 2174 return phy_mii_ioctl(mp->phy, if_mii(ifr), cmd);
2193 2175
2194 return -EOPNOTSUPP; 2176 return -EOPNOTSUPP;
2195} 2177}
@@ -2259,18 +2241,6 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
2259} 2241}
2260#endif 2242#endif
2261 2243
2262static int mv643xx_eth_mdio_read(struct net_device *dev, int addr, int reg)
2263{
2264 struct mv643xx_eth_private *mp = netdev_priv(dev);
2265 return smi_reg_read(mp, addr, reg);
2266}
2267
2268static void mv643xx_eth_mdio_write(struct net_device *dev, int addr, int reg, int val)
2269{
2270 struct mv643xx_eth_private *mp = netdev_priv(dev);
2271 smi_reg_write(mp, addr, reg, val);
2272}
2273
2274 2244
2275/* platform glue ************************************************************/ 2245/* platform glue ************************************************************/
2276static void 2246static void
@@ -2365,11 +2335,23 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
2365 if (msp->base == NULL) 2335 if (msp->base == NULL)
2366 goto out_free; 2336 goto out_free;
2367 2337
2368 msp->smi = msp; 2338 /*
2369 if (pd != NULL && pd->shared_smi != NULL) 2339 * Set up and register SMI bus.
2340 */
2341 if (pd == NULL || pd->shared_smi == NULL) {
2342 msp->smi_bus.priv = msp;
2343 msp->smi_bus.name = "mv643xx_eth smi";
2344 msp->smi_bus.read = smi_bus_read;
2345 msp->smi_bus.write = smi_bus_write,
2346 snprintf(msp->smi_bus.id, MII_BUS_ID_SIZE, "%d", pdev->id);
2347 msp->smi_bus.dev = &pdev->dev;
2348 msp->smi_bus.phy_mask = 0xffffffff;
2349 if (mdiobus_register(&msp->smi_bus) < 0)
2350 goto out_unmap;
2351 msp->smi = msp;
2352 } else {
2370 msp->smi = platform_get_drvdata(pd->shared_smi); 2353 msp->smi = platform_get_drvdata(pd->shared_smi);
2371 2354 }
2372 mutex_init(&msp->phy_lock);
2373 2355
2374 msp->err_interrupt = NO_IRQ; 2356 msp->err_interrupt = NO_IRQ;
2375 init_waitqueue_head(&msp->smi_busy_wait); 2357 init_waitqueue_head(&msp->smi_busy_wait);
@@ -2405,6 +2387,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
2405 2387
2406 return 0; 2388 return 0;
2407 2389
2390out_unmap:
2391 iounmap(msp->base);
2408out_free: 2392out_free:
2409 kfree(msp); 2393 kfree(msp);
2410out: 2394out:
@@ -2414,7 +2398,10 @@ out:
2414static int mv643xx_eth_shared_remove(struct platform_device *pdev) 2398static int mv643xx_eth_shared_remove(struct platform_device *pdev)
2415{ 2399{
2416 struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev); 2400 struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);
2401 struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
2417 2402
2403 if (pd == NULL || pd->shared_smi == NULL)
2404 mdiobus_unregister(&msp->smi_bus);
2418 if (msp->err_interrupt != NO_IRQ) 2405 if (msp->err_interrupt != NO_IRQ)
2419 free_irq(msp->err_interrupt, msp); 2406 free_irq(msp->err_interrupt, msp);
2420 iounmap(msp->base); 2407 iounmap(msp->base);
@@ -2462,17 +2449,6 @@ static void set_params(struct mv643xx_eth_private *mp,
2462 else 2449 else
2463 uc_addr_get(mp, dev->dev_addr); 2450 uc_addr_get(mp, dev->dev_addr);
2464 2451
2465 if (pd->phy_addr == MV643XX_ETH_PHY_NONE) {
2466 mp->phy_addr = -1;
2467 } else {
2468 if (pd->phy_addr != MV643XX_ETH_PHY_ADDR_DEFAULT) {
2469 mp->phy_addr = pd->phy_addr & 0x3f;
2470 phy_addr_set(mp, mp->phy_addr);
2471 } else {
2472 mp->phy_addr = phy_addr_get(mp);
2473 }
2474 }
2475
2476 mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE; 2452 mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE;
2477 if (pd->rx_queue_size) 2453 if (pd->rx_queue_size)
2478 mp->default_rx_ring_size = pd->rx_queue_size; 2454 mp->default_rx_ring_size = pd->rx_queue_size;
@@ -2490,76 +2466,60 @@ static void set_params(struct mv643xx_eth_private *mp,
2490 mp->txq_count = pd->tx_queue_count ? : 1; 2466 mp->txq_count = pd->tx_queue_count ? : 1;
2491} 2467}
2492 2468
2493static int phy_detect(struct mv643xx_eth_private *mp) 2469static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
2470 int phy_addr)
2494{ 2471{
2495 int data; 2472 struct mii_bus *bus = &mp->shared->smi->smi_bus;
2496 int data2; 2473 struct phy_device *phydev;
2474 int start;
2475 int num;
2476 int i;
2497 2477
2498 data = smi_reg_read(mp, mp->phy_addr, MII_BMCR); 2478 if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) {
2499 if (data < 0) 2479 start = phy_addr_get(mp) & 0x1f;
2500 return -ENODEV; 2480 num = 32;
2481 } else {
2482 start = phy_addr & 0x1f;
2483 num = 1;
2484 }
2501 2485
2502 if (smi_reg_write(mp, mp->phy_addr, MII_BMCR, data ^ BMCR_ANENABLE) < 0) 2486 phydev = NULL;
2503 return -ENODEV; 2487 for (i = 0; i < num; i++) {
2488 int addr = (start + i) & 0x1f;
2504 2489
2505 data2 = smi_reg_read(mp, mp->phy_addr, MII_BMCR); 2490 if (bus->phy_map[addr] == NULL)
2506 if (data2 < 0) 2491 mdiobus_scan(bus, addr);
2507 return -ENODEV;
2508 2492
2509 if (((data ^ data2) & BMCR_ANENABLE) == 0) 2493 if (phydev == NULL) {
2510 return -ENODEV; 2494 phydev = bus->phy_map[addr];
2511 2495 if (phydev != NULL)
2512 smi_reg_write(mp, mp->phy_addr, MII_BMCR, data); 2496 phy_addr_set(mp, addr);
2497 }
2498 }
2513 2499
2514 return 0; 2500 return phydev;
2515} 2501}
2516 2502
2517static int phy_init(struct mv643xx_eth_private *mp, 2503static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
2518 struct mv643xx_eth_platform_data *pd)
2519{ 2504{
2520 struct ethtool_cmd cmd; 2505 struct phy_device *phy = mp->phy;
2521 int err;
2522 2506
2523 err = phy_detect(mp);
2524 if (err) {
2525 dev_printk(KERN_INFO, &mp->dev->dev,
2526 "no PHY detected at addr %d\n", mp->phy_addr);
2527 return err;
2528 }
2529 phy_reset(mp); 2507 phy_reset(mp);
2530 2508
2531 mp->mii.phy_id = mp->phy_addr; 2509 phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII);
2532 mp->mii.phy_id_mask = 0x3f; 2510
2533 mp->mii.reg_num_mask = 0x1f; 2511 if (speed == 0) {
2534 mp->mii.dev = mp->dev; 2512 phy->autoneg = AUTONEG_ENABLE;
2535 mp->mii.mdio_read = mv643xx_eth_mdio_read; 2513 phy->speed = 0;
2536 mp->mii.mdio_write = mv643xx_eth_mdio_write; 2514 phy->duplex = 0;
2537 2515 phy->advertising = phy->supported | ADVERTISED_Autoneg;
2538 mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);
2539
2540 memset(&cmd, 0, sizeof(cmd));
2541
2542 cmd.port = PORT_MII;
2543 cmd.transceiver = XCVR_INTERNAL;
2544 cmd.phy_address = mp->phy_addr;
2545 if (pd->speed == 0) {
2546 cmd.autoneg = AUTONEG_ENABLE;
2547 cmd.speed = SPEED_100;
2548 cmd.advertising = ADVERTISED_10baseT_Half |
2549 ADVERTISED_10baseT_Full |
2550 ADVERTISED_100baseT_Half |
2551 ADVERTISED_100baseT_Full;
2552 if (mp->mii.supports_gmii)
2553 cmd.advertising |= ADVERTISED_1000baseT_Full;
2554 } else { 2516 } else {
2555 cmd.autoneg = AUTONEG_DISABLE; 2517 phy->autoneg = AUTONEG_DISABLE;
2556 cmd.speed = pd->speed; 2518 phy->advertising = 0;
2557 cmd.duplex = pd->duplex; 2519 phy->speed = speed;
2520 phy->duplex = duplex;
2558 } 2521 }
2559 2522 phy_start_aneg(phy);
2560 mv643xx_eth_set_settings(mp->dev, &cmd);
2561
2562 return 0;
2563} 2523}
2564 2524
2565static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex) 2525static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
@@ -2573,7 +2533,7 @@ static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
2573 } 2533 }
2574 2534
2575 pscr = MAX_RX_PACKET_9700BYTE | SERIAL_PORT_CONTROL_RESERVED; 2535 pscr = MAX_RX_PACKET_9700BYTE | SERIAL_PORT_CONTROL_RESERVED;
2576 if (mp->phy_addr == -1) { 2536 if (mp->phy == NULL) {
2577 pscr |= DISABLE_AUTO_NEG_SPEED_GMII; 2537 pscr |= DISABLE_AUTO_NEG_SPEED_GMII;
2578 if (speed == SPEED_1000) 2538 if (speed == SPEED_1000)
2579 pscr |= SET_GMII_SPEED_TO_1000; 2539 pscr |= SET_GMII_SPEED_TO_1000;
@@ -2627,18 +2587,16 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
2627 set_params(mp, pd); 2587 set_params(mp, pd);
2628 dev->real_num_tx_queues = mp->txq_count; 2588 dev->real_num_tx_queues = mp->txq_count;
2629 2589
2630 mib_counters_clear(mp); 2590 if (pd->phy_addr != MV643XX_ETH_PHY_NONE)
2631 INIT_WORK(&mp->tx_timeout_task, tx_timeout_task); 2591 mp->phy = phy_scan(mp, pd->phy_addr);
2632
2633 if (mp->phy_addr != -1) {
2634 err = phy_init(mp, pd);
2635 if (err)
2636 goto out;
2637 2592
2593 if (mp->phy != NULL) {
2594 phy_init(mp, pd->speed, pd->duplex);
2638 SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops); 2595 SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
2639 } else { 2596 } else {
2640 SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless); 2597 SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless);
2641 } 2598 }
2599
2642 init_pscr(mp, pd->speed, pd->duplex); 2600 init_pscr(mp, pd->speed, pd->duplex);
2643 2601
2644 2602
@@ -2711,6 +2669,8 @@ static int mv643xx_eth_remove(struct platform_device *pdev)
2711 struct mv643xx_eth_private *mp = platform_get_drvdata(pdev); 2669 struct mv643xx_eth_private *mp = platform_get_drvdata(pdev);
2712 2670
2713 unregister_netdev(mp->dev); 2671 unregister_netdev(mp->dev);
2672 if (mp->phy != NULL)
2673 phy_detach(mp->phy);
2714 flush_scheduled_work(); 2674 flush_scheduled_work();
2715 free_netdev(mp->dev); 2675 free_netdev(mp->dev);
2716 2676