summaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2015-04-01 22:06:36 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-01 22:55:40 -0400
commitfd3a0ee4063e4f44d915df8f117d9e0d8b05950a (patch)
tree4852b462842e2e06bfccd0f16b817affb48f6d91 /drivers/net/dsa
parent4914358567d81d6f1d95f7809c77658c55555f1c (diff)
net: dsa: Consolidate phy read and write functions
Move the common code for reading and writing phy registers into the shared mv88e6xxx. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r--drivers/net/dsa/mv88e6123_61_65.c46
-rw-r--r--drivers/net/dsa/mv88e6171.c40
-rw-r--r--drivers/net/dsa/mv88e6352.c45
-rw-r--r--drivers/net/dsa/mv88e6xxx.c118
-rw-r--r--drivers/net/dsa/mv88e6xxx.h7
5 files changed, 110 insertions, 146 deletions
diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index 10228ad48151..5f536722f7c7 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -277,48 +277,6 @@ static int mv88e6123_61_65_setup(struct dsa_switch *ds)
277 return 0; 277 return 0;
278} 278}
279 279
280static int mv88e6123_61_65_port_to_phy_addr(struct dsa_switch *ds, int port)
281{
282 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
283
284 if (port >= 0 && port < ps->num_ports)
285 return port;
286 return -EINVAL;
287}
288
289static int
290mv88e6123_61_65_phy_read(struct dsa_switch *ds, int port, int regnum)
291{
292 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
293 int addr = mv88e6123_61_65_port_to_phy_addr(ds, port);
294 int ret;
295
296 if (addr < 0)
297 return addr;
298
299 mutex_lock(&ps->phy_mutex);
300 ret = mv88e6xxx_phy_read(ds, addr, regnum);
301 mutex_unlock(&ps->phy_mutex);
302 return ret;
303}
304
305static int
306mv88e6123_61_65_phy_write(struct dsa_switch *ds,
307 int port, int regnum, u16 val)
308{
309 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
310 int addr = mv88e6123_61_65_port_to_phy_addr(ds, port);
311 int ret;
312
313 if (addr < 0)
314 return addr;
315
316 mutex_lock(&ps->phy_mutex);
317 ret = mv88e6xxx_phy_write(ds, addr, regnum, val);
318 mutex_unlock(&ps->phy_mutex);
319 return ret;
320}
321
322static struct mv88e6xxx_hw_stat mv88e6123_61_65_hw_stats[] = { 280static struct mv88e6xxx_hw_stat mv88e6123_61_65_hw_stats[] = {
323 { "in_good_octets", 8, 0x00, }, 281 { "in_good_octets", 8, 0x00, },
324 { "in_bad_octets", 4, 0x02, }, 282 { "in_bad_octets", 4, 0x02, },
@@ -381,8 +339,8 @@ struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
381 .probe = mv88e6123_61_65_probe, 339 .probe = mv88e6123_61_65_probe,
382 .setup = mv88e6123_61_65_setup, 340 .setup = mv88e6123_61_65_setup,
383 .set_addr = mv88e6xxx_set_addr_indirect, 341 .set_addr = mv88e6xxx_set_addr_indirect,
384 .phy_read = mv88e6123_61_65_phy_read, 342 .phy_read = mv88e6xxx_phy_read,
385 .phy_write = mv88e6123_61_65_phy_write, 343 .phy_write = mv88e6xxx_phy_write,
386 .poll_link = mv88e6xxx_poll_link, 344 .poll_link = mv88e6xxx_poll_link,
387 .get_strings = mv88e6123_61_65_get_strings, 345 .get_strings = mv88e6123_61_65_get_strings,
388 .get_ethtool_stats = mv88e6123_61_65_get_ethtool_stats, 346 .get_ethtool_stats = mv88e6123_61_65_get_ethtool_stats,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 69b35d124de5..4d6038991a59 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -258,42 +258,6 @@ static int mv88e6171_setup(struct dsa_switch *ds)
258 return 0; 258 return 0;
259} 259}
260 260
261static int mv88e6171_port_to_phy_addr(struct dsa_switch *ds, int port)
262{
263 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
264
265 if (port >= 0 && port < ps->num_ports)
266 return port;
267 return -1;
268}
269
270static int
271mv88e6171_phy_read(struct dsa_switch *ds, int port, int regnum)
272{
273 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
274 int addr = mv88e6171_port_to_phy_addr(ds, port);
275 int ret;
276
277 mutex_lock(&ps->phy_mutex);
278 ret = mv88e6xxx_phy_read_indirect(ds, addr, regnum);
279 mutex_unlock(&ps->phy_mutex);
280 return ret;
281}
282
283static int
284mv88e6171_phy_write(struct dsa_switch *ds,
285 int port, int regnum, u16 val)
286{
287 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
288 int addr = mv88e6171_port_to_phy_addr(ds, port);
289 int ret;
290
291 mutex_lock(&ps->phy_mutex);
292 ret = mv88e6xxx_phy_write_indirect(ds, addr, regnum, val);
293 mutex_unlock(&ps->phy_mutex);
294 return ret;
295}
296
297static struct mv88e6xxx_hw_stat mv88e6171_hw_stats[] = { 261static struct mv88e6xxx_hw_stat mv88e6171_hw_stats[] = {
298 { "in_good_octets", 8, 0x00, }, 262 { "in_good_octets", 8, 0x00, },
299 { "in_bad_octets", 4, 0x02, }, 263 { "in_bad_octets", 4, 0x02, },
@@ -375,8 +339,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
375 .probe = mv88e6171_probe, 339 .probe = mv88e6171_probe,
376 .setup = mv88e6171_setup, 340 .setup = mv88e6171_setup,
377 .set_addr = mv88e6xxx_set_addr_indirect, 341 .set_addr = mv88e6xxx_set_addr_indirect,
378 .phy_read = mv88e6171_phy_read, 342 .phy_read = mv88e6xxx_phy_read_indirect,
379 .phy_write = mv88e6171_phy_write, 343 .phy_write = mv88e6xxx_phy_write_indirect,
380 .poll_link = mv88e6xxx_poll_link, 344 .poll_link = mv88e6xxx_poll_link,
381 .get_strings = mv88e6171_get_strings, 345 .get_strings = mv88e6171_get_strings,
382 .get_ethtool_stats = mv88e6171_get_ethtool_stats, 346 .get_ethtool_stats = mv88e6171_get_ethtool_stats,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index fb16671c5f92..3806ff1aaa9c 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -321,47 +321,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
321 return 0; 321 return 0;
322} 322}
323 323
324static int mv88e6352_port_to_phy_addr(int port)
325{
326 if (port >= 0 && port <= 4)
327 return port;
328 return -EINVAL;
329}
330
331static int
332mv88e6352_phy_read(struct dsa_switch *ds, int port, int regnum)
333{
334 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
335 int addr = mv88e6352_port_to_phy_addr(port);
336 int ret;
337
338 if (addr < 0)
339 return addr;
340
341 mutex_lock(&ps->phy_mutex);
342 ret = mv88e6xxx_phy_read_indirect(ds, addr, regnum);
343 mutex_unlock(&ps->phy_mutex);
344
345 return ret;
346}
347
348static int
349mv88e6352_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
350{
351 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
352 int addr = mv88e6352_port_to_phy_addr(port);
353 int ret;
354
355 if (addr < 0)
356 return addr;
357
358 mutex_lock(&ps->phy_mutex);
359 ret = mv88e6xxx_phy_write_indirect(ds, addr, regnum, val);
360 mutex_unlock(&ps->phy_mutex);
361
362 return ret;
363}
364
365static struct mv88e6xxx_hw_stat mv88e6352_hw_stats[] = { 324static struct mv88e6xxx_hw_stat mv88e6352_hw_stats[] = {
366 { "in_good_octets", 8, 0x00, }, 325 { "in_good_octets", 8, 0x00, },
367 { "in_bad_octets", 4, 0x02, }, 326 { "in_bad_octets", 4, 0x02, },
@@ -621,8 +580,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
621 .probe = mv88e6352_probe, 580 .probe = mv88e6352_probe,
622 .setup = mv88e6352_setup, 581 .setup = mv88e6352_setup,
623 .set_addr = mv88e6xxx_set_addr_indirect, 582 .set_addr = mv88e6xxx_set_addr_indirect,
624 .phy_read = mv88e6352_phy_read, 583 .phy_read = mv88e6xxx_phy_read_indirect,
625 .phy_write = mv88e6352_phy_write, 584 .phy_write = mv88e6xxx_phy_write_indirect,
626 .poll_link = mv88e6xxx_poll_link, 585 .poll_link = mv88e6xxx_poll_link,
627 .get_strings = mv88e6352_get_strings, 586 .get_strings = mv88e6352_get_strings,
628 .get_ethtool_stats = mv88e6352_get_ethtool_stats, 587 .get_ethtool_stats = mv88e6352_get_ethtool_stats,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index df727e1db18d..7c4c04bb0cb0 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -214,14 +214,17 @@ int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
214 return 0; 214 return 0;
215} 215}
216 216
217int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum) 217/* Must be called with phy mutex held */
218static int _mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum)
218{ 219{
219 if (addr >= 0) 220 if (addr >= 0)
220 return mv88e6xxx_reg_read(ds, addr, regnum); 221 return mv88e6xxx_reg_read(ds, addr, regnum);
221 return 0xffff; 222 return 0xffff;
222} 223}
223 224
224int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val) 225/* Must be called with phy mutex held */
226static int _mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum,
227 u16 val)
225{ 228{
226 if (addr >= 0) 229 if (addr >= 0)
227 return mv88e6xxx_reg_write(ds, addr, regnum, val); 230 return mv88e6xxx_reg_write(ds, addr, regnum, val);
@@ -579,37 +582,37 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
579 582
580 mutex_lock(&ps->phy_mutex); 583 mutex_lock(&ps->phy_mutex);
581 584
582 ret = mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6); 585 ret = _mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6);
583 if (ret < 0) 586 if (ret < 0)
584 goto error; 587 goto error;
585 588
586 /* Enable temperature sensor */ 589 /* Enable temperature sensor */
587 ret = mv88e6xxx_phy_read(ds, 0x0, 0x1a); 590 ret = _mv88e6xxx_phy_read(ds, 0x0, 0x1a);
588 if (ret < 0) 591 if (ret < 0)
589 goto error; 592 goto error;
590 593
591 ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5)); 594 ret = _mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5));
592 if (ret < 0) 595 if (ret < 0)
593 goto error; 596 goto error;
594 597
595 /* Wait for temperature to stabilize */ 598 /* Wait for temperature to stabilize */
596 usleep_range(10000, 12000); 599 usleep_range(10000, 12000);
597 600
598 val = mv88e6xxx_phy_read(ds, 0x0, 0x1a); 601 val = _mv88e6xxx_phy_read(ds, 0x0, 0x1a);
599 if (val < 0) { 602 if (val < 0) {
600 ret = val; 603 ret = val;
601 goto error; 604 goto error;
602 } 605 }
603 606
604 /* Disable temperature sensor */ 607 /* Disable temperature sensor */
605 ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5)); 608 ret = _mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5));
606 if (ret < 0) 609 if (ret < 0)
607 goto error; 610 goto error;
608 611
609 *temp = ((val & 0x1f) - 5) * 5; 612 *temp = ((val & 0x1f) - 5) * 5;
610 613
611error: 614error:
612 mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0); 615 _mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0);
613 mutex_unlock(&ps->phy_mutex); 616 mutex_unlock(&ps->phy_mutex);
614 return ret; 617 return ret;
615} 618}
@@ -671,7 +674,9 @@ static int _mv88e6xxx_atu_wait(struct dsa_switch *ds)
671 return _mv88e6xxx_wait(ds, REG_GLOBAL, 0x0b, ATU_BUSY); 674 return _mv88e6xxx_wait(ds, REG_GLOBAL, 0x0b, ATU_BUSY);
672} 675}
673 676
674int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum) 677/* Must be called with phy mutex held */
678static int _mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr,
679 int regnum)
675{ 680{
676 int ret; 681 int ret;
677 682
@@ -684,8 +689,9 @@ int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum)
684 return REG_READ(REG_GLOBAL2, 0x19); 689 return REG_READ(REG_GLOBAL2, 0x19);
685} 690}
686 691
687int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, 692/* Must be called with phy mutex held */
688 u16 val) 693static int _mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr,
694 int regnum, u16 val)
689{ 695{
690 REG_WRITE(REG_GLOBAL2, 0x19, val); 696 REG_WRITE(REG_GLOBAL2, 0x19, val);
691 REG_WRITE(REG_GLOBAL2, 0x18, 0x9400 | (addr << 5) | regnum); 697 REG_WRITE(REG_GLOBAL2, 0x18, 0x9400 | (addr << 5) | regnum);
@@ -715,7 +721,7 @@ static int mv88e6xxx_eee_enable_set(struct dsa_switch *ds, int port,
715{ 721{
716 int reg, nreg; 722 int reg, nreg;
717 723
718 reg = mv88e6xxx_phy_read_indirect(ds, port, 16); 724 reg = _mv88e6xxx_phy_read_indirect(ds, port, 16);
719 if (reg < 0) 725 if (reg < 0)
720 return reg; 726 return reg;
721 727
@@ -726,7 +732,7 @@ static int mv88e6xxx_eee_enable_set(struct dsa_switch *ds, int port,
726 nreg |= 0x0100; 732 nreg |= 0x0100;
727 733
728 if (nreg != reg) 734 if (nreg != reg)
729 return mv88e6xxx_phy_write_indirect(ds, port, 16, nreg); 735 return _mv88e6xxx_phy_write_indirect(ds, port, 16, nreg);
730 736
731 return 0; 737 return 0;
732} 738}
@@ -1207,12 +1213,12 @@ int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg)
1207 int ret; 1213 int ret;
1208 1214
1209 mutex_lock(&ps->phy_mutex); 1215 mutex_lock(&ps->phy_mutex);
1210 ret = mv88e6xxx_phy_write_indirect(ds, port, 0x16, page); 1216 ret = _mv88e6xxx_phy_write_indirect(ds, port, 0x16, page);
1211 if (ret < 0) 1217 if (ret < 0)
1212 goto error; 1218 goto error;
1213 ret = mv88e6xxx_phy_read_indirect(ds, port, reg); 1219 ret = _mv88e6xxx_phy_read_indirect(ds, port, reg);
1214error: 1220error:
1215 mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0); 1221 _mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0);
1216 mutex_unlock(&ps->phy_mutex); 1222 mutex_unlock(&ps->phy_mutex);
1217 return ret; 1223 return ret;
1218} 1224}
@@ -1224,13 +1230,87 @@ int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page,
1224 int ret; 1230 int ret;
1225 1231
1226 mutex_lock(&ps->phy_mutex); 1232 mutex_lock(&ps->phy_mutex);
1227 ret = mv88e6xxx_phy_write_indirect(ds, port, 0x16, page); 1233 ret = _mv88e6xxx_phy_write_indirect(ds, port, 0x16, page);
1228 if (ret < 0) 1234 if (ret < 0)
1229 goto error; 1235 goto error;
1230 1236
1231 ret = mv88e6xxx_phy_write_indirect(ds, port, reg, val); 1237 ret = _mv88e6xxx_phy_write_indirect(ds, port, reg, val);
1232error: 1238error:
1233 mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0); 1239 _mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0);
1240 mutex_unlock(&ps->phy_mutex);
1241 return ret;
1242}
1243
1244static int mv88e6xxx_port_to_phy_addr(struct dsa_switch *ds, int port)
1245{
1246 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1247
1248 if (port >= 0 && port < ps->num_ports)
1249 return port;
1250 return -EINVAL;
1251}
1252
1253int
1254mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
1255{
1256 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1257 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1258 int ret;
1259
1260 if (addr < 0)
1261 return addr;
1262
1263 mutex_lock(&ps->phy_mutex);
1264 ret = _mv88e6xxx_phy_read(ds, addr, regnum);
1265 mutex_unlock(&ps->phy_mutex);
1266 return ret;
1267}
1268
1269int
1270mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
1271{
1272 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1273 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1274 int ret;
1275
1276 if (addr < 0)
1277 return addr;
1278
1279 mutex_lock(&ps->phy_mutex);
1280 ret = _mv88e6xxx_phy_write(ds, addr, regnum, val);
1281 mutex_unlock(&ps->phy_mutex);
1282 return ret;
1283}
1284
1285int
1286mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum)
1287{
1288 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1289 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1290 int ret;
1291
1292 if (addr < 0)
1293 return addr;
1294
1295 mutex_lock(&ps->phy_mutex);
1296 ret = _mv88e6xxx_phy_read_indirect(ds, addr, regnum);
1297 mutex_unlock(&ps->phy_mutex);
1298 return ret;
1299}
1300
1301int
1302mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
1303 u16 val)
1304{
1305 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1306 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1307 int ret;
1308
1309 if (addr < 0)
1310 return addr;
1311
1312 mutex_lock(&ps->phy_mutex);
1313 ret = _mv88e6xxx_phy_write_indirect(ds, addr, regnum, val);
1234 mutex_unlock(&ps->phy_mutex); 1314 mutex_unlock(&ps->phy_mutex);
1235 return ret; 1315 return ret;
1236} 1316}
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 49614765760f..44b0ec79cc6b 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -140,8 +140,11 @@ int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val);
140int mv88e6xxx_config_prio(struct dsa_switch *ds); 140int mv88e6xxx_config_prio(struct dsa_switch *ds);
141int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr); 141int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
142int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr); 142int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
143int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum); 143int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
144int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val); 144int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
145int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum);
146int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
147 u16 val);
145void mv88e6xxx_ppu_state_init(struct dsa_switch *ds); 148void mv88e6xxx_ppu_state_init(struct dsa_switch *ds);
146int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum); 149int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum);
147int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr, 150int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,