aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-11-12 13:55:41 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-12 13:55:41 -0500
commit8d326d818a2a8fc80c7df85dd88cb214804d1499 (patch)
tree0e59c69d42c2855ae5f63966596b7c22faba897a
parent59af81a14477d88a7a808fda2e2af3225a7d3f02 (diff)
parent7b52314cc44569f56aa07abdbe43e6ccfcef9478 (diff)
Merge branch 'micrel-next'
Johan Hovold says: ==================== net: phy: micrel: refactoring and KSZ8081/KSZ8091 features This series cleans up and refactors parts of the micrel PHY driver, and adds support for broadcast-address-disable and led-mode configuration for KSZ8081 and KSZ8091 PHYs. Specifically, this enables dual KSZ8081 setups (which are limited to using address 0 and 3). A follow up series will add device-type abstraction which will allow for further refactoring and shared initialisation code. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/devicetree/bindings/net/micrel.txt2
-rw-r--r--Documentation/devicetree/bindings/net/phy.txt3
-rw-r--r--drivers/net/phy/micrel.c125
3 files changed, 93 insertions, 37 deletions
diff --git a/Documentation/devicetree/bindings/net/micrel.txt b/Documentation/devicetree/bindings/net/micrel.txt
index e1d99b95c4ec..30062fae5623 100644
--- a/Documentation/devicetree/bindings/net/micrel.txt
+++ b/Documentation/devicetree/bindings/net/micrel.txt
@@ -14,6 +14,8 @@ Optional properties:
14 KSZ8021: register 0x1f, bits 5..4 14 KSZ8021: register 0x1f, bits 5..4
15 KSZ8031: register 0x1f, bits 5..4 15 KSZ8031: register 0x1f, bits 5..4
16 KSZ8051: register 0x1f, bits 5..4 16 KSZ8051: register 0x1f, bits 5..4
17 KSZ8081: register 0x1f, bits 5..4
18 KSZ8091: register 0x1f, bits 5..4
17 19
18 See the respective PHY datasheet for the mode values. 20 See the respective PHY datasheet for the mode values.
19 21
diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt
index 5b8c58903077..40831fbaff72 100644
--- a/Documentation/devicetree/bindings/net/phy.txt
+++ b/Documentation/devicetree/bindings/net/phy.txt
@@ -19,7 +19,6 @@ Optional Properties:
19 specifications. If neither of these are specified, the default is to 19 specifications. If neither of these are specified, the default is to
20 assume clause 22. The compatible list may also contain other 20 assume clause 22. The compatible list may also contain other
21 elements. 21 elements.
22- max-speed: Maximum PHY supported speed (10, 100, 1000...)
23 22
24 If the phy's identifier is known then the list may contain an entry 23 If the phy's identifier is known then the list may contain an entry
25 of the form: "ethernet-phy-idAAAA.BBBB" where 24 of the form: "ethernet-phy-idAAAA.BBBB" where
@@ -29,6 +28,8 @@ Optional Properties:
29 4 hex digits. This is the chip vendor OUI bits 19:24, 28 4 hex digits. This is the chip vendor OUI bits 19:24,
30 followed by 10 bits of a vendor specific ID. 29 followed by 10 bits of a vendor specific ID.
31 30
31- max-speed: Maximum PHY supported speed (10, 100, 1000...)
32
32Example: 33Example:
33 34
34ethernet-phy@0 { 35ethernet-phy@0 {
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index bcc6c0ea75fa..30e894d6ffbd 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -30,30 +30,34 @@
30 30
31/* Operation Mode Strap Override */ 31/* Operation Mode Strap Override */
32#define MII_KSZPHY_OMSO 0x16 32#define MII_KSZPHY_OMSO 0x16
33#define KSZPHY_OMSO_B_CAST_OFF (1 << 9) 33#define KSZPHY_OMSO_B_CAST_OFF BIT(9)
34#define KSZPHY_OMSO_RMII_OVERRIDE (1 << 1) 34#define KSZPHY_OMSO_RMII_OVERRIDE BIT(1)
35#define KSZPHY_OMSO_MII_OVERRIDE (1 << 0) 35#define KSZPHY_OMSO_MII_OVERRIDE BIT(0)
36 36
37/* general Interrupt control/status reg in vendor specific block. */ 37/* general Interrupt control/status reg in vendor specific block. */
38#define MII_KSZPHY_INTCS 0x1B 38#define MII_KSZPHY_INTCS 0x1B
39#define KSZPHY_INTCS_JABBER (1 << 15) 39#define KSZPHY_INTCS_JABBER BIT(15)
40#define KSZPHY_INTCS_RECEIVE_ERR (1 << 14) 40#define KSZPHY_INTCS_RECEIVE_ERR BIT(14)
41#define KSZPHY_INTCS_PAGE_RECEIVE (1 << 13) 41#define KSZPHY_INTCS_PAGE_RECEIVE BIT(13)
42#define KSZPHY_INTCS_PARELLEL (1 << 12) 42#define KSZPHY_INTCS_PARELLEL BIT(12)
43#define KSZPHY_INTCS_LINK_PARTNER_ACK (1 << 11) 43#define KSZPHY_INTCS_LINK_PARTNER_ACK BIT(11)
44#define KSZPHY_INTCS_LINK_DOWN (1 << 10) 44#define KSZPHY_INTCS_LINK_DOWN BIT(10)
45#define KSZPHY_INTCS_REMOTE_FAULT (1 << 9) 45#define KSZPHY_INTCS_REMOTE_FAULT BIT(9)
46#define KSZPHY_INTCS_LINK_UP (1 << 8) 46#define KSZPHY_INTCS_LINK_UP BIT(8)
47#define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\ 47#define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\
48 KSZPHY_INTCS_LINK_DOWN) 48 KSZPHY_INTCS_LINK_DOWN)
49 49
50/* general PHY control reg in vendor specific block. */ 50/* PHY Control 1 */
51#define MII_KSZPHY_CTRL 0x1F 51#define MII_KSZPHY_CTRL_1 0x1e
52
53/* PHY Control 2 / PHY Control (if no PHY Control 1) */
54#define MII_KSZPHY_CTRL_2 0x1f
55#define MII_KSZPHY_CTRL MII_KSZPHY_CTRL_2
52/* bitmap of PHY register to set interrupt mode */ 56/* bitmap of PHY register to set interrupt mode */
53#define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9) 57#define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9)
54#define KSZ9021_CTRL_INT_ACTIVE_HIGH (1 << 14) 58#define KSZ9021_CTRL_INT_ACTIVE_HIGH BIT(14)
55#define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14) 59#define KS8737_CTRL_INT_ACTIVE_HIGH BIT(14)
56#define KSZ8051_RMII_50MHZ_CLK (1 << 7) 60#define KSZ8051_RMII_50MHZ_CLK BIT(7)
57 61
58/* Write/read to/from extended registers */ 62/* Write/read to/from extended registers */
59#define MII_KSZPHY_EXTREG 0x0b 63#define MII_KSZPHY_EXTREG 0x0b
@@ -122,6 +126,8 @@ static int kszphy_config_intr(struct phy_device *phydev)
122 126
123 /* set the interrupt pin active low */ 127 /* set the interrupt pin active low */
124 temp = phy_read(phydev, MII_KSZPHY_CTRL); 128 temp = phy_read(phydev, MII_KSZPHY_CTRL);
129 if (temp < 0)
130 return temp;
125 temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH; 131 temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH;
126 phy_write(phydev, MII_KSZPHY_CTRL, temp); 132 phy_write(phydev, MII_KSZPHY_CTRL, temp);
127 rc = kszphy_set_interrupt(phydev); 133 rc = kszphy_set_interrupt(phydev);
@@ -134,6 +140,8 @@ static int ksz9021_config_intr(struct phy_device *phydev)
134 140
135 /* set the interrupt pin active low */ 141 /* set the interrupt pin active low */
136 temp = phy_read(phydev, MII_KSZPHY_CTRL); 142 temp = phy_read(phydev, MII_KSZPHY_CTRL);
143 if (temp < 0)
144 return temp;
137 temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH; 145 temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH;
138 phy_write(phydev, MII_KSZPHY_CTRL, temp); 146 phy_write(phydev, MII_KSZPHY_CTRL, temp);
139 rc = kszphy_set_interrupt(phydev); 147 rc = kszphy_set_interrupt(phydev);
@@ -146,19 +154,20 @@ static int ks8737_config_intr(struct phy_device *phydev)
146 154
147 /* set the interrupt pin active low */ 155 /* set the interrupt pin active low */
148 temp = phy_read(phydev, MII_KSZPHY_CTRL); 156 temp = phy_read(phydev, MII_KSZPHY_CTRL);
157 if (temp < 0)
158 return temp;
149 temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH; 159 temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH;
150 phy_write(phydev, MII_KSZPHY_CTRL, temp); 160 phy_write(phydev, MII_KSZPHY_CTRL, temp);
151 rc = kszphy_set_interrupt(phydev); 161 rc = kszphy_set_interrupt(phydev);
152 return rc < 0 ? rc : 0; 162 return rc < 0 ? rc : 0;
153} 163}
154 164
155static int kszphy_setup_led(struct phy_device *phydev, 165static int kszphy_setup_led(struct phy_device *phydev, u32 reg)
156 unsigned int reg, unsigned int shift)
157{ 166{
158 167
159 struct device *dev = &phydev->dev; 168 struct device *dev = &phydev->dev;
160 struct device_node *of_node = dev->of_node; 169 struct device_node *of_node = dev->of_node;
161 int rc, temp; 170 int rc, temp, shift;
162 u32 val; 171 u32 val;
163 172
164 if (!of_node && dev->parent->of_node) 173 if (!of_node && dev->parent->of_node)
@@ -167,15 +176,55 @@ static int kszphy_setup_led(struct phy_device *phydev,
167 if (of_property_read_u32(of_node, "micrel,led-mode", &val)) 176 if (of_property_read_u32(of_node, "micrel,led-mode", &val))
168 return 0; 177 return 0;
169 178
179 if (val > 3) {
180 dev_err(&phydev->dev, "invalid led mode: 0x%02x\n", val);
181 return -EINVAL;
182 }
183
184 switch (reg) {
185 case MII_KSZPHY_CTRL_1:
186 shift = 14;
187 break;
188 case MII_KSZPHY_CTRL_2:
189 shift = 4;
190 break;
191 default:
192 return -EINVAL;
193 }
194
170 temp = phy_read(phydev, reg); 195 temp = phy_read(phydev, reg);
171 if (temp < 0) 196 if (temp < 0) {
172 return temp; 197 rc = temp;
198 goto out;
199 }
173 200
174 temp &= ~(3 << shift); 201 temp &= ~(3 << shift);
175 temp |= val << shift; 202 temp |= val << shift;
176 rc = phy_write(phydev, reg, temp); 203 rc = phy_write(phydev, reg, temp);
204out:
205 if (rc < 0)
206 dev_err(&phydev->dev, "failed to set led mode\n");
177 207
178 return rc < 0 ? rc : 0; 208 return rc;
209}
210
211/* Disable PHY address 0 as the broadcast address, so that it can be used as a
212 * unique (non-broadcast) address on a shared bus.
213 */
214static int kszphy_broadcast_disable(struct phy_device *phydev)
215{
216 int ret;
217
218 ret = phy_read(phydev, MII_KSZPHY_OMSO);
219 if (ret < 0)
220 goto out;
221
222 ret = phy_write(phydev, MII_KSZPHY_OMSO, ret | KSZPHY_OMSO_B_CAST_OFF);
223out:
224 if (ret)
225 dev_err(&phydev->dev, "failed to disable broadcast address\n");
226
227 return ret;
179} 228}
180 229
181static int kszphy_config_init(struct phy_device *phydev) 230static int kszphy_config_init(struct phy_device *phydev)
@@ -185,23 +234,21 @@ static int kszphy_config_init(struct phy_device *phydev)
185 234
186static int kszphy_config_init_led8041(struct phy_device *phydev) 235static int kszphy_config_init_led8041(struct phy_device *phydev)
187{ 236{
188 /* single led control, register 0x1e bits 15..14 */ 237 return kszphy_setup_led(phydev, MII_KSZPHY_CTRL_1);
189 return kszphy_setup_led(phydev, 0x1e, 14);
190} 238}
191 239
192static int ksz8021_config_init(struct phy_device *phydev) 240static int ksz8021_config_init(struct phy_device *phydev)
193{ 241{
194 const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE;
195 int rc; 242 int rc;
196 243
197 rc = kszphy_setup_led(phydev, 0x1f, 4); 244 kszphy_setup_led(phydev, MII_KSZPHY_CTRL_2);
198 if (rc)
199 dev_err(&phydev->dev, "failed to set led mode\n");
200 245
201 rc = ksz_config_flags(phydev); 246 rc = ksz_config_flags(phydev);
202 if (rc < 0) 247 if (rc < 0)
203 return rc; 248 return rc;
204 rc = phy_write(phydev, MII_KSZPHY_OMSO, val); 249
250 rc = kszphy_broadcast_disable(phydev);
251
205 return rc < 0 ? rc : 0; 252 return rc < 0 ? rc : 0;
206} 253}
207 254
@@ -209,14 +256,20 @@ static int ks8051_config_init(struct phy_device *phydev)
209{ 256{
210 int rc; 257 int rc;
211 258
212 rc = kszphy_setup_led(phydev, 0x1f, 4); 259 kszphy_setup_led(phydev, MII_KSZPHY_CTRL_2);
213 if (rc)
214 dev_err(&phydev->dev, "failed to set led mode\n");
215 260
216 rc = ksz_config_flags(phydev); 261 rc = ksz_config_flags(phydev);
217 return rc < 0 ? rc : 0; 262 return rc < 0 ? rc : 0;
218} 263}
219 264
265static int ksz8081_config_init(struct phy_device *phydev)
266{
267 kszphy_broadcast_disable(phydev);
268 kszphy_setup_led(phydev, MII_KSZPHY_CTRL_2);
269
270 return 0;
271}
272
220static int ksz9021_load_values_from_of(struct phy_device *phydev, 273static int ksz9021_load_values_from_of(struct phy_device *phydev,
221 struct device_node *of_node, u16 reg, 274 struct device_node *of_node, u16 reg,
222 char *field1, char *field2, 275 char *field1, char *field2,
@@ -394,8 +447,8 @@ static int ksz9031_config_init(struct phy_device *phydev)
394} 447}
395 448
396#define KSZ8873MLL_GLOBAL_CONTROL_4 0x06 449#define KSZ8873MLL_GLOBAL_CONTROL_4 0x06
397#define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX (1 << 6) 450#define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX BIT(6)
398#define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED (1 << 4) 451#define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED BIT(4)
399static int ksz8873mll_read_status(struct phy_device *phydev) 452static int ksz8873mll_read_status(struct phy_device *phydev)
400{ 453{
401 int regval; 454 int regval;
@@ -579,7 +632,7 @@ static struct phy_driver ksphy_driver[] = {
579 .phy_id_mask = 0x00fffff0, 632 .phy_id_mask = 0x00fffff0,
580 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), 633 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
581 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 634 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
582 .config_init = kszphy_config_init, 635 .config_init = ksz8081_config_init,
583 .config_aneg = genphy_config_aneg, 636 .config_aneg = genphy_config_aneg,
584 .read_status = genphy_read_status, 637 .read_status = genphy_read_status,
585 .ack_interrupt = kszphy_ack_interrupt, 638 .ack_interrupt = kszphy_ack_interrupt,