diff options
author | David S. Miller <davem@davemloft.net> | 2008-04-25 03:31:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-25 03:31:07 -0400 |
commit | cc93d7d77d28d65d4f947dabc95a01c42d713ea3 (patch) | |
tree | bdaa01a54c7d881b7087551daf85fa52c61b3d1c /drivers/net/ibm_newemac/core.c | |
parent | 461e6c856faf9cdd8862fa4d0785974a64e39dba (diff) | |
parent | f946dffed6334f08da065a89ed65026ebf8b33b4 (diff) |
Merge branch 'upstream-davem' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'drivers/net/ibm_newemac/core.c')
-rw-r--r-- | drivers/net/ibm_newemac/core.c | 83 |
1 files changed, 73 insertions, 10 deletions
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 378a23963495..5d2108c5ac7c 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <asm/io.h> | 43 | #include <asm/io.h> |
44 | #include <asm/dma.h> | 44 | #include <asm/dma.h> |
45 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
46 | #include <asm/dcr.h> | ||
47 | #include <asm/dcr-regs.h> | ||
46 | 48 | ||
47 | #include "core.h" | 49 | #include "core.h" |
48 | 50 | ||
@@ -127,10 +129,35 @@ static struct device_node *emac_boot_list[EMAC_BOOT_LIST_SIZE]; | |||
127 | static inline void emac_report_timeout_error(struct emac_instance *dev, | 129 | static inline void emac_report_timeout_error(struct emac_instance *dev, |
128 | const char *error) | 130 | const char *error) |
129 | { | 131 | { |
130 | if (net_ratelimit()) | 132 | if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX | |
133 | EMAC_FTR_440EP_PHY_CLK_FIX)) | ||
134 | DBG(dev, "%s" NL, error); | ||
135 | else if (net_ratelimit()) | ||
131 | printk(KERN_ERR "%s: %s\n", dev->ndev->name, error); | 136 | printk(KERN_ERR "%s: %s\n", dev->ndev->name, error); |
132 | } | 137 | } |
133 | 138 | ||
139 | /* EMAC PHY clock workaround: | ||
140 | * 440EP/440GR has more sane SDR0_MFR register implementation than 440GX, | ||
141 | * which allows controlling each EMAC clock | ||
142 | */ | ||
143 | static inline void emac_rx_clk_tx(struct emac_instance *dev) | ||
144 | { | ||
145 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
146 | if (emac_has_feature(dev, EMAC_FTR_440EP_PHY_CLK_FIX)) | ||
147 | dcri_clrset(SDR0, SDR0_MFR, | ||
148 | 0, SDR0_MFR_ECS >> dev->cell_index); | ||
149 | #endif | ||
150 | } | ||
151 | |||
152 | static inline void emac_rx_clk_default(struct emac_instance *dev) | ||
153 | { | ||
154 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
155 | if (emac_has_feature(dev, EMAC_FTR_440EP_PHY_CLK_FIX)) | ||
156 | dcri_clrset(SDR0, SDR0_MFR, | ||
157 | SDR0_MFR_ECS >> dev->cell_index, 0); | ||
158 | #endif | ||
159 | } | ||
160 | |||
134 | /* PHY polling intervals */ | 161 | /* PHY polling intervals */ |
135 | #define PHY_POLL_LINK_ON HZ | 162 | #define PHY_POLL_LINK_ON HZ |
136 | #define PHY_POLL_LINK_OFF (HZ / 5) | 163 | #define PHY_POLL_LINK_OFF (HZ / 5) |
@@ -524,7 +551,10 @@ static int emac_configure(struct emac_instance *dev) | |||
524 | rx_size = dev->rx_fifo_size_gige; | 551 | rx_size = dev->rx_fifo_size_gige; |
525 | 552 | ||
526 | if (dev->ndev->mtu > ETH_DATA_LEN) { | 553 | if (dev->ndev->mtu > ETH_DATA_LEN) { |
527 | mr1 |= EMAC_MR1_JPSM; | 554 | if (emac_has_feature(dev, EMAC_FTR_EMAC4)) |
555 | mr1 |= EMAC4_MR1_JPSM; | ||
556 | else | ||
557 | mr1 |= EMAC_MR1_JPSM; | ||
528 | dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO; | 558 | dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO; |
529 | } else | 559 | } else |
530 | dev->stop_timeout = STOP_TIMEOUT_1000; | 560 | dev->stop_timeout = STOP_TIMEOUT_1000; |
@@ -708,7 +738,7 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg) | |||
708 | rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port); | 738 | rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port); |
709 | 739 | ||
710 | /* Wait for management interface to become idle */ | 740 | /* Wait for management interface to become idle */ |
711 | n = 10; | 741 | n = 20; |
712 | while (!emac_phy_done(dev, in_be32(&p->stacr))) { | 742 | while (!emac_phy_done(dev, in_be32(&p->stacr))) { |
713 | udelay(1); | 743 | udelay(1); |
714 | if (!--n) { | 744 | if (!--n) { |
@@ -733,7 +763,7 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg) | |||
733 | out_be32(&p->stacr, r); | 763 | out_be32(&p->stacr, r); |
734 | 764 | ||
735 | /* Wait for read to complete */ | 765 | /* Wait for read to complete */ |
736 | n = 100; | 766 | n = 200; |
737 | while (!emac_phy_done(dev, (r = in_be32(&p->stacr)))) { | 767 | while (!emac_phy_done(dev, (r = in_be32(&p->stacr)))) { |
738 | udelay(1); | 768 | udelay(1); |
739 | if (!--n) { | 769 | if (!--n) { |
@@ -780,7 +810,7 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg, | |||
780 | rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port); | 810 | rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port); |
781 | 811 | ||
782 | /* Wait for management interface to be idle */ | 812 | /* Wait for management interface to be idle */ |
783 | n = 10; | 813 | n = 20; |
784 | while (!emac_phy_done(dev, in_be32(&p->stacr))) { | 814 | while (!emac_phy_done(dev, in_be32(&p->stacr))) { |
785 | udelay(1); | 815 | udelay(1); |
786 | if (!--n) { | 816 | if (!--n) { |
@@ -806,7 +836,7 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg, | |||
806 | out_be32(&p->stacr, r); | 836 | out_be32(&p->stacr, r); |
807 | 837 | ||
808 | /* Wait for write to complete */ | 838 | /* Wait for write to complete */ |
809 | n = 100; | 839 | n = 200; |
810 | while (!emac_phy_done(dev, in_be32(&p->stacr))) { | 840 | while (!emac_phy_done(dev, in_be32(&p->stacr))) { |
811 | udelay(1); | 841 | udelay(1); |
812 | if (!--n) { | 842 | if (!--n) { |
@@ -1094,9 +1124,11 @@ static int emac_open(struct net_device *ndev) | |||
1094 | int link_poll_interval; | 1124 | int link_poll_interval; |
1095 | if (dev->phy.def->ops->poll_link(&dev->phy)) { | 1125 | if (dev->phy.def->ops->poll_link(&dev->phy)) { |
1096 | dev->phy.def->ops->read_link(&dev->phy); | 1126 | dev->phy.def->ops->read_link(&dev->phy); |
1127 | emac_rx_clk_default(dev); | ||
1097 | netif_carrier_on(dev->ndev); | 1128 | netif_carrier_on(dev->ndev); |
1098 | link_poll_interval = PHY_POLL_LINK_ON; | 1129 | link_poll_interval = PHY_POLL_LINK_ON; |
1099 | } else { | 1130 | } else { |
1131 | emac_rx_clk_tx(dev); | ||
1100 | netif_carrier_off(dev->ndev); | 1132 | netif_carrier_off(dev->ndev); |
1101 | link_poll_interval = PHY_POLL_LINK_OFF; | 1133 | link_poll_interval = PHY_POLL_LINK_OFF; |
1102 | } | 1134 | } |
@@ -1174,6 +1206,7 @@ static void emac_link_timer(struct work_struct *work) | |||
1174 | 1206 | ||
1175 | if (dev->phy.def->ops->poll_link(&dev->phy)) { | 1207 | if (dev->phy.def->ops->poll_link(&dev->phy)) { |
1176 | if (!netif_carrier_ok(dev->ndev)) { | 1208 | if (!netif_carrier_ok(dev->ndev)) { |
1209 | emac_rx_clk_default(dev); | ||
1177 | /* Get new link parameters */ | 1210 | /* Get new link parameters */ |
1178 | dev->phy.def->ops->read_link(&dev->phy); | 1211 | dev->phy.def->ops->read_link(&dev->phy); |
1179 | 1212 | ||
@@ -1186,6 +1219,7 @@ static void emac_link_timer(struct work_struct *work) | |||
1186 | link_poll_interval = PHY_POLL_LINK_ON; | 1219 | link_poll_interval = PHY_POLL_LINK_ON; |
1187 | } else { | 1220 | } else { |
1188 | if (netif_carrier_ok(dev->ndev)) { | 1221 | if (netif_carrier_ok(dev->ndev)) { |
1222 | emac_rx_clk_tx(dev); | ||
1189 | netif_carrier_off(dev->ndev); | 1223 | netif_carrier_off(dev->ndev); |
1190 | netif_tx_disable(dev->ndev); | 1224 | netif_tx_disable(dev->ndev); |
1191 | emac_reinitialize(dev); | 1225 | emac_reinitialize(dev); |
@@ -2237,7 +2271,7 @@ static int __devinit emac_of_bus_notify(struct notifier_block *nb, | |||
2237 | return 0; | 2271 | return 0; |
2238 | } | 2272 | } |
2239 | 2273 | ||
2240 | static struct notifier_block emac_of_bus_notifier = { | 2274 | static struct notifier_block emac_of_bus_notifier __devinitdata = { |
2241 | .notifier_call = emac_of_bus_notify | 2275 | .notifier_call = emac_of_bus_notify |
2242 | }; | 2276 | }; |
2243 | 2277 | ||
@@ -2330,6 +2364,19 @@ static int __devinit emac_init_phy(struct emac_instance *dev) | |||
2330 | dev->phy.mdio_read = emac_mdio_read; | 2364 | dev->phy.mdio_read = emac_mdio_read; |
2331 | dev->phy.mdio_write = emac_mdio_write; | 2365 | dev->phy.mdio_write = emac_mdio_write; |
2332 | 2366 | ||
2367 | /* Enable internal clock source */ | ||
2368 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
2369 | if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX)) | ||
2370 | dcri_clrset(SDR0, SDR0_MFR, 0, SDR0_MFR_ECS); | ||
2371 | #endif | ||
2372 | /* PHY clock workaround */ | ||
2373 | emac_rx_clk_tx(dev); | ||
2374 | |||
2375 | /* Enable internal clock source on 440GX*/ | ||
2376 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
2377 | if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX)) | ||
2378 | dcri_clrset(SDR0, SDR0_MFR, 0, SDR0_MFR_ECS); | ||
2379 | #endif | ||
2333 | /* Configure EMAC with defaults so we can at least use MDIO | 2380 | /* Configure EMAC with defaults so we can at least use MDIO |
2334 | * This is needed mostly for 440GX | 2381 | * This is needed mostly for 440GX |
2335 | */ | 2382 | */ |
@@ -2362,6 +2409,12 @@ static int __devinit emac_init_phy(struct emac_instance *dev) | |||
2362 | if (!emac_mii_phy_probe(&dev->phy, i)) | 2409 | if (!emac_mii_phy_probe(&dev->phy, i)) |
2363 | break; | 2410 | break; |
2364 | } | 2411 | } |
2412 | |||
2413 | /* Enable external clock source */ | ||
2414 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
2415 | if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX)) | ||
2416 | dcri_clrset(SDR0, SDR0_MFR, SDR0_MFR_ECS, 0); | ||
2417 | #endif | ||
2365 | mutex_unlock(&emac_phy_map_lock); | 2418 | mutex_unlock(&emac_phy_map_lock); |
2366 | if (i == 0x20) { | 2419 | if (i == 0x20) { |
2367 | printk(KERN_WARNING "%s: can't find PHY!\n", np->full_name); | 2420 | printk(KERN_WARNING "%s: can't find PHY!\n", np->full_name); |
@@ -2487,8 +2540,15 @@ static int __devinit emac_init_config(struct emac_instance *dev) | |||
2487 | } | 2540 | } |
2488 | 2541 | ||
2489 | /* Check EMAC version */ | 2542 | /* Check EMAC version */ |
2490 | if (of_device_is_compatible(np, "ibm,emac4")) | 2543 | if (of_device_is_compatible(np, "ibm,emac4")) { |
2491 | dev->features |= EMAC_FTR_EMAC4; | 2544 | dev->features |= EMAC_FTR_EMAC4; |
2545 | if (of_device_is_compatible(np, "ibm,emac-440gx")) | ||
2546 | dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX; | ||
2547 | } else { | ||
2548 | if (of_device_is_compatible(np, "ibm,emac-440ep") || | ||
2549 | of_device_is_compatible(np, "ibm,emac-440gr")) | ||
2550 | dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX; | ||
2551 | } | ||
2492 | 2552 | ||
2493 | /* Fixup some feature bits based on the device tree */ | 2553 | /* Fixup some feature bits based on the device tree */ |
2494 | if (of_get_property(np, "has-inverted-stacr-oc", NULL)) | 2554 | if (of_get_property(np, "has-inverted-stacr-oc", NULL)) |
@@ -2559,8 +2619,11 @@ static int __devinit emac_probe(struct of_device *ofdev, | |||
2559 | struct device_node **blist = NULL; | 2619 | struct device_node **blist = NULL; |
2560 | int err, i; | 2620 | int err, i; |
2561 | 2621 | ||
2562 | /* Skip unused/unwired EMACS */ | 2622 | /* Skip unused/unwired EMACS. We leave the check for an unused |
2563 | if (of_get_property(np, "unused", NULL)) | 2623 | * property here for now, but new flat device trees should set a |
2624 | * status property to "disabled" instead. | ||
2625 | */ | ||
2626 | if (of_get_property(np, "unused", NULL) || !of_device_is_available(np)) | ||
2564 | return -ENODEV; | 2627 | return -ENODEV; |
2565 | 2628 | ||
2566 | /* Find ourselves in the bootlist if we are there */ | 2629 | /* Find ourselves in the bootlist if we are there */ |