aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2009-04-25 08:53:12 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-27 05:53:48 -0400
commitfe192a49118f5b1272317d60c7930ece4e13ae49 (patch)
tree9bafb44af6a43861ec7b906c897ac9f4570124a0 /drivers/net/gianfar.c
parent324931ba21858c34787dee7d222388ef3fb41ee0 (diff)
net: Rework gianfar driver to use of_mdio infrastructure.
This patch simplifies the driver by making use of more common code. Tested on Freescale MPC8349emitxgp eval board Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Acked-by: Andy Fleming <afleming@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r--drivers/net/gianfar.c109
1 files changed, 37 insertions, 72 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index b2c49679bba7..dae14373296a 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -75,6 +75,7 @@
75#include <linux/if_vlan.h> 75#include <linux/if_vlan.h>
76#include <linux/spinlock.h> 76#include <linux/spinlock.h>
77#include <linux/mm.h> 77#include <linux/mm.h>
78#include <linux/of_mdio.h>
78#include <linux/of_platform.h> 79#include <linux/of_platform.h>
79#include <linux/ip.h> 80#include <linux/ip.h>
80#include <linux/tcp.h> 81#include <linux/tcp.h>
@@ -168,17 +169,13 @@ static inline int gfar_uses_fcb(struct gfar_private *priv)
168 169
169static int gfar_of_init(struct net_device *dev) 170static int gfar_of_init(struct net_device *dev)
170{ 171{
171 struct device_node *phy, *mdio;
172 const unsigned int *id;
173 const char *model; 172 const char *model;
174 const char *ctype; 173 const char *ctype;
175 const void *mac_addr; 174 const void *mac_addr;
176 const phandle *ph;
177 u64 addr, size; 175 u64 addr, size;
178 int err = 0; 176 int err = 0;
179 struct gfar_private *priv = netdev_priv(dev); 177 struct gfar_private *priv = netdev_priv(dev);
180 struct device_node *np = priv->node; 178 struct device_node *np = priv->node;
181 char bus_name[MII_BUS_ID_SIZE];
182 const u32 *stash; 179 const u32 *stash;
183 const u32 *stash_len; 180 const u32 *stash_len;
184 const u32 *stash_idx; 181 const u32 *stash_idx;
@@ -264,8 +261,8 @@ static int gfar_of_init(struct net_device *dev)
264 if (of_get_property(np, "fsl,magic-packet", NULL)) 261 if (of_get_property(np, "fsl,magic-packet", NULL))
265 priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; 262 priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
266 263
267 ph = of_get_property(np, "phy-handle", NULL); 264 priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
268 if (ph == NULL) { 265 if (!priv->phy_node) {
269 u32 *fixed_link; 266 u32 *fixed_link;
270 267
271 fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL); 268 fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL);
@@ -273,57 +270,10 @@ static int gfar_of_init(struct net_device *dev)
273 err = -ENODEV; 270 err = -ENODEV;
274 goto err_out; 271 goto err_out;
275 } 272 }
276
277 snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id),
278 PHY_ID_FMT, "0", fixed_link[0]);
279 } else {
280 phy = of_find_node_by_phandle(*ph);
281
282 if (phy == NULL) {
283 err = -ENODEV;
284 goto err_out;
285 }
286
287 mdio = of_get_parent(phy);
288
289 id = of_get_property(phy, "reg", NULL);
290
291 of_node_put(phy);
292
293 fsl_pq_mdio_bus_name(bus_name, mdio);
294 of_node_put(mdio);
295 snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
296 bus_name, *id);
297 } 273 }
298 274
299 /* Find the TBI PHY. If it's not there, we don't support SGMII */ 275 /* Find the TBI PHY. If it's not there, we don't support SGMII */
300 ph = of_get_property(np, "tbi-handle", NULL); 276 priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
301 if (ph) {
302 struct device_node *tbi = of_find_node_by_phandle(*ph);
303 struct of_device *ofdev;
304 struct mii_bus *bus;
305
306 if (!tbi)
307 return 0;
308
309 mdio = of_get_parent(tbi);
310 if (!mdio)
311 return 0;
312
313 ofdev = of_find_device_by_node(mdio);
314
315 of_node_put(mdio);
316
317 id = of_get_property(tbi, "reg", NULL);
318 if (!id)
319 return 0;
320
321 of_node_put(tbi);
322
323 bus = dev_get_drvdata(&ofdev->dev);
324
325 priv->tbiphy = bus->phy_map[*id];
326 }
327 277
328 return 0; 278 return 0;
329 279
@@ -529,6 +479,10 @@ static int gfar_probe(struct of_device *ofdev,
529register_fail: 479register_fail:
530 iounmap(priv->regs); 480 iounmap(priv->regs);
531regs_fail: 481regs_fail:
482 if (priv->phy_node)
483 of_node_put(priv->phy_node);
484 if (priv->tbi_node)
485 of_node_put(priv->tbi_node);
532 free_netdev(dev); 486 free_netdev(dev);
533 return err; 487 return err;
534} 488}
@@ -537,6 +491,11 @@ static int gfar_remove(struct of_device *ofdev)
537{ 491{
538 struct gfar_private *priv = dev_get_drvdata(&ofdev->dev); 492 struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
539 493
494 if (priv->phy_node)
495 of_node_put(priv->phy_node);
496 if (priv->tbi_node)
497 of_node_put(priv->tbi_node);
498
540 dev_set_drvdata(&ofdev->dev, NULL); 499 dev_set_drvdata(&ofdev->dev, NULL);
541 500
542 iounmap(priv->regs); 501 iounmap(priv->regs);
@@ -690,7 +649,6 @@ static int init_phy(struct net_device *dev)
690 uint gigabit_support = 649 uint gigabit_support =
691 priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ? 650 priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
692 SUPPORTED_1000baseT_Full : 0; 651 SUPPORTED_1000baseT_Full : 0;
693 struct phy_device *phydev;
694 phy_interface_t interface; 652 phy_interface_t interface;
695 653
696 priv->oldlink = 0; 654 priv->oldlink = 0;
@@ -699,21 +657,21 @@ static int init_phy(struct net_device *dev)
699 657
700 interface = gfar_get_interface(dev); 658 interface = gfar_get_interface(dev);
701 659
702 phydev = phy_connect(dev, priv->phy_bus_id, &adjust_link, 0, interface); 660 if (priv->phy_node) {
661 priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link,
662 0, interface);
663 if (!priv->phydev) {
664 dev_err(&dev->dev, "error: Could not attach to PHY\n");
665 return -ENODEV;
666 }
667 }
703 668
704 if (interface == PHY_INTERFACE_MODE_SGMII) 669 if (interface == PHY_INTERFACE_MODE_SGMII)
705 gfar_configure_serdes(dev); 670 gfar_configure_serdes(dev);
706 671
707 if (IS_ERR(phydev)) {
708 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
709 return PTR_ERR(phydev);
710 }
711
712 /* Remove any features not supported by the controller */ 672 /* Remove any features not supported by the controller */
713 phydev->supported &= (GFAR_SUPPORTED | gigabit_support); 673 priv->phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
714 phydev->advertising = phydev->supported; 674 priv->phydev->advertising = priv->phydev->supported;
715
716 priv->phydev = phydev;
717 675
718 return 0; 676 return 0;
719} 677}
@@ -730,10 +688,17 @@ static int init_phy(struct net_device *dev)
730static void gfar_configure_serdes(struct net_device *dev) 688static void gfar_configure_serdes(struct net_device *dev)
731{ 689{
732 struct gfar_private *priv = netdev_priv(dev); 690 struct gfar_private *priv = netdev_priv(dev);
691 struct phy_device *tbiphy;
692
693 if (!priv->tbi_node) {
694 dev_warn(&dev->dev, "error: SGMII mode requires that the "
695 "device tree specify a tbi-handle\n");
696 return;
697 }
733 698
734 if (!priv->tbiphy) { 699 tbiphy = of_phy_find_device(priv->tbi_node);
735 printk(KERN_WARNING "SGMII mode requires that the device " 700 if (!tbiphy) {
736 "tree specify a tbi-handle\n"); 701 dev_err(&dev->dev, "error: Could not get TBI device\n");
737 return; 702 return;
738 } 703 }
739 704
@@ -743,17 +708,17 @@ static void gfar_configure_serdes(struct net_device *dev)
743 * everything for us? Resetting it takes the link down and requires 708 * everything for us? Resetting it takes the link down and requires
744 * several seconds for it to come back. 709 * several seconds for it to come back.
745 */ 710 */
746 if (phy_read(priv->tbiphy, MII_BMSR) & BMSR_LSTATUS) 711 if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS)
747 return; 712 return;
748 713
749 /* Single clk mode, mii mode off(for serdes communication) */ 714 /* Single clk mode, mii mode off(for serdes communication) */
750 phy_write(priv->tbiphy, MII_TBICON, TBICON_CLK_SELECT); 715 phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT);
751 716
752 phy_write(priv->tbiphy, MII_ADVERTISE, 717 phy_write(tbiphy, MII_ADVERTISE,
753 ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | 718 ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE |
754 ADVERTISE_1000XPSE_ASYM); 719 ADVERTISE_1000XPSE_ASYM);
755 720
756 phy_write(priv->tbiphy, MII_BMCR, BMCR_ANENABLE | 721 phy_write(tbiphy, MII_BMCR, BMCR_ANENABLE |
757 BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); 722 BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000);
758} 723}
759 724