Skip to content

Commit

Permalink
net/phy: Add interrupt support for dp83640 phy.
Browse files Browse the repository at this point in the history
Added functions for ack_interrupt and config_intr. Tested on an mpc5200b
powerpc board.

Signed-off-by: Stephan Gatzka <stephan.gatzka@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Stephan Gatzka authored and David S. Miller committed Dec 5, 2012
1 parent 59e955e commit 1642182
Showing 1 changed file with 77 additions and 1 deletion.
78 changes: 77 additions & 1 deletion drivers/net/phy/dp83640.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@
#define CAL_TRIGGER 7
#define PER_TRIGGER 6

#define MII_DP83640_MICR 0x11
#define MII_DP83640_MISR 0x12

#define MII_DP83640_MICR_OE 0x1
#define MII_DP83640_MICR_IE 0x2

#define MII_DP83640_MISR_RHF_INT_EN 0x01
#define MII_DP83640_MISR_FHF_INT_EN 0x02
#define MII_DP83640_MISR_ANC_INT_EN 0x04
#define MII_DP83640_MISR_DUP_INT_EN 0x08
#define MII_DP83640_MISR_SPD_INT_EN 0x10
#define MII_DP83640_MISR_LINK_INT_EN 0x20
#define MII_DP83640_MISR_ED_INT_EN 0x40
#define MII_DP83640_MISR_LQ_INT_EN 0x80

/* phyter seems to miss the mark by 16 ns */
#define ADJTIME_FIX 16

Expand Down Expand Up @@ -1043,6 +1058,65 @@ static void dp83640_remove(struct phy_device *phydev)
kfree(dp83640);
}

static int dp83640_ack_interrupt(struct phy_device *phydev)
{
int err = phy_read(phydev, MII_DP83640_MISR);

if (err < 0)
return err;

return 0;
}

static int dp83640_config_intr(struct phy_device *phydev)
{
int micr;
int misr;
int err;

if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
misr = phy_read(phydev, MII_DP83640_MISR);
if (misr < 0)
return misr;
misr |=
(MII_DP83640_MISR_ANC_INT_EN |
MII_DP83640_MISR_DUP_INT_EN |
MII_DP83640_MISR_SPD_INT_EN |
MII_DP83640_MISR_LINK_INT_EN);
err = phy_write(phydev, MII_DP83640_MISR, misr);
if (err < 0)
return err;

micr = phy_read(phydev, MII_DP83640_MICR);
if (micr < 0)
return micr;
micr |=
(MII_DP83640_MICR_OE |
MII_DP83640_MICR_IE);
return phy_write(phydev, MII_DP83640_MICR, micr);
} else {
micr = phy_read(phydev, MII_DP83640_MICR);
if (micr < 0)
return micr;
micr &=
~(MII_DP83640_MICR_OE |
MII_DP83640_MICR_IE);
err = phy_write(phydev, MII_DP83640_MICR, micr);
if (err < 0)
return err;

misr = phy_read(phydev, MII_DP83640_MISR);
if (misr < 0)
return misr;
misr &=
~(MII_DP83640_MISR_ANC_INT_EN |
MII_DP83640_MISR_DUP_INT_EN |
MII_DP83640_MISR_SPD_INT_EN |
MII_DP83640_MISR_LINK_INT_EN);
return phy_write(phydev, MII_DP83640_MISR, misr);
}
}

static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr)
{
struct dp83640_private *dp83640 = phydev->priv;
Expand Down Expand Up @@ -1253,11 +1327,13 @@ static struct phy_driver dp83640_driver = {
.phy_id_mask = 0xfffffff0,
.name = "NatSemi DP83640",
.features = PHY_BASIC_FEATURES,
.flags = 0,
.flags = PHY_HAS_INTERRUPT,
.probe = dp83640_probe,
.remove = dp83640_remove,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.ack_interrupt = dp83640_ack_interrupt,
.config_intr = dp83640_config_intr,
.ts_info = dp83640_ts_info,
.hwtstamp = dp83640_hwtstamp,
.rxtstamp = dp83640_rxtstamp,
Expand Down

0 comments on commit 1642182

Please sign in to comment.