aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/sungem.c4
-rw-r--r--drivers/net/sungem_phy.c69
-rw-r--r--drivers/net/sungem_phy.h3
3 files changed, 56 insertions, 20 deletions
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 1f5655655c40..2608e7a3d214 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -3079,7 +3079,9 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
3079 gp->phy_mii.dev = dev; 3079 gp->phy_mii.dev = dev;
3080 gp->phy_mii.mdio_read = _phy_read; 3080 gp->phy_mii.mdio_read = _phy_read;
3081 gp->phy_mii.mdio_write = _phy_write; 3081 gp->phy_mii.mdio_write = _phy_write;
3082 3082#ifdef CONFIG_PPC_PMAC
3083 gp->phy_mii.platform_data = gp->of_node;
3084#endif
3083 /* By default, we start with autoneg */ 3085 /* By default, we start with autoneg */
3084 gp->want_autoneg = 1; 3086 gp->want_autoneg = 1;
3085 3087
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 0fca414d3657..d3ddb41d6e5c 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -32,6 +32,10 @@
32#include <linux/ethtool.h> 32#include <linux/ethtool.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34 34
35#ifdef CONFIG_PPC_PMAC
36#include <asm/prom.h>
37#endif
38
35#include "sungem_phy.h" 39#include "sungem_phy.h"
36 40
37/* Link modes of the BCM5400 PHY */ 41/* Link modes of the BCM5400 PHY */
@@ -281,10 +285,12 @@ static int bcm5411_suspend(struct mii_phy* phy)
281static int bcm5421_init(struct mii_phy* phy) 285static int bcm5421_init(struct mii_phy* phy)
282{ 286{
283 u16 data; 287 u16 data;
284 int rev; 288 unsigned int id;
285 289
286 rev = phy_read(phy, MII_PHYSID2) & 0x000f; 290 id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
287 if (rev == 0) { 291
292 /* Revision 0 of 5421 needs some fixups */
293 if (id == 0x002060e0) {
288 /* This is borrowed from MacOS 294 /* This is borrowed from MacOS
289 */ 295 */
290 phy_write(phy, 0x18, 0x1007); 296 phy_write(phy, 0x18, 0x1007);
@@ -297,21 +303,28 @@ static int bcm5421_init(struct mii_phy* phy)
297 data = phy_read(phy, 0x15); 303 data = phy_read(phy, 0x15);
298 phy_write(phy, 0x15, data | 0x0200); 304 phy_write(phy, 0x15, data | 0x0200);
299 } 305 }
300#if 0
301 /* This has to be verified before I enable it */
302 /* Enable automatic low-power */
303 phy_write(phy, 0x1c, 0x9002);
304 phy_write(phy, 0x1c, 0xa821);
305 phy_write(phy, 0x1c, 0x941d);
306#endif
307 return 0;
308}
309 306
310static int bcm5421k2_init(struct mii_phy* phy) 307 /* Pick up some init code from OF for K2 version */
311{ 308 if ((id & 0xfffffff0) == 0x002062e0) {
312 /* Init code borrowed from OF */ 309 phy_write(phy, 4, 0x01e1);
313 phy_write(phy, 4, 0x01e1); 310 phy_write(phy, 9, 0x0300);
314 phy_write(phy, 9, 0x0300); 311 }
312
313 /* Check if we can enable automatic low power */
314#ifdef CONFIG_PPC_PMAC
315 if (phy->platform_data) {
316 struct device_node *np = of_get_parent(phy->platform_data);
317 int can_low_power = 1;
318 if (np == NULL || get_property(np, "no-autolowpower", NULL))
319 can_low_power = 0;
320 if (can_low_power) {
321 /* Enable automatic low-power */
322 phy_write(phy, 0x1c, 0x9002);
323 phy_write(phy, 0x1c, 0xa821);
324 phy_write(phy, 0x1c, 0x941d);
325 }
326 }
327#endif /* CONFIG_PPC_PMAC */
315 328
316 return 0; 329 return 0;
317} 330}
@@ -762,7 +775,7 @@ static struct mii_phy_def bcm5421_phy_def = {
762 775
763/* Broadcom BCM 5421 built-in K2 */ 776/* Broadcom BCM 5421 built-in K2 */
764static struct mii_phy_ops bcm5421k2_phy_ops = { 777static struct mii_phy_ops bcm5421k2_phy_ops = {
765 .init = bcm5421k2_init, 778 .init = bcm5421_init,
766 .suspend = bcm5411_suspend, 779 .suspend = bcm5411_suspend,
767 .setup_aneg = bcm54xx_setup_aneg, 780 .setup_aneg = bcm54xx_setup_aneg,
768 .setup_forced = bcm54xx_setup_forced, 781 .setup_forced = bcm54xx_setup_forced,
@@ -779,6 +792,25 @@ static struct mii_phy_def bcm5421k2_phy_def = {
779 .ops = &bcm5421k2_phy_ops 792 .ops = &bcm5421k2_phy_ops
780}; 793};
781 794
795/* Broadcom BCM 5462 built-in Vesta */
796static struct mii_phy_ops bcm5462V_phy_ops = {
797 .init = bcm5421_init,
798 .suspend = bcm5411_suspend,
799 .setup_aneg = bcm54xx_setup_aneg,
800 .setup_forced = bcm54xx_setup_forced,
801 .poll_link = genmii_poll_link,
802 .read_link = bcm54xx_read_link,
803};
804
805static struct mii_phy_def bcm5462V_phy_def = {
806 .phy_id = 0x002060d0,
807 .phy_id_mask = 0xfffffff0,
808 .name = "BCM5462-Vesta",
809 .features = MII_GBIT_FEATURES,
810 .magic_aneg = 1,
811 .ops = &bcm5462V_phy_ops
812};
813
782/* Marvell 88E1101 (Apple seem to deal with 2 different revs, 814/* Marvell 88E1101 (Apple seem to deal with 2 different revs,
783 * I masked out the 8 last bits to get both, but some specs 815 * I masked out the 8 last bits to get both, but some specs
784 * would be useful here) --BenH. 816 * would be useful here) --BenH.
@@ -824,6 +856,7 @@ static struct mii_phy_def* mii_phy_table[] = {
824 &bcm5411_phy_def, 856 &bcm5411_phy_def,
825 &bcm5421_phy_def, 857 &bcm5421_phy_def,
826 &bcm5421k2_phy_def, 858 &bcm5421k2_phy_def,
859 &bcm5462V_phy_def,
827 &marvell_phy_def, 860 &marvell_phy_def,
828 &genmii_phy_def, 861 &genmii_phy_def,
829 NULL 862 NULL
diff --git a/drivers/net/sungem_phy.h b/drivers/net/sungem_phy.h
index 822cb58174ea..430544496c52 100644
--- a/drivers/net/sungem_phy.h
+++ b/drivers/net/sungem_phy.h
@@ -43,9 +43,10 @@ struct mii_phy
43 int pause; 43 int pause;
44 44
45 /* Provided by host chip */ 45 /* Provided by host chip */
46 struct net_device* dev; 46 struct net_device *dev;
47 int (*mdio_read) (struct net_device *dev, int mii_id, int reg); 47 int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
48 void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val); 48 void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
49 void *platform_data;
49}; 50};
50 51
51/* Pass in a struct mii_phy with dev, mdio_read and mdio_write 52/* Pass in a struct mii_phy with dev, mdio_read and mdio_write