aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mv643xx_eth.c
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2006-01-27 03:13:15 -0500
committerJeff Garzik <jgarzik@pobox.com>2006-01-27 11:11:16 -0500
commitc28a4f8947f1b08996502967e348dc88363749a7 (patch)
treea0afa38353ebb02f2cef528d1b84e2e8e89443c2 /drivers/net/mv643xx_eth.c
parent9f8dd319459bb5ab9efcc1c345bed7895cc41768 (diff)
[PATCH] mv643xx_eth: use MII library for PHY management
Modify link up/down handling to use the functions from the MII library. Note that I track link state using the MII PHY registers rather than the mv643xx chip's link state registers because I think it's cleaner to use the MII library code rather than writing local driver support code. It is also useful to make the actual MII registers available to the user with maskable kernel printk messages so the MII registers are being read anyway Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: Dale Farnsworth <dale@farnsworth.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r--drivers/net/mv643xx_eth.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 2daa9b97d2c0..bca7257c707a 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -79,7 +79,6 @@
79#define PHY_WAIT_MICRO_SECONDS 10 79#define PHY_WAIT_MICRO_SECONDS 10
80 80
81/* Static function declarations */ 81/* Static function declarations */
82static int eth_port_link_is_up(unsigned int eth_port_num);
83static void eth_port_uc_addr_get(struct net_device *dev, 82static void eth_port_uc_addr_get(struct net_device *dev,
84 unsigned char *MacAddr); 83 unsigned char *MacAddr);
85static void eth_port_set_multicast_list(struct net_device *); 84static void eth_port_set_multicast_list(struct net_device *);
@@ -97,8 +96,11 @@ static void eth_port_init_mac_tables(unsigned int eth_port_num);
97#ifdef MV643XX_NAPI 96#ifdef MV643XX_NAPI
98static int mv643xx_poll(struct net_device *dev, int *budget); 97static int mv643xx_poll(struct net_device *dev, int *budget);
99#endif 98#endif
99static int ethernet_phy_get(unsigned int eth_port_num);
100static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); 100static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
101static int ethernet_phy_detect(unsigned int eth_port_num); 101static int ethernet_phy_detect(unsigned int eth_port_num);
102static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
103static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val);
102static struct ethtool_ops mv643xx_ethtool_ops; 104static struct ethtool_ops mv643xx_ethtool_ops;
103 105
104static char mv643xx_driver_name[] = "mv643xx_eth"; 106static char mv643xx_driver_name[] = "mv643xx_eth";
@@ -537,14 +539,17 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
537 } 539 }
538 /* PHY status changed */ 540 /* PHY status changed */
539 if (eth_int_cause_ext & (BIT16 | BIT20)) { 541 if (eth_int_cause_ext & (BIT16 | BIT20)) {
540 if (eth_port_link_is_up(port_num)) { 542 if (mii_link_ok(&mp->mii)) {
541 netif_carrier_on(dev); 543 if (!netif_carrier_ok(dev)) {
542 netif_wake_queue(dev); 544 netif_carrier_on(dev);
543 /* Start TX queue */ 545 netif_wake_queue(dev);
544 mv643xx_eth_port_enable_tx(port_num, mp->port_tx_queue_command); 546 /* Start TX queue */
545 } else { 547 mv643xx_eth_port_enable_tx(port_num,
546 netif_carrier_off(dev); 548 mp->port_tx_queue_command);
549 }
550 } else if (netif_carrier_ok(dev)) {
547 netif_stop_queue(dev); 551 netif_stop_queue(dev);
552 netif_carrier_off(dev);
548 } 553 }
549 } 554 }
550 555
@@ -1434,6 +1439,14 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
1434 } 1439 }
1435 } 1440 }
1436 1441
1442 /* Hook up MII support for ethtool */
1443 mp->mii.dev = dev;
1444 mp->mii.mdio_read = mv643xx_mdio_read;
1445 mp->mii.mdio_write = mv643xx_mdio_write;
1446 mp->mii.phy_id = ethernet_phy_get(port_num);
1447 mp->mii.phy_id_mask = 0x3f;
1448 mp->mii.reg_num_mask = 0x1f;
1449
1437 err = ethernet_phy_detect(port_num); 1450 err = ethernet_phy_detect(port_num);
1438 if (err) { 1451 if (err) {
1439 pr_debug("MV643xx ethernet port %d: " 1452 pr_debug("MV643xx ethernet port %d: "
@@ -1442,6 +1455,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
1442 return err; 1455 return err;
1443 } 1456 }
1444 1457
1458 mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);
1459
1445 err = register_netdev(dev); 1460 err = register_netdev(dev);
1446 if (err) 1461 if (err)
1447 goto out; 1462 goto out;
@@ -2416,21 +2431,6 @@ static int eth_port_autoneg_supported(unsigned int eth_port_num)
2416 return phy_reg_data0 & 0x1000; 2431 return phy_reg_data0 & 0x1000;
2417} 2432}
2418 2433
2419static int eth_port_link_is_up(unsigned int eth_port_num)
2420{
2421 unsigned int phy_reg_data1;
2422
2423 eth_port_read_smi_reg(eth_port_num, 1, &phy_reg_data1);
2424
2425 if (eth_port_autoneg_supported(eth_port_num)) {
2426 if (phy_reg_data1 & 0x20) /* auto-neg complete */
2427 return 1;
2428 } else if (phy_reg_data1 & 0x4) /* link up */
2429 return 1;
2430
2431 return 0;
2432}
2433
2434/* 2434/*
2435 * eth_port_read_smi_reg - Read PHY registers 2435 * eth_port_read_smi_reg - Read PHY registers
2436 * 2436 *
@@ -2536,6 +2536,24 @@ out:
2536} 2536}
2537 2537
2538/* 2538/*
2539 * Wrappers for MII support library.
2540 */
2541static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location)
2542{
2543 int val;
2544 struct mv643xx_private *mp = netdev_priv(dev);
2545
2546 eth_port_read_smi_reg(mp->port_num, location, &val);
2547 return val;
2548}
2549
2550static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val)
2551{
2552 struct mv643xx_private *mp = netdev_priv(dev);
2553 eth_port_write_smi_reg(mp->port_num, location, val);
2554}
2555
2556/*
2539 * eth_port_send - Send an Ethernet packet 2557 * eth_port_send - Send an Ethernet packet
2540 * 2558 *
2541 * DESCRIPTION: 2559 * DESCRIPTION: