22 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/types.h>
26 #include <linux/netdevice.h>
28 #include <linux/mii.h>
29 #include <linux/ethtool.h>
32 #ifdef CONFIG_PPC_PMAC
39 static const int phy_BCM5400_link_table[8][3] = {
50 static inline int __phy_read(
struct mii_phy*
phy,
int id,
int reg)
55 static inline void __phy_write(
struct mii_phy* phy,
int id,
int reg,
int val)
75 val = __phy_read(phy, phy_id,
MII_BMCR);
78 __phy_write(phy, phy_id,
MII_BMCR, val);
83 val = __phy_read(phy, phy_id,
MII_BMCR);
89 __phy_write(phy, phy_id,
MII_BMCR, val & ~BMCR_ISOLATE);
94 static int bcm5201_init(
struct mii_phy* phy)
107 static int bcm5201_suspend(
struct mii_phy* phy)
115 static int bcm5221_init(
struct mii_phy* phy)
138 static int bcm5221_suspend(
struct mii_phy* phy)
153 static int bcm5241_init(
struct mii_phy* phy)
176 static int bcm5241_suspend(
struct mii_phy* phy)
191 static int bcm5400_init(
struct mii_phy* phy)
207 (
void)reset_one_mii_phy(phy, 0x1f);
220 static int bcm5400_suspend(
struct mii_phy* phy)
228 static int bcm5401_init(
struct mii_phy* phy)
234 if (rev == 0 || rev == 3) {
267 (
void)reset_one_mii_phy(phy, 0x1f);
276 static int bcm5401_suspend(
struct mii_phy* phy)
284 static int bcm5411_init(
struct mii_phy* phy)
308 (
void)reset_one_mii_phy(phy, 0x1f);
313 static int genmii_setup_aneg(
struct mii_phy *phy,
u32 advertise)
344 static int genmii_setup_forced(
struct mii_phy *phy,
int speed,
int fd)
377 static int genmii_poll_link(
struct mii_phy *phy)
390 static int genmii_read_link(
struct mii_phy *phy)
414 static int generic_suspend(
struct mii_phy* phy)
421 static int bcm5421_init(
struct mii_phy* phy)
429 if (
id == 0x002060e0) {
444 if ((
id & 0xfffffff0) == 0x002062e0) {
450 #ifdef CONFIG_PPC_PMAC
453 int can_low_power = 1;
468 static int bcm54xx_setup_aneg(
struct mii_phy *phy,
u32 advertise)
481 if (advertise & ADVERTISED_10baseT_Half)
483 if (advertise & ADVERTISED_10baseT_Full)
485 if (advertise & ADVERTISED_100baseT_Half)
512 static int bcm54xx_setup_forced(
struct mii_phy *phy,
int speed,
int fd)
547 static int bcm54xx_read_link(
struct mii_phy *phy)
556 phy->
duplex = phy_BCM5400_link_table[link_mode][0] ?
558 phy->
speed = phy_BCM5400_link_table[link_mode][2] ?
560 (phy_BCM5400_link_table[link_mode][1] ?
573 static int marvell88e1111_init(
struct mii_phy* phy)
595 #define BCM5421_MODE_MASK (1 << 5)
597 static int bcm5421_poll_link(
struct mii_phy* phy)
609 return genmii_poll_link(phy);
615 if (phy_reg & 0x0020)
621 static int bcm5421_read_link(
struct mii_phy* phy)
633 return bcm54xx_read_link(phy);
641 if ( (phy_reg & 0x0080) >> 7)
667 #define BCM5461_FIBER_LINK (1 << 2)
668 #define BCM5461_MODE_MASK (3 << 1)
670 static int bcm5461_poll_link(
struct mii_phy* phy)
682 return genmii_poll_link(phy);
694 #define BCM5461_FIBER_DUPLEX (1 << 3)
696 static int bcm5461_read_link(
struct mii_phy* phy)
708 return bcm54xx_read_link(phy);
725 static int bcm5461_enable_fiber(
struct mii_phy* phy,
int autoneg)
744 static int marvell_setup_aneg(
struct mii_phy *phy,
u32 advertise)
757 if (advertise & ADVERTISED_10baseT_Half)
759 if (advertise & ADVERTISED_10baseT_Full)
761 if (advertise & ADVERTISED_100baseT_Half)
763 if (advertise & ADVERTISED_100baseT_Full)
765 if (advertise & ADVERTISED_Pause)
767 if (advertise & ADVERTISED_Asym_Pause)
781 if (advertise & SUPPORTED_1000baseT_Half)
795 static int marvell_setup_forced(
struct mii_phy *phy,
int speed,
int fd)
845 static int marvell_read_link(
struct mii_phy *phy)
865 phy->
pause = (status & pmask) == pmask;
874 #define MII_BASIC_FEATURES \
875 (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
876 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
877 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | \
884 #define MII_GBIT_FEATURES \
885 (MII_BASIC_FEATURES | \
886 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
890 .init = bcm5201_init,
891 .suspend = bcm5201_suspend,
892 .setup_aneg = genmii_setup_aneg,
893 .setup_forced = genmii_setup_forced,
894 .poll_link = genmii_poll_link,
895 .read_link = genmii_read_link,
899 .phy_id = 0x00406210,
900 .phy_id_mask = 0xfffffff0,
904 .ops = &bcm5201_phy_ops
909 .suspend = bcm5221_suspend,
910 .init = bcm5221_init,
911 .setup_aneg = genmii_setup_aneg,
912 .setup_forced = genmii_setup_forced,
913 .poll_link = genmii_poll_link,
914 .read_link = genmii_read_link,
918 .phy_id = 0x004061e0,
919 .phy_id_mask = 0xfffffff0,
923 .ops = &bcm5221_phy_ops
928 .suspend = bcm5241_suspend,
929 .init = bcm5241_init,
930 .setup_aneg = genmii_setup_aneg,
931 .setup_forced = genmii_setup_forced,
932 .poll_link = genmii_poll_link,
933 .read_link = genmii_read_link,
936 .phy_id = 0x0143bc30,
937 .phy_id_mask = 0xfffffff0,
941 .ops = &bcm5241_phy_ops
946 .init = bcm5400_init,
947 .suspend = bcm5400_suspend,
948 .setup_aneg = bcm54xx_setup_aneg,
949 .setup_forced = bcm54xx_setup_forced,
950 .poll_link = genmii_poll_link,
951 .read_link = bcm54xx_read_link,
955 .phy_id = 0x00206040,
956 .phy_id_mask = 0xfffffff0,
960 .ops = &bcm5400_phy_ops
965 .init = bcm5401_init,
966 .suspend = bcm5401_suspend,
967 .setup_aneg = bcm54xx_setup_aneg,
968 .setup_forced = bcm54xx_setup_forced,
969 .poll_link = genmii_poll_link,
970 .read_link = bcm54xx_read_link,
974 .phy_id = 0x00206050,
975 .phy_id_mask = 0xfffffff0,
979 .ops = &bcm5401_phy_ops
984 .init = bcm5411_init,
985 .suspend = generic_suspend,
986 .setup_aneg = bcm54xx_setup_aneg,
987 .setup_forced = bcm54xx_setup_forced,
988 .poll_link = genmii_poll_link,
989 .read_link = bcm54xx_read_link,
993 .phy_id = 0x00206070,
994 .phy_id_mask = 0xfffffff0,
998 .ops = &bcm5411_phy_ops
1003 .init = bcm5421_init,
1004 .suspend = generic_suspend,
1005 .setup_aneg = bcm54xx_setup_aneg,
1006 .setup_forced = bcm54xx_setup_forced,
1007 .poll_link = bcm5421_poll_link,
1008 .read_link = bcm5421_read_link,
1009 .enable_fiber = bcm5421_enable_fiber,
1013 .phy_id = 0x002060e0,
1014 .phy_id_mask = 0xfffffff0,
1018 .ops = &bcm5421_phy_ops
1023 .init = bcm5421_init,
1024 .suspend = generic_suspend,
1025 .setup_aneg = bcm54xx_setup_aneg,
1026 .setup_forced = bcm54xx_setup_forced,
1027 .poll_link = genmii_poll_link,
1028 .read_link = bcm54xx_read_link,
1032 .phy_id = 0x002062e0,
1033 .phy_id_mask = 0xfffffff0,
1034 .name =
"BCM5421-K2",
1037 .ops = &bcm5421k2_phy_ops
1041 .init = bcm5421_init,
1042 .suspend = generic_suspend,
1043 .setup_aneg = bcm54xx_setup_aneg,
1044 .setup_forced = bcm54xx_setup_forced,
1045 .poll_link = bcm5461_poll_link,
1046 .read_link = bcm5461_read_link,
1047 .enable_fiber = bcm5461_enable_fiber,
1051 .phy_id = 0x002060c0,
1052 .phy_id_mask = 0xfffffff0,
1056 .ops = &bcm5461_phy_ops
1061 .init = bcm5421_init,
1062 .suspend = generic_suspend,
1063 .setup_aneg = bcm54xx_setup_aneg,
1064 .setup_forced = bcm54xx_setup_forced,
1065 .poll_link = genmii_poll_link,
1066 .read_link = bcm54xx_read_link,
1070 .phy_id = 0x002060d0,
1071 .phy_id_mask = 0xfffffff0,
1072 .name =
"BCM5462-Vesta",
1075 .ops = &bcm5462V_phy_ops
1079 static struct mii_phy_ops marvell88e1101_phy_ops = {
1080 .suspend = generic_suspend,
1081 .setup_aneg = marvell_setup_aneg,
1082 .setup_forced = marvell_setup_forced,
1083 .poll_link = genmii_poll_link,
1084 .read_link = marvell_read_link
1087 static struct mii_phy_ops marvell88e1111_phy_ops = {
1088 .init = marvell88e1111_init,
1089 .suspend = generic_suspend,
1090 .setup_aneg = marvell_setup_aneg,
1091 .setup_forced = marvell_setup_forced,
1092 .poll_link = genmii_poll_link,
1093 .read_link = marvell_read_link
1099 static struct mii_phy_def marvell88e1101v1_phy_def = {
1100 .phy_id = 0x01410c20,
1101 .phy_id_mask = 0xfffffff0,
1102 .name =
"Marvell 88E1101v1",
1105 .ops = &marvell88e1101_phy_ops
1107 static struct mii_phy_def marvell88e1101v2_phy_def = {
1108 .phy_id = 0x01410c60,
1109 .phy_id_mask = 0xfffffff0,
1110 .name =
"Marvell 88E1101v2",
1113 .ops = &marvell88e1101_phy_ops
1115 static struct mii_phy_def marvell88e1111_phy_def = {
1116 .phy_id = 0x01410cc0,
1117 .phy_id_mask = 0xfffffff0,
1118 .name =
"Marvell 88E1111",
1121 .ops = &marvell88e1111_phy_ops
1126 .setup_aneg = genmii_setup_aneg,
1127 .setup_forced = genmii_setup_forced,
1128 .poll_link = genmii_poll_link,
1129 .read_link = genmii_read_link
1133 .phy_id = 0x00000000,
1134 .phy_id_mask = 0x00000000,
1135 .name =
"Generic MII",
1138 .ops = &generic_phy_ops
1152 &marvell88e1101v1_phy_def,
1153 &marvell88e1101v2_phy_def,
1154 &marvell88e1111_phy_def,
1172 rc = reset_one_mii_phy(phy, mii_id);
1180 for (i=0; (def = mii_phy_table[
i]) !=
NULL; i++)