Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] ppc64: Add new PHY to sungem

This patch adds support for some new PHY models to sungem as used on some
recent Apple iMac G5 models.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Benjamin Herrenschmidt and committed by
Linus Torvalds
3c326fe9 155ad605

+56 -20
+3 -1
drivers/net/sungem.c
··· 3079 3079 gp->phy_mii.dev = dev; 3080 3080 gp->phy_mii.mdio_read = _phy_read; 3081 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 3085 /* By default, we start with autoneg */ 3084 3086 gp->want_autoneg = 1; 3085 3087
+51 -18
drivers/net/sungem_phy.c
··· 32 32 #include <linux/ethtool.h> 33 33 #include <linux/delay.h> 34 34 35 + #ifdef CONFIG_PPC_PMAC 36 + #include <asm/prom.h> 37 + #endif 38 + 35 39 #include "sungem_phy.h" 36 40 37 41 /* Link modes of the BCM5400 PHY */ ··· 285 281 static int bcm5421_init(struct mii_phy* phy) 286 282 { 287 283 u16 data; 288 - int rev; 284 + unsigned int id; 289 285 290 - rev = phy_read(phy, MII_PHYSID2) & 0x000f; 291 - if (rev == 0) { 286 + id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2)); 287 + 288 + /* Revision 0 of 5421 needs some fixups */ 289 + if (id == 0x002060e0) { 292 290 /* This is borrowed from MacOS 293 291 */ 294 292 phy_write(phy, 0x18, 0x1007); ··· 303 297 data = phy_read(phy, 0x15); 304 298 phy_write(phy, 0x15, data | 0x0200); 305 299 } 306 - #if 0 307 - /* This has to be verified before I enable it */ 308 - /* Enable automatic low-power */ 309 - phy_write(phy, 0x1c, 0x9002); 310 - phy_write(phy, 0x1c, 0xa821); 311 - phy_write(phy, 0x1c, 0x941d); 312 - #endif 313 - return 0; 314 - } 315 300 316 - static int bcm5421k2_init(struct mii_phy* phy) 317 - { 318 - /* Init code borrowed from OF */ 319 - phy_write(phy, 4, 0x01e1); 320 - phy_write(phy, 9, 0x0300); 301 + /* Pick up some init code from OF for K2 version */ 302 + if ((id & 0xfffffff0) == 0x002062e0) { 303 + phy_write(phy, 4, 0x01e1); 304 + phy_write(phy, 9, 0x0300); 305 + } 306 + 307 + /* Check if we can enable automatic low power */ 308 + #ifdef CONFIG_PPC_PMAC 309 + if (phy->platform_data) { 310 + struct device_node *np = of_get_parent(phy->platform_data); 311 + int can_low_power = 1; 312 + if (np == NULL || get_property(np, "no-autolowpower", NULL)) 313 + can_low_power = 0; 314 + if (can_low_power) { 315 + /* Enable automatic low-power */ 316 + phy_write(phy, 0x1c, 0x9002); 317 + phy_write(phy, 0x1c, 0xa821); 318 + phy_write(phy, 0x1c, 0x941d); 319 + } 320 + } 321 + #endif /* CONFIG_PPC_PMAC */ 321 322 322 323 return 0; 323 324 } ··· 775 762 776 763 /* Broadcom BCM 5421 built-in K2 */ 777 764 static struct mii_phy_ops bcm5421k2_phy_ops = { 778 - .init = bcm5421k2_init, 765 + .init = bcm5421_init, 779 766 .suspend = bcm5411_suspend, 780 767 .setup_aneg = bcm54xx_setup_aneg, 781 768 .setup_forced = bcm54xx_setup_forced, ··· 790 777 .features = MII_GBIT_FEATURES, 791 778 .magic_aneg = 1, 792 779 .ops = &bcm5421k2_phy_ops 780 + }; 781 + 782 + /* Broadcom BCM 5462 built-in Vesta */ 783 + static struct mii_phy_ops bcm5462V_phy_ops = { 784 + .init = bcm5421_init, 785 + .suspend = bcm5411_suspend, 786 + .setup_aneg = bcm54xx_setup_aneg, 787 + .setup_forced = bcm54xx_setup_forced, 788 + .poll_link = genmii_poll_link, 789 + .read_link = bcm54xx_read_link, 790 + }; 791 + 792 + static struct mii_phy_def bcm5462V_phy_def = { 793 + .phy_id = 0x002060d0, 794 + .phy_id_mask = 0xfffffff0, 795 + .name = "BCM5462-Vesta", 796 + .features = MII_GBIT_FEATURES, 797 + .magic_aneg = 1, 798 + .ops = &bcm5462V_phy_ops 793 799 }; 794 800 795 801 /* Marvell 88E1101 (Apple seem to deal with 2 different revs, ··· 856 824 &bcm5411_phy_def, 857 825 &bcm5421_phy_def, 858 826 &bcm5421k2_phy_def, 827 + &bcm5462V_phy_def, 859 828 &marvell_phy_def, 860 829 &genmii_phy_def, 861 830 NULL
+2 -1
drivers/net/sungem_phy.h
··· 43 43 int pause; 44 44 45 45 /* Provided by host chip */ 46 - struct net_device* dev; 46 + struct net_device *dev; 47 47 int (*mdio_read) (struct net_device *dev, int mii_id, int reg); 48 48 void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val); 49 + void *platform_data; 49 50 }; 50 51 51 52 /* Pass in a struct mii_phy with dev, mdio_read and mdio_write