Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1642182e authored by Stephan Gatzka's avatar Stephan Gatzka Committed by David S. Miller
Browse files

net/phy: Add interrupt support for dp83640 phy.



Added functions for ack_interrupt and config_intr. Tested on an mpc5200b
powerpc board.

Signed-off-by: default avatarStephan Gatzka <stephan.gatzka@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 59e955ed
Loading
Loading
Loading
Loading
+77 −1
Original line number Original line Diff line number Diff line
@@ -48,6 +48,21 @@
#define CAL_TRIGGER	7
#define CAL_TRIGGER	7
#define PER_TRIGGER	6
#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 */
/* phyter seems to miss the mark by 16 ns */
#define ADJTIME_FIX	16
#define ADJTIME_FIX	16


@@ -1043,6 +1058,65 @@ static void dp83640_remove(struct phy_device *phydev)
	kfree(dp83640);
	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)
static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr)
{
{
	struct dp83640_private *dp83640 = phydev->priv;
	struct dp83640_private *dp83640 = phydev->priv;
@@ -1253,11 +1327,13 @@ static struct phy_driver dp83640_driver = {
	.phy_id_mask	= 0xfffffff0,
	.phy_id_mask	= 0xfffffff0,
	.name		= "NatSemi DP83640",
	.name		= "NatSemi DP83640",
	.features	= PHY_BASIC_FEATURES,
	.features	= PHY_BASIC_FEATURES,
	.flags		= 0,
	.flags		= PHY_HAS_INTERRUPT,
	.probe		= dp83640_probe,
	.probe		= dp83640_probe,
	.remove		= dp83640_remove,
	.remove		= dp83640_remove,
	.config_aneg	= genphy_config_aneg,
	.config_aneg	= genphy_config_aneg,
	.read_status	= genphy_read_status,
	.read_status	= genphy_read_status,
	.ack_interrupt  = dp83640_ack_interrupt,
	.config_intr    = dp83640_config_intr,
	.ts_info	= dp83640_ts_info,
	.ts_info	= dp83640_ts_info,
	.hwtstamp	= dp83640_hwtstamp,
	.hwtstamp	= dp83640_hwtstamp,
	.rxtstamp	= dp83640_rxtstamp,
	.rxtstamp	= dp83640_rxtstamp,