aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorSylvain Rochet <sylvain.rochet@finsecur.com>2015-02-13 15:35:33 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-14 23:30:55 -0500
commit2b0ba96cea6066d2543066fa524120b384f3bd6b (patch)
treeb6f8ac9fb6c223c763e82887f19d02110aae6872 /drivers/net/phy
parent3b4711757d7903ab6fa88a9e7ab8901b8227da60 (diff)
net: phy: micrel: disable NAND-tree for KSZ8021, KSZ8031, KSZ8051, KSZ8081
NAND-tree is used to check wiring between MAC and PHY using NAND gates on the PHY side, hence the name. NAND-tree initial status is latched at reset by probing the IRQ pin. However some devices are sharing the PHY IRQ pin with other peripherals such as Atmel SAMA5D[34]x-EK boards when using the optional TM7000 display module, therefore they are switching the PHY in NAND-tree test mode depending on the current IRQ line status at reset. This patch ensure PHY is not in NAND-tree test mode for all Micrel PHYs using IRQ line as a NAND-tree toggle mode at reset. Signed-off-by: Sylvain Rochet <sylvain.rochet@finsecur.com> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/micrel.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 3ad8ca76196d..1190fd8f0088 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -32,6 +32,7 @@
32/* Operation Mode Strap Override */ 32/* Operation Mode Strap Override */
33#define MII_KSZPHY_OMSO 0x16 33#define MII_KSZPHY_OMSO 0x16
34#define KSZPHY_OMSO_B_CAST_OFF BIT(9) 34#define KSZPHY_OMSO_B_CAST_OFF BIT(9)
35#define KSZPHY_OMSO_NAND_TREE_ON BIT(5)
35#define KSZPHY_OMSO_RMII_OVERRIDE BIT(1) 36#define KSZPHY_OMSO_RMII_OVERRIDE BIT(1)
36#define KSZPHY_OMSO_MII_OVERRIDE BIT(0) 37#define KSZPHY_OMSO_MII_OVERRIDE BIT(0)
37 38
@@ -76,6 +77,7 @@ struct kszphy_type {
76 u32 led_mode_reg; 77 u32 led_mode_reg;
77 u16 interrupt_level_mask; 78 u16 interrupt_level_mask;
78 bool has_broadcast_disable; 79 bool has_broadcast_disable;
80 bool has_nand_tree_disable;
79 bool has_rmii_ref_clk_sel; 81 bool has_rmii_ref_clk_sel;
80}; 82};
81 83
@@ -89,6 +91,7 @@ struct kszphy_priv {
89static const struct kszphy_type ksz8021_type = { 91static const struct kszphy_type ksz8021_type = {
90 .led_mode_reg = MII_KSZPHY_CTRL_2, 92 .led_mode_reg = MII_KSZPHY_CTRL_2,
91 .has_broadcast_disable = true, 93 .has_broadcast_disable = true,
94 .has_nand_tree_disable = true,
92 .has_rmii_ref_clk_sel = true, 95 .has_rmii_ref_clk_sel = true,
93}; 96};
94 97
@@ -98,11 +101,13 @@ static const struct kszphy_type ksz8041_type = {
98 101
99static const struct kszphy_type ksz8051_type = { 102static const struct kszphy_type ksz8051_type = {
100 .led_mode_reg = MII_KSZPHY_CTRL_2, 103 .led_mode_reg = MII_KSZPHY_CTRL_2,
104 .has_nand_tree_disable = true,
101}; 105};
102 106
103static const struct kszphy_type ksz8081_type = { 107static const struct kszphy_type ksz8081_type = {
104 .led_mode_reg = MII_KSZPHY_CTRL_2, 108 .led_mode_reg = MII_KSZPHY_CTRL_2,
105 .has_broadcast_disable = true, 109 .has_broadcast_disable = true,
110 .has_nand_tree_disable = true,
106 .has_rmii_ref_clk_sel = true, 111 .has_rmii_ref_clk_sel = true,
107}; 112};
108 113
@@ -231,6 +236,26 @@ out:
231 return ret; 236 return ret;
232} 237}
233 238
239static int kszphy_nand_tree_disable(struct phy_device *phydev)
240{
241 int ret;
242
243 ret = phy_read(phydev, MII_KSZPHY_OMSO);
244 if (ret < 0)
245 goto out;
246
247 if (!(ret & KSZPHY_OMSO_NAND_TREE_ON))
248 return 0;
249
250 ret = phy_write(phydev, MII_KSZPHY_OMSO,
251 ret & ~KSZPHY_OMSO_NAND_TREE_ON);
252out:
253 if (ret)
254 dev_err(&phydev->dev, "failed to disable NAND tree mode\n");
255
256 return ret;
257}
258
234static int kszphy_config_init(struct phy_device *phydev) 259static int kszphy_config_init(struct phy_device *phydev)
235{ 260{
236 struct kszphy_priv *priv = phydev->priv; 261 struct kszphy_priv *priv = phydev->priv;
@@ -245,6 +270,9 @@ static int kszphy_config_init(struct phy_device *phydev)
245 if (type->has_broadcast_disable) 270 if (type->has_broadcast_disable)
246 kszphy_broadcast_disable(phydev); 271 kszphy_broadcast_disable(phydev);
247 272
273 if (type->has_nand_tree_disable)
274 kszphy_nand_tree_disable(phydev);
275
248 if (priv->rmii_ref_clk_sel) { 276 if (priv->rmii_ref_clk_sel) {
249 ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val); 277 ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
250 if (ret) { 278 if (ret) {