aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/mv643xx_eth.c64
-rw-r--r--drivers/net/mv643xx_eth.h2
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 */
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:
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 */