lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1455741127-25453-3-git-send-email-andrew@lunn.ch>
Date:	Wed, 17 Feb 2016 21:32:07 +0100
From:	Andrew Lunn <andrew@...n.ch>
To:	David Miller <davem@...emloft.net>,
	Florian Fainelli <f.fainelli@...il.com>
Cc:	netdev <netdev@...r.kernel.org>, Andrew Lunn <andrew@...n.ch>
Subject: [PATCH net-next 2/2] phy: marvell: Add support for phy packet generator

Most of the Marvell PHYs include a packet generator, for sending up to
255 packets, of size 64 or 1518 bytes. Packets can either contain
repeated 0x5a 0xa5, or random bytes. Packets can contain CRC errors or
symbol errors. Some PHYs allow the inter packet gap to be changed.

Signed-off-by: Andrew Lunn <andrew@...n.ch>
---
 drivers/net/phy/marvell.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index e3eb96443c97..1c42aef6dcf3 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -133,6 +133,15 @@
 #define MII_88E3016_DISABLE_SCRAMBLER	0x0200
 #define MII_88E3016_AUTO_MDIX_CROSSOVER	0x0030
 
+#define MII_88E1540_PKT_GEN		16
+#define MII_88E1540_PKT_GEN_BURST_SHIFT	8
+#define MII_88E1540_PKT_GEN_ENABLE	BIT(3)
+#define MII_88E1540_PKT_GEN_FIXED	BIT(2)
+#define MII_88E1540_PKT_GEN_LEN_1518	BIT(1)
+#define MII_88E1540_PKT_GEN_ERROR	BIT(0)
+
+#define MII_88E1540_PKT_GEN_IPG		19
+
 MODULE_DESCRIPTION("Marvell PHY driver");
 MODULE_AUTHOR("Andy Fleming");
 MODULE_LICENSE("GPL");
@@ -1057,6 +1066,83 @@ static void marvell_get_stats(struct phy_device *phydev,
 		data[i] = marvell_get_stat(phydev, i);
 }
 
+static int marvell_pkt_gen(struct phy_device *phydev,
+			   struct ethtool_phy_pkt_gen *pkt_gen)
+{
+	int err, oldpage, reg, max_loop = 100;
+	u32 phy_id = phydev->drv->phy_id;
+	bool has_ipg = false;
+
+	switch (phy_id) {
+	case MARVELL_PHY_ID_88E1510:
+	case MARVELL_PHY_ID_88E1540:
+		has_ipg = true;
+	}
+
+	if (pkt_gen->count < 1 || pkt_gen->count > 255)
+		return -EINVAL;
+
+	if (pkt_gen->len == 0)
+		pkt_gen->len = 64;
+
+	if (pkt_gen->len != 64 && pkt_gen->len != 1518)
+		return -EINVAL;
+
+	if (has_ipg) {
+		if (pkt_gen->ipg == 0)
+			pkt_gen->ipg = 12;
+
+		if (pkt_gen->ipg > 256)
+			return -EINVAL;
+	} else {
+		if (pkt_gen->ipg != 0)
+			return -EINVAL;
+	}
+
+	oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
+	if (oldpage < 0) {
+		err = oldpage;
+		goto out;
+	}
+
+	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 6);
+	if (err)
+		goto out;
+
+	if (has_ipg) {
+		err = phy_write(phydev, MII_88E1540_PKT_GEN_IPG,
+				pkt_gen->ipg - 1);
+		if (err)
+			goto out;
+	}
+
+	reg = MII_88E1540_PKT_GEN_ENABLE;
+	reg |= pkt_gen->count << MII_88E1540_PKT_GEN_BURST_SHIFT;
+	if (pkt_gen->len == 1518)
+		reg |= MII_88E1540_PKT_GEN_LEN_1518;
+	if (!(pkt_gen->flags & ETH_PKT_RANDOM))
+		reg |= MII_88E1540_PKT_GEN_FIXED;
+	if (pkt_gen->flags & ETH_PKT_ERROR)
+		reg |= MII_88E1540_PKT_GEN_ERROR;
+
+	err = phy_write(phydev, MII_88E1540_PKT_GEN, reg);
+	if (err)
+		goto out;
+
+	do {
+		usleep_range(3000, 4000);
+		reg = phy_read(phydev, MII_88E1540_PKT_GEN);
+	} while (max_loop-- && (reg & MII_88E1540_PKT_GEN_ENABLE));
+
+	if (!max_loop)
+		err = -ETIMEDOUT;
+
+out:
+	phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
+
+	return err;
+}
+
 static int marvell_probe(struct phy_device *phydev)
 {
 	struct marvell_priv *priv;
@@ -1102,6 +1188,7 @@ static struct phy_driver marvell_drivers[] = {
 		.config_intr = &marvell_config_intr,
 		.resume = &genphy_resume,
 		.suspend = &genphy_suspend,
+		.pkt_gen = marvell_pkt_gen,
 		.get_sset_count = marvell_get_sset_count,
 		.get_strings = marvell_get_strings,
 		.get_stats = marvell_get_stats,
@@ -1156,6 +1243,7 @@ static struct phy_driver marvell_drivers[] = {
 		.did_interrupt = &m88e1121_did_interrupt,
 		.resume = &genphy_resume,
 		.suspend = &genphy_suspend,
+		.pkt_gen = marvell_pkt_gen,
 		.get_sset_count = marvell_get_sset_count,
 		.get_strings = marvell_get_strings,
 		.get_stats = marvell_get_stats,
@@ -1212,6 +1300,7 @@ static struct phy_driver marvell_drivers[] = {
 		.config_intr = &marvell_config_intr,
 		.resume = &genphy_resume,
 		.suspend = &genphy_suspend,
+		.pkt_gen = marvell_pkt_gen,
 		.get_sset_count = marvell_get_sset_count,
 		.get_strings = marvell_get_strings,
 		.get_stats = marvell_get_stats,
@@ -1248,6 +1337,7 @@ static struct phy_driver marvell_drivers[] = {
 		.config_intr = &marvell_config_intr,
 		.resume = &genphy_resume,
 		.suspend = &genphy_suspend,
+		.pkt_gen = marvell_pkt_gen,
 		.get_sset_count = marvell_get_sset_count,
 		.get_strings = marvell_get_strings,
 		.get_stats = marvell_get_stats,
@@ -1284,6 +1374,7 @@ static struct phy_driver marvell_drivers[] = {
 		.did_interrupt = &m88e1121_did_interrupt,
 		.resume = &genphy_resume,
 		.suspend = &genphy_suspend,
+		.pkt_gen = marvell_pkt_gen,
 		.get_sset_count = marvell_get_sset_count,
 		.get_strings = marvell_get_strings,
 		.get_stats = marvell_get_stats,
@@ -1304,6 +1395,7 @@ static struct phy_driver marvell_drivers[] = {
 		.did_interrupt = &m88e1121_did_interrupt,
 		.resume = &genphy_resume,
 		.suspend = &genphy_suspend,
+		.pkt_gen = marvell_pkt_gen,
 		.get_sset_count = marvell_get_sset_count,
 		.get_strings = marvell_get_strings,
 		.get_stats = marvell_get_stats,
-- 
2.7.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ