aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mv643xx_eth.c
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/mv643xx_eth.c
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/mv643xx_eth.c')
-rw-r--r--drivers/net/mv643xx_eth.c248
1 files changed, 104 insertions, 144 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index d0ecc440aac2..1f944a23f53d 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