]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/mv643xx_eth.c
[PATCH] mv643xx_eth: use MII library for PHY management
[linux-2.6-omap-h63xx.git] / drivers / net / mv643xx_eth.c
index 2daa9b97d2c03b8bd8c6d0942c9d99cb753b4393..bca7257c707a610815bd9b161099607877441284 100644 (file)
@@ -79,7 +79,6 @@
 #define PHY_WAIT_MICRO_SECONDS 10
 
 /* Static function declarations */
-static int eth_port_link_is_up(unsigned int eth_port_num);
 static void eth_port_uc_addr_get(struct net_device *dev,
                                                unsigned char *MacAddr);
 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);
 #ifdef MV643XX_NAPI
 static int mv643xx_poll(struct net_device *dev, int *budget);
 #endif
+static int ethernet_phy_get(unsigned int eth_port_num);
 static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
 static int ethernet_phy_detect(unsigned int eth_port_num);
+static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
+static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val);
 static struct ethtool_ops mv643xx_ethtool_ops;
 
 static char mv643xx_driver_name[] = "mv643xx_eth";
@@ -537,14 +539,17 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
        }
        /* PHY status changed */
        if (eth_int_cause_ext & (BIT16 | BIT20)) {
-               if (eth_port_link_is_up(port_num)) {
-                       netif_carrier_on(dev);
-                       netif_wake_queue(dev);
-                       /* Start TX queue */
-                       mv643xx_eth_port_enable_tx(port_num, mp->port_tx_queue_command);
-               } else {
-                       netif_carrier_off(dev);
+               if (mii_link_ok(&mp->mii)) {
+                       if (!netif_carrier_ok(dev)) {
+                               netif_carrier_on(dev);
+                               netif_wake_queue(dev);
+                               /* Start TX queue */
+                               mv643xx_eth_port_enable_tx(port_num,
+                                               mp->port_tx_queue_command);
+                       }
+               } else if (netif_carrier_ok(dev)) {
                        netif_stop_queue(dev);
+                       netif_carrier_off(dev);
                }
        }
 
@@ -1434,6 +1439,14 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
                }
        }
 
+       /* Hook up MII support for ethtool */
+       mp->mii.dev = dev;
+       mp->mii.mdio_read = mv643xx_mdio_read;
+       mp->mii.mdio_write = mv643xx_mdio_write;
+       mp->mii.phy_id = ethernet_phy_get(port_num);
+       mp->mii.phy_id_mask = 0x3f;
+       mp->mii.reg_num_mask = 0x1f;
+
        err = ethernet_phy_detect(port_num);
        if (err) {
                pr_debug("MV643xx ethernet port %d: "
@@ -1442,6 +1455,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
                return err;
        }
 
+       mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);
+
        err = register_netdev(dev);
        if (err)
                goto out;
@@ -2416,21 +2431,6 @@ static int eth_port_autoneg_supported(unsigned int eth_port_num)
        return phy_reg_data0 & 0x1000;
 }
 
-static int eth_port_link_is_up(unsigned int eth_port_num)
-{
-       unsigned int phy_reg_data1;
-
-       eth_port_read_smi_reg(eth_port_num, 1, &phy_reg_data1);
-
-       if (eth_port_autoneg_supported(eth_port_num)) {
-               if (phy_reg_data1 & 0x20)       /* auto-neg complete */
-                       return 1;
-       } else if (phy_reg_data1 & 0x4)         /* link up */
-               return 1;
-
-       return 0;
-}
-
 /*
  * eth_port_read_smi_reg - Read PHY registers
  *
@@ -2535,6 +2535,24 @@ out:
        spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
 }
 
+/*
+ * Wrappers for MII support library.
+ */
+static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location)
+{
+       int val;
+       struct mv643xx_private *mp = netdev_priv(dev);
+
+       eth_port_read_smi_reg(mp->port_num, location, &val);
+       return val;
+}
+
+static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val)
+{
+       struct mv643xx_private *mp = netdev_priv(dev);
+       eth_port_write_smi_reg(mp->port_num, location, val);
+}
+
 /*
  * eth_port_send - Send an Ethernet packet
  *