diff options
Diffstat (limited to 'drivers/net/fec.c')
-rw-r--r-- | drivers/net/fec.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 938426953149..b7cb59a51c55 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -51,6 +51,7 @@ #include <asm/uaccess.h> #include <asm/io.h> #include <asm/pgtable.h> +#include <asm/cacheflush.h> #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ @@ -113,8 +114,6 @@ static unsigned char fec_mac_default[] = { #define FEC_FLASHMAC 0xf0006006 #elif defined(CONFIG_GILBARCONAP) || defined(CONFIG_SCALES) #define FEC_FLASHMAC 0xf0006000 -#elif defined (CONFIG_MTD_KeyTechnology) -#define FEC_FLASHMAC 0xffe04000 #elif defined(CONFIG_CANCam) #define FEC_FLASHMAC 0xf0020000 #elif defined (CONFIG_M5272C3) @@ -212,6 +211,8 @@ struct fec_enet_private { /* Hardware registers of the FEC device */ volatile fec_t *hwp; + struct net_device *netdev; + /* The saved address of a sent-in-place packet/buffer, for skfree(). */ unsigned char *tx_bounce[TX_RING_SIZE]; struct sk_buff* tx_skbuff[TX_RING_SIZE]; @@ -236,7 +237,6 @@ struct fec_enet_private { uint phy_speed; phy_info_t const *phy; struct work_struct phy_task; - struct net_device *net; uint sequence_done; uint mii_phy_task_queued; @@ -675,7 +675,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { fep->stats.rx_bytes += pkt_len; data = (__u8*)__va(bdp->cbd_bufaddr); fec_dcache_inv_range(data, data+pkt_len -4); - + /* This does 16 byte alignment, exactly what we need. * The packet length includes FCS, but we don't want to * include that when passing upstream as it messes up @@ -702,9 +702,9 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { fep->rx_skbuff[rx_index] = skb; skb->data = FEC_ADDR_ALIGNMENT(skb->data); bdp->cbd_bufaddr = __pa(skb->data); - skb_put(pskb,pkt_len-4); /* Make room */ - skb = pskb; - } + skb_put(pskb,pkt_len-4); /* Make room */ + skb = pskb; + } skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } @@ -1340,7 +1340,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3); *icrp = 0x00000ddd; icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (*icrp & 0x70777777) | 0x0d000000; + *icrp = 0x0d000000; } static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) @@ -1402,7 +1402,7 @@ static void __inline__ fec_disable_phy_intr(void) { volatile unsigned long *icrp; icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (*icrp & 0x70777777) | 0x08000000; + *icrp = 0x08000000; } static void __inline__ fec_phy_ack_intr(void) @@ -1410,7 +1410,7 @@ static void __inline__ fec_phy_ack_intr(void) volatile unsigned long *icrp; /* Acknowledge the interrupt */ icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (*icrp & 0x77777777) | 0x08000000; + *icrp = 0x0d000000; } static void __inline__ fec_localhw_setup(void) @@ -1538,6 +1538,29 @@ static void __inline__ fec_request_intrs(struct net_device *dev) *gpio_pehlpar = 0xc0; } #endif + +#if defined(CONFIG_M527x) + /* Set up gpio outputs for MII lines */ + { + volatile u8 *gpio_par_fec; + volatile u16 *gpio_par_feci2c; + + gpio_par_feci2c = (volatile u16 *)(MCF_IPSBAR + 0x100082); + /* Set up gpio outputs for FEC0 MII lines */ + gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100078); + + *gpio_par_feci2c |= 0x0f00; + *gpio_par_fec |= 0xc0; + +#if defined(CONFIG_FEC2) + /* Set up gpio outputs for FEC1 MII lines */ + gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100079); + + *gpio_par_feci2c |= 0x00a0; + *gpio_par_fec |= 0xc0; +#endif /* CONFIG_FEC2 */ + } +#endif /* CONFIG_M527x */ } static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) @@ -2363,9 +2386,8 @@ static void mii_display_status(struct net_device *dev) static void mii_display_config(struct work_struct *work) { - struct fec_enet_private *fep = - container_of(work, struct fec_enet_private, phy_task); - struct net_device *dev = fep->net; + struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->netdev; uint status = fep->phy_status; /* @@ -2401,9 +2423,8 @@ static void mii_display_config(struct work_struct *work) static void mii_relink(struct work_struct *work) { - struct fec_enet_private *fep = - container_of(work, struct fec_enet_private, phy_task); - struct net_device *dev = fep->net; + struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->netdev; int duplex; /* @@ -2447,7 +2468,7 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev) return; fep->mii_phy_task_queued = 1; - INIT_WORK(&fep->phy_task, (void*)mii_relink); + INIT_WORK(&fep->phy_task, mii_relink); schedule_work(&fep->phy_task); } @@ -2460,7 +2481,7 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev) return; fep->mii_phy_task_queued = 1; - INIT_WORK(&fep->phy_task, (void*)mii_display_config); + INIT_WORK(&fep->phy_task, mii_display_config); schedule_work(&fep->phy_task); } @@ -2744,9 +2765,7 @@ int __init fec_enet_init(struct net_device *dev) /* Only allow us to be probed once. */ if (index >= FEC_MAX_PORTS) return -ENXIO; - - fep->net = dev; - + spin_lock_init(&(fep->lock)); /* Allocate memory for buffer descriptors. @@ -2764,6 +2783,7 @@ int __init fec_enet_init(struct net_device *dev) fep->index = index; fep->hwp = fecp; + fep->netdev = dev; /* Whack a reset. We should wait for this. */ |