Commit 212ea99a85d30dbc834888384c57ad5abbc67a0a

Authored by Marek Vasut
Committed by David S. Miller
1 parent 2b018d57ff

phy/micrel: Implement support for KSZ8021

The KSZ8021 PHY was previously caught by KS8051, which is not correct.
This PHY needs additional setup if it is strapped for address 0. In such
case an reserved bit must be written in the 0x16, "Operation Mode Strap
Override" register. According to the KS8051 datasheet, that bit means
"PHY Address 0 in non-broadcast" and it indeed behaves as such on KSZ8021.
The issue where the ethernet controller (Freescale FEC) did not communicate
with network is fixed by writing this bit as 1.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: David J. Choi <david.choi@micrel.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 28 additions and 0 deletions Side-by-side Diff

drivers/net/phy/micrel.c
... ... @@ -21,6 +21,12 @@
21 21 #include <linux/phy.h>
22 22 #include <linux/micrel_phy.h>
23 23  
  24 +/* Operation Mode Strap Override */
  25 +#define MII_KSZPHY_OMSO 0x16
  26 +#define KSZPHY_OMSO_B_CAST_OFF (1 << 9)
  27 +#define KSZPHY_OMSO_RMII_OVERRIDE (1 << 1)
  28 +#define KSZPHY_OMSO_MII_OVERRIDE (1 << 0)
  29 +
24 30 /* general Interrupt control/status reg in vendor specific block. */
25 31 #define MII_KSZPHY_INTCS 0x1B
26 32 #define KSZPHY_INTCS_JABBER (1 << 15)
... ... @@ -101,6 +107,13 @@
101 107 return 0;
102 108 }
103 109  
  110 +static int ksz8021_config_init(struct phy_device *phydev)
  111 +{
  112 + const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE;
  113 + phy_write(phydev, MII_KSZPHY_OMSO, val);
  114 + return 0;
  115 +}
  116 +
104 117 static int ks8051_config_init(struct phy_device *phydev)
105 118 {
106 119 int regval;
... ... @@ -128,6 +141,19 @@
128 141 .config_intr = ks8737_config_intr,
129 142 .driver = { .owner = THIS_MODULE,},
130 143 }, {
  144 + .phy_id = PHY_ID_KSZ8021,
  145 + .phy_id_mask = 0x00ffffff,
  146 + .name = "Micrel KSZ8021",
  147 + .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
  148 + SUPPORTED_Asym_Pause),
  149 + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  150 + .config_init = ksz8021_config_init,
  151 + .config_aneg = genphy_config_aneg,
  152 + .read_status = genphy_read_status,
  153 + .ack_interrupt = kszphy_ack_interrupt,
  154 + .config_intr = kszphy_config_intr,
  155 + .driver = { .owner = THIS_MODULE,},
  156 +}, {
131 157 .phy_id = PHY_ID_KS8041,
132 158 .phy_id_mask = 0x00fffff0,
133 159 .name = "Micrel KS8041",
... ... @@ -203,6 +229,7 @@
203 229 { PHY_ID_KSZ9021, 0x000ffffe },
204 230 { PHY_ID_KS8001, 0x00ffffff },
205 231 { PHY_ID_KS8737, 0x00fffff0 },
  232 + { PHY_ID_KSZ8021, 0x00ffffff },
206 233 { PHY_ID_KS8041, 0x00fffff0 },
207 234 { PHY_ID_KS8051, 0x00fffff0 },
208 235 { }
include/linux/micrel_phy.h
... ... @@ -5,6 +5,7 @@
5 5  
6 6 #define PHY_ID_KSZ9021 0x00221610
7 7 #define PHY_ID_KS8737 0x00221720
  8 +#define PHY_ID_KSZ8021 0x00221555
8 9 #define PHY_ID_KS8041 0x00221510
9 10 #define PHY_ID_KS8051 0x00221550
10 11 /* both for ks8001 Rev. A/B, and for ks8721 Rev 3. */