@@ -94,6 +94,27 @@ config PHY_AQUANTIA_FW_NAME
config PHY_ATHEROS
bool "Atheros Ethernet PHYs support"
+config PHY_ATHEROS_SMART_EEE
+ depends on PHY_ATHEROS
+ default y
+ tristate "SmartEEE feature for Atheros PHYs"
+ help
+ Enables the Atheros SmartEEE feature (not IEEE 802.3az). When 2 PHYs
+ which support this feature are connected back-to-back, they may
+ negotiate a low-power sleep mode autonomously, without the Ethernet
+ controller's knowledge. This setting may cause issues under 2 known
+ circumstances (both noticed at low traffic rates):
+ - If the voltage rails on the PHY are unstable, then the PHY can
+ actually reset as it enters the low power state. This means that
+ the frames it is supposed to buffer until it wakes up are going
+ to be dropped instead.
+ - If 1588/PTP synchronization is the only traffic source over this
+ PHY, the delays caused by the sleep/wakeup time are going to add
+ to the synchronization error between the master and the slave.
+ Default y, which means that the PHY's out-of-reset state is not
+ changed (SmartEEE active). To work around the issues described
+ above, change to n.
+
config PHY_BROADCOM
bool "Broadcom Ethernet PHYs support"
@@ -5,6 +5,7 @@
* Copyright 2011, 2013 Freescale Semiconductor, Inc.
* author Andy Fleming
*/
+#include <linux/bitops.h>
#include <common.h>
#include <phy.h>
@@ -17,6 +18,21 @@
#define AR803x_DEBUG_REG_0 0x0
#define AR803x_RGMII_RX_CLK_DLY 0x8000
+#define AR803x_SMART_EEE_CTRL3_REG 0x805D
+#define AR803x_LPI_EN BIT(8)
+
+static void ar803x_enable_smart_eee(struct phy_device *phydev, bool on)
+{
+ int regval;
+
+ regval = phy_read_mmd(phydev, MDIO_MMD_PCS, AR803x_SMART_EEE_CTRL3_REG);
+ if (on)
+ regval |= AR803x_LPI_EN;
+ else
+ regval &= ~AR803x_LPI_EN;
+ phy_write_mmd(phydev, MDIO_MMD_PCS, AR803x_SMART_EEE_CTRL3_REG, regval);
+}
+
static int ar8021_config(struct phy_device *phydev)
{
phy_write(phydev, MDIO_DEVAD_NONE, 0x00, 0x1200);
@@ -29,6 +45,11 @@ static int ar8021_config(struct phy_device *phydev)
static int ar8031_config(struct phy_device *phydev)
{
+#ifdef CONFIG_PHY_ATHEROS_SMART_EEE
+ ar803x_enable_smart_eee(phydev, true);
+#else
+ ar803x_enable_smart_eee(phydev, false);
+#endif
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
@@ -57,6 +78,11 @@ static int ar8035_config(struct phy_device *phydev)
{
int regval;
+#ifdef CONFIG_PHY_ATHEROS_SMART_EEE
+ ar803x_enable_smart_eee(phydev, true);
+#else
+ ar803x_enable_smart_eee(phydev, false);
+#endif
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);