aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/fixed.c5
-rw-r--r--drivers/net/phy/marvell.c54
-rw-r--r--drivers/net/phy/phy.c14
3 files changed, 68 insertions, 5 deletions
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index cf24cc34debe..e7070515d2e3 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -19,6 +19,7 @@
19#include <linux/mii.h> 19#include <linux/mii.h>
20#include <linux/phy.h> 20#include <linux/phy.h>
21#include <linux/phy_fixed.h> 21#include <linux/phy_fixed.h>
22#include <linux/err.h>
22 23
23#define MII_REGS_NUM 29 24#define MII_REGS_NUM 29
24 25
@@ -207,8 +208,8 @@ static int __init fixed_mdio_bus_init(void)
207 int ret; 208 int ret;
208 209
209 pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0); 210 pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
210 if (!pdev) { 211 if (IS_ERR(pdev)) {
211 ret = -ENOMEM; 212 ret = PTR_ERR(pdev);
212 goto err_pdev; 213 goto err_pdev;
213 } 214 }
214 215
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index eb6411c4694f..7a3ec9d39a9a 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -69,6 +69,11 @@
69#define MII_M1111_COPPER 0 69#define MII_M1111_COPPER 0
70#define MII_M1111_FIBER 1 70#define MII_M1111_FIBER 1
71 71
72#define MII_88E1121_PHY_LED_CTRL 16
73#define MII_88E1121_PHY_LED_PAGE 3
74#define MII_88E1121_PHY_LED_DEF 0x0030
75#define MII_88E1121_PHY_PAGE 22
76
72#define MII_M1011_PHY_STATUS 0x11 77#define MII_M1011_PHY_STATUS 0x11
73#define MII_M1011_PHY_STATUS_1000 0x8000 78#define MII_M1011_PHY_STATUS_1000 0x8000
74#define MII_M1011_PHY_STATUS_100 0x4000 79#define MII_M1011_PHY_STATUS_100 0x4000
@@ -154,6 +159,30 @@ static int marvell_config_aneg(struct phy_device *phydev)
154 return err; 159 return err;
155} 160}
156 161
162static int m88e1121_config_aneg(struct phy_device *phydev)
163{
164 int err, temp;
165
166 err = phy_write(phydev, MII_BMCR, BMCR_RESET);
167 if (err < 0)
168 return err;
169
170 err = phy_write(phydev, MII_M1011_PHY_SCR,
171 MII_M1011_PHY_SCR_AUTO_CROSS);
172 if (err < 0)
173 return err;
174
175 temp = phy_read(phydev, MII_88E1121_PHY_PAGE);
176
177 phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
178 phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF);
179 phy_write(phydev, MII_88E1121_PHY_PAGE, temp);
180
181 err = genphy_config_aneg(phydev);
182
183 return err;
184}
185
157static int m88e1111_config_init(struct phy_device *phydev) 186static int m88e1111_config_init(struct phy_device *phydev)
158{ 187{
159 int err; 188 int err;
@@ -429,6 +458,18 @@ static int marvell_read_status(struct phy_device *phydev)
429 return 0; 458 return 0;
430} 459}
431 460
461static int m88e1121_did_interrupt(struct phy_device *phydev)
462{
463 int imask;
464
465 imask = phy_read(phydev, MII_M1011_IEVENT);
466
467 if (imask & MII_M1011_IMASK_INIT)
468 return 1;
469
470 return 0;
471}
472
432static struct phy_driver marvell_drivers[] = { 473static struct phy_driver marvell_drivers[] = {
433 { 474 {
434 .phy_id = 0x01410c60, 475 .phy_id = 0x01410c60,
@@ -482,6 +523,19 @@ static struct phy_driver marvell_drivers[] = {
482 .driver = {.owner = THIS_MODULE,}, 523 .driver = {.owner = THIS_MODULE,},
483 }, 524 },
484 { 525 {
526 .phy_id = 0x01410cb0,
527 .phy_id_mask = 0xfffffff0,
528 .name = "Marvell 88E1121R",
529 .features = PHY_GBIT_FEATURES,
530 .flags = PHY_HAS_INTERRUPT,
531 .config_aneg = &m88e1121_config_aneg,
532 .read_status = &marvell_read_status,
533 .ack_interrupt = &marvell_ack_interrupt,
534 .config_intr = &marvell_config_intr,
535 .did_interrupt = &m88e1121_did_interrupt,
536 .driver = { .owner = THIS_MODULE },
537 },
538 {
485 .phy_id = 0x01410cd0, 539 .phy_id = 0x01410cd0,
486 .phy_id_mask = 0xfffffff0, 540 .phy_id_mask = 0xfffffff0,
487 .name = "Marvell 88E1145", 541 .name = "Marvell 88E1145",
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 3ff1f425f1bb..61755cbd978e 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -434,7 +434,7 @@ void phy_start_machine(struct phy_device *phydev,
434 phydev->adjust_state = handler; 434 phydev->adjust_state = handler;
435 435
436 INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine); 436 INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine);
437 schedule_delayed_work(&phydev->state_queue, jiffies + HZ); 437 schedule_delayed_work(&phydev->state_queue, HZ);
438} 438}
439 439
440/** 440/**
@@ -655,6 +655,10 @@ static void phy_change(struct work_struct *work)
655 struct phy_device *phydev = 655 struct phy_device *phydev =
656 container_of(work, struct phy_device, phy_queue); 656 container_of(work, struct phy_device, phy_queue);
657 657
658 if (phydev->drv->did_interrupt &&
659 !phydev->drv->did_interrupt(phydev))
660 goto ignore;
661
658 err = phy_disable_interrupts(phydev); 662 err = phy_disable_interrupts(phydev);
659 663
660 if (err) 664 if (err)
@@ -681,6 +685,11 @@ static void phy_change(struct work_struct *work)
681 685
682 return; 686 return;
683 687
688ignore:
689 atomic_dec(&phydev->irq_disable);
690 enable_irq(phydev->irq);
691 return;
692
684irq_enable_err: 693irq_enable_err:
685 disable_irq(phydev->irq); 694 disable_irq(phydev->irq);
686 atomic_inc(&phydev->irq_disable); 695 atomic_inc(&phydev->irq_disable);
@@ -937,6 +946,5 @@ static void phy_state_machine(struct work_struct *work)
937 if (err < 0) 946 if (err < 0)
938 phy_error(phydev); 947 phy_error(phydev);
939 948
940 schedule_delayed_work(&phydev->state_queue, 949 schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ);
941 jiffies + PHY_STATE_TIME * HZ);
942} 950}