Subject: Axon EMAC support From: Shaun Wetzstein Enable support for EMAC4+McMAL+RGMII (ibm_emac) in Axon. Signed-off-by: Shaun Wetzstein Signed-off-by: Murali Iyer Signed-off-by: Arnd Bergmann Index: linux-2.6.16/drivers/net/Kconfig =================================================================== --- linux-2.6.16.orig/drivers/net/Kconfig +++ linux-2.6.16/drivers/net/Kconfig @@ -1184,11 +1184,16 @@ config SYSTEMSIM_NET config IBM_EMAC tristate "PowerPC 4xx on-chip Ethernet support" - depends on 4xx help This driver supports the PowerPC 4xx EMAC family of on-chip Ethernet controllers. +config IBM_EMAC_AXON + bool "Axon EMAC4 support" + select IBM_EMAC4 + depends on IBM_EMAC + default y + config IBM_EMAC_RXB int "Number of receive buffers" depends on IBM_EMAC @@ -1239,17 +1244,22 @@ config IBM_EMAC_DEBUG config IBM_EMAC_ZMII bool - depends on IBM_EMAC && (NP405H || NP405L || 44x) + depends on IBM_EMAC default y config IBM_EMAC_RGMII bool - depends on IBM_EMAC && 440GX + depends on IBM_EMAC + default y + +config IBM_EMAC_RGMII_AXON + bool "Axon RGMII support" + depends on IBM_EMAC_RGMII default y config IBM_EMAC_TAH bool - depends on IBM_EMAC && 440GX + depends on IBM_EMAC default y config NET_PCI Index: linux-2.6.16/drivers/net/ibm_emac/ibm_emac.h =================================================================== --- linux-2.6.16.orig/drivers/net/ibm_emac/ibm_emac.h +++ linux-2.6.16/drivers/net/ibm_emac/ibm_emac.h @@ -27,7 +27,7 @@ #if !defined(CONFIG_405GP) && !defined(CONFIG_405GPR) && !defined(CONFIG_405EP) && \ !defined(CONFIG_440GP) && !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && \ !defined(CONFIG_440EP) && !defined(CONFIG_NP405H) && !defined(CONFIG_440SPE) && \ - !defined(CONFIG_440GR) + !defined(CONFIG_440GR) && !defined(CONFIG_IBM_EMAC_AXON) #error "Unknown SoC. Please, check chip user manual and make sure EMAC defines are OK" #endif @@ -228,9 +228,14 @@ struct emac_regs { #define EMAC_STACR_PHYD_SHIFT 16 #define EMAC_STACR_OC 0x00008000 #define EMAC_STACR_PHYE 0x00004000 -#define EMAC_STACR_STAC_MASK 0x00003000 #define EMAC_STACR_STAC_READ 0x00001000 +#if defined(CONFIG_IBM_EMAC_AXON) +#define EMAC_STACR_STAC_MASK 0x00001800 +#define EMAC_STACR_STAC_WRITE 0x00000800 +#else +#define EMAC_STACR_STAC_MASK 0x00003000 #define EMAC_STACR_STAC_WRITE 0x00002000 +#endif #if !defined(CONFIG_IBM_EMAC4) #define EMAC_STACR_OPBC_MASK 0x00000C00 #define EMAC_STACR_OPBC_50 0x00000000 @@ -252,7 +257,7 @@ struct emac_regs { * For the 440SPe, AMCC inexplicably changed the polarity of * the "operation complete" bit in the MII control register. */ -#if defined(CONFIG_440SPE) +#if defined(CONFIG_440SPE) || defined(CONFIG_IBM_EMAC_AXON) static inline int emac_phy_done(u32 stacr) { return !(stacr & EMAC_STACR_OC); Index: linux-2.6.16/drivers/net/ibm_emac/ibm_emac_mal.h =================================================================== --- linux-2.6.16.orig/drivers/net/ibm_emac/ibm_emac_mal.h +++ linux-2.6.16/drivers/net/ibm_emac/ibm_emac_mal.h @@ -25,6 +25,7 @@ #include #include +#include /* * These MAL "versions" probably aren't the real versions IBM uses for these @@ -35,7 +36,7 @@ defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_NP405H) #define MAL_VERSION 1 #elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP) || \ - defined(CONFIG_440SPE) + defined(CONFIG_440SPE) || defined(CONFIG_IBM_EMAC_AXON) #define MAL_VERSION 2 #else #error "Unknown SoC, please check chip manual and choose MAL 'version'" Index: linux-2.6.16/drivers/net/ibm_emac/ibm_emac_core.c =================================================================== --- linux-2.6.16.orig/drivers/net/ibm_emac/ibm_emac_core.c +++ linux-2.6.16/drivers/net/ibm_emac/ibm_emac_core.c @@ -553,6 +553,16 @@ static void emac_full_tx_reset(struct ne netif_wake_queue(ndev); } +static void mii_enable_mdio(struct ocp_enet_private *dev) +{ + if (dev) { + if (dev->zmii_dev) + zmii_enable_mdio(dev->zmii_dev, dev->zmii_input); + else + rgmii_enable_mdio(dev->rgmii_dev, dev->rgmii_input); + } +} + static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg) { struct emac_regs *p = dev->emacp; @@ -562,7 +572,7 @@ static int __emac_mdio_read(struct ocp_e DBG2("%d: mdio_read(%02x,%02x)" NL, dev->def->index, id, reg); /* Enable proper MDIO port */ - zmii_enable_mdio(dev->zmii_dev, dev->zmii_input); + mii_enable_mdio(dev); /* Wait for management interface to become idle */ n = 10; @@ -611,7 +621,7 @@ static void __emac_mdio_write(struct ocp val); /* Enable proper MDIO port */ - zmii_enable_mdio(dev->zmii_dev, dev->zmii_input); + mii_enable_mdio(dev); /* Wait for management interface to be idle */ n = 10; @@ -1340,8 +1350,14 @@ static inline int emac_rx_sg_append(stru dev_kfree_skb(dev->rx_sg_skb); dev->rx_sg_skb = NULL; } else { +#if defined(CONFIG_4xx) || defined(CONFIG_44x) cacheable_memcpy(dev->rx_sg_skb->tail, dev->rx_skb[slot]->data, len); +#else + memcpy(dev->rx_sg_skb->tail, + dev->rx_skb[slot]->data, len); +#endif + skb_put(dev->rx_sg_skb, len); emac_recycle_rx_skb(dev, slot, len); return 0; @@ -1391,8 +1407,13 @@ static int emac_poll_rx(void *param, int goto oom; skb_reserve(copy_skb, EMAC_RX_SKB_HEADROOM + 2); +#if defined(CONFIG_4xx) || defined(CONFIG_44x) cacheable_memcpy(copy_skb->data - 2, skb->data - 2, len + 2); +#else + memcpy(copy_skb->data - 2, skb->data - 2, + len + 2); +#endif emac_recycle_rx_skb(dev, slot, len); skb = copy_skb; } else if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC))) Index: linux-2.6.16/drivers/net/ibm_emac/ibm_emac_rgmii.c =================================================================== --- linux-2.6.16.orig/drivers/net/ibm_emac/ibm_emac_rgmii.c +++ linux-2.6.16/drivers/net/ibm_emac/ibm_emac_rgmii.c @@ -25,6 +25,11 @@ #include "ibm_emac_debug.h" /* RGMIIx_FER */ +#if defined(CONFIG_IBM_EMAC_RGMII_AXON) +#define RGMII_FER_MDI(idx) (0x80000000 >> ((idx) + 12)) +#define RGMII_FER_MDI_ALL (RGMII_FER_MDI(0) | RGMII_FER_MDI(1) | \ + RGMII_FER_MDI(2) | RGMII_FER_MDI(3)) +#endif #define RGMII_FER_MASK(idx) (0x7 << ((idx) * 4)) #define RGMII_FER_RTBI(idx) (0x4 << ((idx) * 4)) #define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4)) @@ -148,6 +153,16 @@ int __init rgmii_attach(void *emac) return 0; } +void rgmii_enable_mdio(struct ocp_device *ocpdev, int input) +{ + struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev); + u32 fer = in_be32(&dev->base->fer) & ~RGMII_FER_MDI_ALL; + + RGMII_DBG2("%d: mdio(%d)" NL, ocpdev->def->index, input); + + out_be32(&dev->base->fer, fer | RGMII_FER_MDI(input)); +} + void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed) { struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev); Index: linux-2.6.16/drivers/net/ibm_emac/ibm_emac_rgmii.h =================================================================== --- linux-2.6.16.orig/drivers/net/ibm_emac/ibm_emac_rgmii.h +++ linux-2.6.16/drivers/net/ibm_emac/ibm_emac_rgmii.h @@ -46,6 +46,7 @@ static inline void rgmii_fini(struct ocp } void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed); +void rgmii_enable_mdio(struct ocp_device *ocpdev, int input); int __rgmii_get_regs_len(struct ocp_device *ocpdev); static inline int rgmii_get_regs_len(struct ocp_device *ocpdev)