Commit 9a23b6f0 authored by Matt Porter's avatar Matt Porter

[PATCH] ibm_emac driver updates

Optimizes transmit windows for improved performance and to prevent
TX underruns. Fixes driver registration error handling. Fixes ZMII
and RGMII thinkos. Fixes for MDIO handling issues from Ralph
Siemsen. Please apply.
Signed-off-by: default avatarMatt Porter <mporter@kernel.crashing.org>
parent 74d8e9b7
...@@ -228,6 +228,21 @@ typedef struct emac_regs { ...@@ -228,6 +228,21 @@ typedef struct emac_regs {
(desc & EMAC_BAD_RX_PACKET) (desc & EMAC_BAD_RX_PACKET)
#endif #endif
/* SoC implementation specific EMAC register defaults */
#if defined(CONFIG_440GP)
#define EMAC_RWMR_DEFAULT 0x80009000
#define EMAC_TMR0_DEFAULT 0x00000000
#define EMAC_TMR1_DEFAULT 0xf8640000
#elif defined(CONFIG_440GX)
#define EMAC_RWMR_DEFAULT 0x1000a200
#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_2_32
#define EMAC_TMR1_DEFAULT 0xa00f0000
#else
#define EMAC_RWMR_DEFAULT 0x0f002000
#define EMAC_TMR0_DEFAULT 0x00000000
#define EMAC_TMR1_DEFAULT 0x380f0000
#endif /* CONFIG_440GP */
/* Revision specific EMAC register defaults */ /* Revision specific EMAC register defaults */
#ifdef CONFIG_IBM_EMAC4 #ifdef CONFIG_IBM_EMAC4
#define EMAC_M1_DEFAULT (EMAC_M1_BASE | \ #define EMAC_M1_DEFAULT (EMAC_M1_BASE | \
...@@ -236,7 +251,7 @@ typedef struct emac_regs { ...@@ -236,7 +251,7 @@ typedef struct emac_regs {
#define EMAC_RMR_DEFAULT (EMAC_RMR_BASE | \ #define EMAC_RMR_DEFAULT (EMAC_RMR_BASE | \
EMAC_RMR_RFAF_128_2048) EMAC_RMR_RFAF_128_2048)
#define EMAC_TMR0_XMIT (EMAC_TMR0_GNP0 | \ #define EMAC_TMR0_XMIT (EMAC_TMR0_GNP0 | \
EMAC_TMR0_TFAE_128_2048) EMAC_TMR0_DEFAULT)
#define EMAC_TRTR_DEFAULT EMAC_TRTR_1024 #define EMAC_TRTR_DEFAULT EMAC_TRTR_1024
#else /* !CONFIG_IBM_EMAC4 */ #else /* !CONFIG_IBM_EMAC4 */
#define EMAC_M1_DEFAULT EMAC_M1_BASE #define EMAC_M1_DEFAULT EMAC_M1_BASE
...@@ -245,19 +260,4 @@ typedef struct emac_regs { ...@@ -245,19 +260,4 @@ typedef struct emac_regs {
#define EMAC_TRTR_DEFAULT EMAC_TRTR_1600 #define EMAC_TRTR_DEFAULT EMAC_TRTR_1600
#endif /* CONFIG_IBM_EMAC4 */ #endif /* CONFIG_IBM_EMAC4 */
/* SoC implementation specific EMAC register defaults */
#if defined(CONFIG_440GP)
#define EMAC_RWMR_DEFAULT 0x80009000
#define EMAC_TMR0_DEFAULT 0x00000000
#define EMAC_TMR1_DEFAULT 0xf8640000
#elif defined(CONFIG_440GX)
#define EMAC_RWMR_DEFAULT 0x1000a200
#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_128_2048
#define EMAC_TMR1_DEFAULT 0x88810000
#else
#define EMAC_RWMR_DEFAULT 0x0f002000
#define EMAC_TMR0_DEFAULT 0x00000000
#define EMAC_TMR1_DEFAULT 0x380f0000
#endif /* CONFIG_440GP */
#endif #endif
...@@ -90,23 +90,24 @@ MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n" ...@@ -90,23 +90,24 @@ MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n"
#define RGMII_PRIV(ocpdev) ((struct ibm_ocp_rgmii*)ocp_get_drvdata(ocpdev)) #define RGMII_PRIV(ocpdev) ((struct ibm_ocp_rgmii*)ocp_get_drvdata(ocpdev))
static unsigned int rgmii_enable[] = static unsigned int rgmii_enable[] = {
{ RGMII_RTBI, RGMII_RGMII, RGMII_TBI, RGMII_GMII }; RGMII_RTBI,
RGMII_RGMII,
RGMII_TBI,
RGMII_GMII
};
static unsigned int rgmii_speed_mask[] = { 0, static unsigned int rgmii_speed_mask[] = {
0,
RGMII_MII2_SPDMASK, RGMII_MII2_SPDMASK,
RGMII_MII3_SPDMASK RGMII_MII3_SPDMASK
}; };
static unsigned int rgmii_speed100[] = { 0, static unsigned int rgmii_speed100[] = {
0,
RGMII_MII2_100MB, RGMII_MII2_100MB,
RGMII_MII3_100MB RGMII_MII3_100MB
}; };
static unsigned int rgmii_speed1000[] = { 0, static unsigned int rgmii_speed1000[] = {
0,
RGMII_MII2_1000MB, RGMII_MII2_1000MB,
RGMII_MII3_1000MB RGMII_MII3_1000MB
}; };
...@@ -122,11 +123,21 @@ static unsigned int zmii_enable[][4] = { ...@@ -122,11 +123,21 @@ static unsigned int zmii_enable[][4] = {
~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)}, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)},
{ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)} {ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)}
}; };
static unsigned int mdi_enable[] =
{ ZMII_MDI0, ZMII_MDI1, ZMII_MDI2, ZMII_MDI3 }; static unsigned int mdi_enable[] = {
ZMII_MDI0,
ZMII_MDI1,
ZMII_MDI2,
ZMII_MDI3
};
static unsigned int zmii_speed = 0x0; static unsigned int zmii_speed = 0x0;
static unsigned int zmii_speed100[] = { ZMII_MII0_100MB, ZMII_MII1_100MB }; static unsigned int zmii_speed100[] = {
ZMII_MII0_100MB,
ZMII_MII1_100MB,
ZMII_MII2_100MB,
ZMII_MII3_100MB
};
/* Since multiple EMACs share MDIO lines in various ways, we need /* Since multiple EMACs share MDIO lines in various ways, we need
* to avoid re-using the same PHY ID in cases where the arch didn't * to avoid re-using the same PHY ID in cases where the arch didn't
...@@ -367,6 +378,7 @@ static void emac_close_zmii(struct ocp_device *ocpdev) ...@@ -367,6 +378,7 @@ static void emac_close_zmii(struct ocp_device *ocpdev)
int emac_phy_read(struct net_device *dev, int mii_id, int reg) int emac_phy_read(struct net_device *dev, int mii_id, int reg)
{ {
int count;
uint32_t stacr; uint32_t stacr;
struct ocp_enet_private *fep = dev->priv; struct ocp_enet_private *fep = dev->priv;
emac_t *emacp = fep->emacp; emac_t *emacp = fep->emacp;
...@@ -385,9 +397,13 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg) ...@@ -385,9 +397,13 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg)
emacp = fep->emacp; emacp = fep->emacp;
} }
udelay(MDIO_DELAY); count = 0;
while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
&& (count++ < MDIO_DELAY))
udelay(1);
MDIO_DEBUG((" (count was %d)\n", count));
if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) { if ((stacr & EMAC_STACR_OC) == 0) {
printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name); printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name);
return -1; return -1;
} }
...@@ -398,8 +414,11 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg) ...@@ -398,8 +414,11 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg)
out_be32(&emacp->em0stacr, stacr); out_be32(&emacp->em0stacr, stacr);
udelay(MDIO_DELAY); count = 0;
stacr = in_be32(&emacp->em0stacr); while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
&& (count++ < MDIO_DELAY))
udelay(1);
MDIO_DEBUG((" (count was %d)\n", count));
if ((stacr & EMAC_STACR_OC) == 0) { if ((stacr & EMAC_STACR_OC) == 0) {
printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name); printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name);
...@@ -419,6 +438,7 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg) ...@@ -419,6 +438,7 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg)
void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data)
{ {
int count;
uint32_t stacr; uint32_t stacr;
struct ocp_enet_private *fep = dev->priv; struct ocp_enet_private *fep = dev->priv;
emac_t *emacp = fep->emacp; emac_t *emacp = fep->emacp;
...@@ -437,9 +457,13 @@ void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) ...@@ -437,9 +457,13 @@ void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data)
emacp = fep->emacp; emacp = fep->emacp;
} }
udelay(MDIO_DELAY); count = 0;
while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
&& (count++ < MDIO_DELAY))
udelay(1);
MDIO_DEBUG((" (count was %d)\n", count));
if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) { if ((stacr & EMAC_STACR_OC) == 0) {
printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
return; return;
} }
...@@ -451,9 +475,12 @@ void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) ...@@ -451,9 +475,12 @@ void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data)
out_be32(&emacp->em0stacr, stacr); out_be32(&emacp->em0stacr, stacr);
udelay(MDIO_DELAY); while (((stacr = in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0)
&& (count++ < 5000))
udelay(1);
MDIO_DEBUG((" (count was %d)\n", count));
if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) if ((stacr & EMAC_STACR_OC) == 0)
printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
/* Check for a write error */ /* Check for a write error */
...@@ -1940,8 +1967,6 @@ static struct ocp_driver emac_driver = { ...@@ -1940,8 +1967,6 @@ static struct ocp_driver emac_driver = {
static int __init emac_init(void) static int __init emac_init(void)
{ {
int rc;
printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n"); printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n");
printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n"); printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n");
...@@ -1950,13 +1975,8 @@ static int __init emac_init(void) ...@@ -1950,13 +1975,8 @@ static int __init emac_init(void)
skb_res); skb_res);
skb_res = 2; skb_res = 2;
} }
rc = ocp_register_driver(&emac_driver);
if (rc < 0) {
ocp_unregister_driver(&emac_driver);
return -ENODEV;
}
return 0; return ocp_register_driver(&emac_driver);
} }
static void __exit emac_exit(void) static void __exit emac_exit(void)
......
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
#define TX_TIMEOUT (2*HZ) #define TX_TIMEOUT (2*HZ)
/* MDIO latency delay */ /* MDIO latency delay */
#define MDIO_DELAY 50 #define MDIO_DELAY 250
/* Power managment shift registers */ /* Power managment shift registers */
#define IBM_CPM_EMMII 0 /* Shift value for MII */ #define IBM_CPM_EMMII 0 /* Shift value for MII */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment