diff options
Diffstat (limited to 'drivers')
-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 */ |