diff options
author | James Chapman <jchapman@katalix.com> | 2006-01-27 03:13:15 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-27 11:11:16 -0500 |
commit | c28a4f8947f1b08996502967e348dc88363749a7 (patch) | |
tree | a0afa38353ebb02f2cef528d1b84e2e8e89443c2 | |
parent | 9f8dd319459bb5ab9efcc1c345bed7895cc41768 (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>
-rw-r--r-- | drivers/net/mv643xx_eth.c | 64 | ||||
-rw-r--r-- | drivers/net/mv643xx_eth.h | 2 |
2 files changed, 43 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 */ |
82 | static int eth_port_link_is_up(unsigned int eth_port_num); | ||
83 | static void eth_port_uc_addr_get(struct net_device *dev, | 82 | static void eth_port_uc_addr_get(struct net_device *dev, |
84 | unsigned char *MacAddr); | 83 | unsigned char *MacAddr); |
85 | static void eth_port_set_multicast_list(struct net_device *); | 84 | static 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 |
98 | static int mv643xx_poll(struct net_device *dev, int *budget); | 97 | static int mv643xx_poll(struct net_device *dev, int *budget); |
99 | #endif | 98 | #endif |
99 | static int ethernet_phy_get(unsigned int eth_port_num); | ||
100 | static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); | 100 | static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); |
101 | static int ethernet_phy_detect(unsigned int eth_port_num); | 101 | static int ethernet_phy_detect(unsigned int eth_port_num); |
102 | static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location); | ||
103 | static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val); | ||
102 | static struct ethtool_ops mv643xx_ethtool_ops; | 104 | static struct ethtool_ops mv643xx_ethtool_ops; |
103 | 105 | ||
104 | static char mv643xx_driver_name[] = "mv643xx_eth"; | 106 | static 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 | ||
2419 | static 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 | */ | ||
2541 | static 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 | |||
2550 | static 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: |
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h index 345f970d122c..f2e5da79dde8 100644 --- a/drivers/net/mv643xx_eth.h +++ b/drivers/net/mv643xx_eth.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/spinlock.h> | 6 | #include <linux/spinlock.h> |
7 | #include <linux/workqueue.h> | 7 | #include <linux/workqueue.h> |
8 | #include <linux/mii.h> | ||
8 | 9 | ||
9 | #include <linux/mv643xx.h> | 10 | #include <linux/mv643xx.h> |
10 | 11 | ||
@@ -393,6 +394,7 @@ struct mv643xx_private { | |||
393 | 394 | ||
394 | u32 rx_int_coal; | 395 | u32 rx_int_coal; |
395 | u32 tx_int_coal; | 396 | u32 tx_int_coal; |
397 | struct mii_if_info mii; | ||
396 | }; | 398 | }; |
397 | 399 | ||
398 | /* ethernet.h API list */ | 400 | /* ethernet.h API list */ |