diff options
Diffstat (limited to 'drivers/net/phy/smsc.c')
-rw-r--r-- | drivers/net/phy/smsc.c | 83 |
1 files changed, 75 insertions, 8 deletions
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index b1d8ed40ad98..73baa7a3bb0e 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c | |||
@@ -12,6 +12,8 @@ | |||
12 | * Free Software Foundation; either version 2 of the License, or (at your | 12 | * Free Software Foundation; either version 2 of the License, or (at your |
13 | * option) any later version. | 13 | * option) any later version. |
14 | * | 14 | * |
15 | * Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@smsc.com | ||
16 | * | ||
15 | */ | 17 | */ |
16 | 18 | ||
17 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
@@ -38,7 +40,7 @@ | |||
38 | (MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4) | 40 | (MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4) |
39 | 41 | ||
40 | 42 | ||
41 | static int lan83c185_config_intr(struct phy_device *phydev) | 43 | static int smsc_phy_config_intr(struct phy_device *phydev) |
42 | { | 44 | { |
43 | int rc = phy_write (phydev, MII_LAN83C185_IM, | 45 | int rc = phy_write (phydev, MII_LAN83C185_IM, |
44 | ((PHY_INTERRUPT_ENABLED == phydev->interrupts) | 46 | ((PHY_INTERRUPT_ENABLED == phydev->interrupts) |
@@ -48,16 +50,16 @@ static int lan83c185_config_intr(struct phy_device *phydev) | |||
48 | return rc < 0 ? rc : 0; | 50 | return rc < 0 ? rc : 0; |
49 | } | 51 | } |
50 | 52 | ||
51 | static int lan83c185_ack_interrupt(struct phy_device *phydev) | 53 | static int smsc_phy_ack_interrupt(struct phy_device *phydev) |
52 | { | 54 | { |
53 | int rc = phy_read (phydev, MII_LAN83C185_ISF); | 55 | int rc = phy_read (phydev, MII_LAN83C185_ISF); |
54 | 56 | ||
55 | return rc < 0 ? rc : 0; | 57 | return rc < 0 ? rc : 0; |
56 | } | 58 | } |
57 | 59 | ||
58 | static int lan83c185_config_init(struct phy_device *phydev) | 60 | static int smsc_phy_config_init(struct phy_device *phydev) |
59 | { | 61 | { |
60 | return lan83c185_ack_interrupt (phydev); | 62 | return smsc_phy_ack_interrupt (phydev); |
61 | } | 63 | } |
62 | 64 | ||
63 | 65 | ||
@@ -73,22 +75,87 @@ static struct phy_driver lan83c185_driver = { | |||
73 | /* basic functions */ | 75 | /* basic functions */ |
74 | .config_aneg = genphy_config_aneg, | 76 | .config_aneg = genphy_config_aneg, |
75 | .read_status = genphy_read_status, | 77 | .read_status = genphy_read_status, |
76 | .config_init = lan83c185_config_init, | 78 | .config_init = smsc_phy_config_init, |
77 | 79 | ||
78 | /* IRQ related */ | 80 | /* IRQ related */ |
79 | .ack_interrupt = lan83c185_ack_interrupt, | 81 | .ack_interrupt = smsc_phy_ack_interrupt, |
80 | .config_intr = lan83c185_config_intr, | 82 | .config_intr = smsc_phy_config_intr, |
83 | |||
84 | .driver = { .owner = THIS_MODULE, } | ||
85 | }; | ||
86 | |||
87 | static struct phy_driver lan8187_driver = { | ||
88 | .phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */ | ||
89 | .phy_id_mask = 0xfffffff0, | ||
90 | .name = "SMSC LAN8187", | ||
91 | |||
92 | .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | ||
93 | | SUPPORTED_Asym_Pause), | ||
94 | .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, | ||
95 | |||
96 | /* basic functions */ | ||
97 | .config_aneg = genphy_config_aneg, | ||
98 | .read_status = genphy_read_status, | ||
99 | .config_init = smsc_phy_config_init, | ||
100 | |||
101 | /* IRQ related */ | ||
102 | .ack_interrupt = smsc_phy_ack_interrupt, | ||
103 | .config_intr = smsc_phy_config_intr, | ||
104 | |||
105 | .driver = { .owner = THIS_MODULE, } | ||
106 | }; | ||
107 | |||
108 | static struct phy_driver lan8700_driver = { | ||
109 | .phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */ | ||
110 | .phy_id_mask = 0xfffffff0, | ||
111 | .name = "SMSC LAN8700", | ||
112 | |||
113 | .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | ||
114 | | SUPPORTED_Asym_Pause), | ||
115 | .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, | ||
116 | |||
117 | /* basic functions */ | ||
118 | .config_aneg = genphy_config_aneg, | ||
119 | .read_status = genphy_read_status, | ||
120 | .config_init = smsc_phy_config_init, | ||
121 | |||
122 | /* IRQ related */ | ||
123 | .ack_interrupt = smsc_phy_ack_interrupt, | ||
124 | .config_intr = smsc_phy_config_intr, | ||
81 | 125 | ||
82 | .driver = { .owner = THIS_MODULE, } | 126 | .driver = { .owner = THIS_MODULE, } |
83 | }; | 127 | }; |
84 | 128 | ||
85 | static int __init smsc_init(void) | 129 | static int __init smsc_init(void) |
86 | { | 130 | { |
87 | return phy_driver_register (&lan83c185_driver); | 131 | int ret; |
132 | |||
133 | ret = phy_driver_register (&lan83c185_driver); | ||
134 | if (ret) | ||
135 | goto err1; | ||
136 | |||
137 | ret = phy_driver_register (&lan8187_driver); | ||
138 | if (ret) | ||
139 | goto err2; | ||
140 | |||
141 | ret = phy_driver_register (&lan8700_driver); | ||
142 | if (ret) | ||
143 | goto err3; | ||
144 | |||
145 | return 0; | ||
146 | |||
147 | err3: | ||
148 | phy_driver_unregister (&lan8187_driver); | ||
149 | err2: | ||
150 | phy_driver_unregister (&lan83c185_driver); | ||
151 | err1: | ||
152 | return ret; | ||
88 | } | 153 | } |
89 | 154 | ||
90 | static void __exit smsc_exit(void) | 155 | static void __exit smsc_exit(void) |
91 | { | 156 | { |
157 | phy_driver_unregister (&lan8700_driver); | ||
158 | phy_driver_unregister (&lan8187_driver); | ||
92 | phy_driver_unregister (&lan83c185_driver); | 159 | phy_driver_unregister (&lan83c185_driver); |
93 | } | 160 | } |
94 | 161 | ||