提交 f44d6305 编写于 作者: S Sascha Hauer 提交者: David S. Miller

fec: switch to writel/readl

Signed-off-by: NSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 2160187a
...@@ -165,7 +165,7 @@ typedef struct { ...@@ -165,7 +165,7 @@ typedef struct {
*/ */
struct fec_enet_private { struct fec_enet_private {
/* Hardware registers of the FEC device */ /* Hardware registers of the FEC device */
volatile fec_t *hwp; void __iomem *hwp;
struct net_device *netdev; struct net_device *netdev;
...@@ -288,15 +288,11 @@ static int mii_queue(struct net_device *dev, int request, ...@@ -288,15 +288,11 @@ static int mii_queue(struct net_device *dev, int request,
static int static int
fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct fec_enet_private *fep; struct fec_enet_private *fep = netdev_priv(dev);
volatile fec_t *fecp;
volatile cbd_t *bdp; volatile cbd_t *bdp;
unsigned short status; unsigned short status;
unsigned long flags; unsigned long flags;
fep = netdev_priv(dev);
fecp = (volatile fec_t*)dev->base_addr;
if (!fep->link) { if (!fep->link) {
/* Link is down or autonegotiation is in progress. */ /* Link is down or autonegotiation is in progress. */
return 1; return 1;
...@@ -363,7 +359,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -363,7 +359,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies; dev->trans_start = jiffies;
/* Trigger transmission start */ /* Trigger transmission start */
fecp->fec_x_des_active = 0; writel(0, fep->hwp + FEC_X_DES_ACTIVE);
/* If this was the last BD in the ring, start at the beginning again. /* If this was the last BD in the ring, start at the beginning again.
*/ */
...@@ -436,29 +432,25 @@ static irqreturn_t ...@@ -436,29 +432,25 @@ static irqreturn_t
fec_enet_interrupt(int irq, void * dev_id) fec_enet_interrupt(int irq, void * dev_id)
{ {
struct net_device *dev = dev_id; struct net_device *dev = dev_id;
volatile fec_t *fecp; struct fec_enet_private *fep = netdev_priv(dev);
uint int_events; uint int_events;
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
fecp = (volatile fec_t*)dev->base_addr; /* Get the interrupt events that caused us to be here. */
/* Get the interrupt events that caused us to be here.
*/
do { do {
int_events = fecp->fec_ievent; int_events = readl(fep->hwp + FEC_IEVENT);
fecp->fec_ievent = int_events; writel(int_events, fep->hwp + FEC_IEVENT);
/* Handle receive event in its own function. /* Handle receive event in its own function. */
*/
if (int_events & FEC_ENET_RXF) { if (int_events & FEC_ENET_RXF) {
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
fec_enet_rx(dev); fec_enet_rx(dev);
} }
/* Transmit OK, or non-fatal error. Update the buffer /* Transmit OK, or non-fatal error. Update the buffer
descriptors. FEC handles all errors, we just discover * descriptors. FEC handles all errors, we just discover
them as part of the transmit process. * them as part of the transmit process.
*/ */
if (int_events & FEC_ENET_TXF) { if (int_events & FEC_ENET_TXF) {
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
fec_enet_tx(dev); fec_enet_tx(dev);
...@@ -555,8 +547,7 @@ fec_enet_tx(struct net_device *dev) ...@@ -555,8 +547,7 @@ fec_enet_tx(struct net_device *dev)
static void static void
fec_enet_rx(struct net_device *dev) fec_enet_rx(struct net_device *dev)
{ {
struct fec_enet_private *fep; struct fec_enet_private *fep = netdev_priv(dev);
volatile fec_t *fecp;
volatile cbd_t *bdp; volatile cbd_t *bdp;
unsigned short status; unsigned short status;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -567,9 +558,6 @@ fec_enet_rx(struct net_device *dev) ...@@ -567,9 +558,6 @@ fec_enet_rx(struct net_device *dev)
flush_cache_all(); flush_cache_all();
#endif #endif
fep = netdev_priv(dev);
fecp = (volatile fec_t*)dev->base_addr;
spin_lock_irq(&fep->hw_lock); spin_lock_irq(&fep->hw_lock);
/* First, grab all of the stats for the incoming packet. /* First, grab all of the stats for the incoming packet.
...@@ -665,7 +653,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { ...@@ -665,7 +653,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
* incoming frames. On a heavily loaded network, we should be * incoming frames. On a heavily loaded network, we should be
* able to keep up at the expense of system resources. * able to keep up at the expense of system resources.
*/ */
fecp->fec_r_des_active = 0; writel(0, fep->hwp + FEC_R_DES_ACTIVE);
#endif #endif
} /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */
fep->cur_rx = (cbd_t *)bdp; fep->cur_rx = (cbd_t *)bdp;
...@@ -690,30 +678,25 @@ static void ...@@ -690,30 +678,25 @@ static void
fec_enet_mii(struct net_device *dev) fec_enet_mii(struct net_device *dev)
{ {
struct fec_enet_private *fep; struct fec_enet_private *fep;
volatile fec_t *ep;
mii_list_t *mip; mii_list_t *mip;
uint mii_reg;
fep = netdev_priv(dev); fep = netdev_priv(dev);
spin_lock_irq(&fep->mii_lock); spin_lock_irq(&fep->mii_lock);
ep = fep->hwp;
mii_reg = ep->fec_mii_data;
if ((mip = mii_head) == NULL) { if ((mip = mii_head) == NULL) {
printk("MII and no head!\n"); printk("MII and no head!\n");
goto unlock; goto unlock;
} }
if (mip->mii_func != NULL) if (mip->mii_func != NULL)
(*(mip->mii_func))(mii_reg, dev); (*(mip->mii_func))(readl(fep->hwp + FEC_MII_DATA), dev);
mii_head = mip->mii_next; mii_head = mip->mii_next;
mip->mii_next = mii_free; mip->mii_next = mii_free;
mii_free = mip; mii_free = mip;
if ((mip = mii_head) != NULL) if ((mip = mii_head) != NULL)
ep->fec_mii_data = mip->mii_regval; writel(mip->mii_regval, fep->hwp + FEC_MII_DATA);
unlock: unlock:
spin_unlock_irq(&fep->mii_lock); spin_unlock_irq(&fep->mii_lock);
...@@ -745,7 +728,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi ...@@ -745,7 +728,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
mii_tail = mip; mii_tail = mip;
} else { } else {
mii_head = mii_tail = mip; mii_head = mii_tail = mip;
fep->hwp->fec_mii_data = regval; writel(regval, fep->hwp + FEC_MII_DATA);
} }
} else { } else {
retval = 1; retval = 1;
...@@ -1245,11 +1228,8 @@ static void __inline__ fec_phy_ack_intr(void) ...@@ -1245,11 +1228,8 @@ static void __inline__ fec_phy_ack_intr(void)
static void __inline__ fec_get_mac(struct net_device *dev) static void __inline__ fec_get_mac(struct net_device *dev)
{ {
struct fec_enet_private *fep = netdev_priv(dev); struct fec_enet_private *fep = netdev_priv(dev);
volatile fec_t *fecp;
unsigned char *iap, tmpaddr[ETH_ALEN]; unsigned char *iap, tmpaddr[ETH_ALEN];
fecp = fep->hwp;
if (FEC_FLASHMAC) { if (FEC_FLASHMAC) {
/* /*
* Get MAC address from FLASH. * Get MAC address from FLASH.
...@@ -1263,8 +1243,8 @@ static void __inline__ fec_get_mac(struct net_device *dev) ...@@ -1263,8 +1243,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
(iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
iap = fec_mac_default; iap = fec_mac_default;
} else { } else {
*((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; *((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
*((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); *((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
iap = &tmpaddr[0]; iap = &tmpaddr[0];
} }
...@@ -1456,11 +1436,9 @@ static void ...@@ -1456,11 +1436,9 @@ static void
mii_discover_phy(uint mii_reg, struct net_device *dev) mii_discover_phy(uint mii_reg, struct net_device *dev)
{ {
struct fec_enet_private *fep; struct fec_enet_private *fep;
volatile fec_t *fecp;
uint phytype; uint phytype;
fep = netdev_priv(dev); fep = netdev_priv(dev);
fecp = fep->hwp;
if (fep->phy_addr < 32) { if (fep->phy_addr < 32) {
if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) { if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
...@@ -1478,7 +1456,8 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) ...@@ -1478,7 +1456,8 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
} else { } else {
printk("FEC: No PHY device found.\n"); printk("FEC: No PHY device found.\n");
/* Disable external MII interface */ /* Disable external MII interface */
fecp->fec_mii_speed = fep->phy_speed = 0; writel(0, fep->hwp + FEC_MII_SPEED);
fep->phy_speed = 0;
#ifdef HAVE_mii_link_interrupt #ifdef HAVE_mii_link_interrupt
fec_disable_phy_intr(); fec_disable_phy_intr();
#endif #endif
...@@ -1582,32 +1561,31 @@ fec_enet_close(struct net_device *dev) ...@@ -1582,32 +1561,31 @@ fec_enet_close(struct net_device *dev)
static void set_multicast_list(struct net_device *dev) static void set_multicast_list(struct net_device *dev)
{ {
struct fec_enet_private *fep; struct fec_enet_private *fep = netdev_priv(dev);
volatile fec_t *ep;
struct dev_mc_list *dmi; struct dev_mc_list *dmi;
unsigned int i, j, bit, data, crc; unsigned int i, j, bit, data, crc, tmp;
unsigned char hash; unsigned char hash;
fep = netdev_priv(dev);
ep = fep->hwp;
if (dev->flags&IFF_PROMISC) { if (dev->flags&IFF_PROMISC) {
ep->fec_r_cntrl |= 0x0008; tmp = readl(fep->hwp + FEC_R_CNTRL);
tmp |= 0x8;
writel(tmp, fep->hwp + FEC_R_CNTRL);
} else { } else {
tmp = readl(fep->hwp + FEC_R_CNTRL);
ep->fec_r_cntrl &= ~0x0008; tmp &= ~0x8;
writel(tmp, fep->hwp + FEC_R_CNTRL);
if (dev->flags & IFF_ALLMULTI) { if (dev->flags & IFF_ALLMULTI) {
/* Catch all multicast addresses, so set the /* Catch all multicast addresses, so set the
* filter to all 1's. * filter to all 1's.
*/ */
ep->fec_grp_hash_table_high = 0xffffffff; writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
ep->fec_grp_hash_table_low = 0xffffffff; writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
} else { } else {
/* Clear filter and add the addresses in hash register. /* Clear filter and add the addresses in hash register.
*/ */
ep->fec_grp_hash_table_high = 0; writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
ep->fec_grp_hash_table_low = 0; writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
dmi = dev->mc_list; dmi = dev->mc_list;
...@@ -1637,10 +1615,15 @@ static void set_multicast_list(struct net_device *dev) ...@@ -1637,10 +1615,15 @@ static void set_multicast_list(struct net_device *dev)
*/ */
hash = (crc >> (32 - HASH_BITS)) & 0x3f; hash = (crc >> (32 - HASH_BITS)) & 0x3f;
if (hash > 31) if (hash > 31) {
ep->fec_grp_hash_table_high |= 1 << (hash - 32); tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
else tmp |= 1 << (hash - 32);
ep->fec_grp_hash_table_low |= 1 << hash; writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
} else {
tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
tmp |= 1 << hash;
writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
}
} }
} }
} }
...@@ -1651,16 +1634,14 @@ static void set_multicast_list(struct net_device *dev) ...@@ -1651,16 +1634,14 @@ static void set_multicast_list(struct net_device *dev)
static void static void
fec_set_mac_address(struct net_device *dev) fec_set_mac_address(struct net_device *dev)
{ {
volatile fec_t *fecp; struct fec_enet_private *fep = netdev_priv(dev);
fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp;
/* Set station address. */ /* Set station address. */
fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) | writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
(dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24); (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
fecp->fec_addr_high = (dev->dev_addr[5] << 16) | fep->hwp + FEC_ADDR_LOW);
(dev->dev_addr[4] << 24); writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24),
fep + FEC_ADDR_HIGH);
} }
/* /*
...@@ -1674,7 +1655,6 @@ int __init fec_enet_init(struct net_device *dev, int index) ...@@ -1674,7 +1655,6 @@ int __init fec_enet_init(struct net_device *dev, int index)
unsigned long mem_addr; unsigned long mem_addr;
volatile cbd_t *bdp; volatile cbd_t *bdp;
cbd_t *cbd_base; cbd_t *cbd_base;
volatile fec_t *fecp;
int i, j; int i, j;
/* Allocate memory for buffer descriptors. /* Allocate memory for buffer descriptors.
...@@ -1689,17 +1669,13 @@ int __init fec_enet_init(struct net_device *dev, int index) ...@@ -1689,17 +1669,13 @@ int __init fec_enet_init(struct net_device *dev, int index)
spin_lock_init(&fep->hw_lock); spin_lock_init(&fep->hw_lock);
spin_lock_init(&fep->mii_lock); spin_lock_init(&fep->mii_lock);
/* Create an Ethernet device instance.
*/
fecp = (volatile fec_t *)dev->base_addr;
fep->index = index; fep->index = index;
fep->hwp = fecp; fep->hwp = (void __iomem *)dev->base_addr;
fep->netdev = dev; fep->netdev = dev;
/* Whack a reset. We should wait for this. /* Whack a reset. We should wait for this.
*/ */
fecp->fec_ecntrl = 1; writel(1, fep->hwp + FEC_ECNTRL);
udelay(10); udelay(10);
/* Set the Ethernet address */ /* Set the Ethernet address */
...@@ -1708,12 +1684,12 @@ int __init fec_enet_init(struct net_device *dev, int index) ...@@ -1708,12 +1684,12 @@ int __init fec_enet_init(struct net_device *dev, int index)
#else #else
{ {
unsigned long l; unsigned long l;
l = fecp->fec_addr_low; l = readl(fep->hwp + FEC_ADDR_LOW);
dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24); dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16); dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8); dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0); dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
l = fecp->fec_addr_high; l = readl(fep->hwp + FEC_ADDR_HIGH);
dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24); dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16); dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
} }
...@@ -1783,22 +1759,22 @@ int __init fec_enet_init(struct net_device *dev, int index) ...@@ -1783,22 +1759,22 @@ int __init fec_enet_init(struct net_device *dev, int index)
/* Set receive and transmit descriptor base. /* Set receive and transmit descriptor base.
*/ */
fecp->fec_r_des_start = fep->bd_dma; writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE,
* RX_RING_SIZE; fep->hwp + FEC_X_DES_START);
#ifdef HAVE_mii_link_interrupt #ifdef HAVE_mii_link_interrupt
fec_request_mii_intr(dev); fec_request_mii_intr(dev);
#endif #endif
fecp->fec_grp_hash_table_high = 0; writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
fecp->fec_grp_hash_table_low = 0; writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
fecp->fec_ecntrl = 2; writel(2, fep->hwp + FEC_ECNTRL);
fecp->fec_r_des_active = 0; writel(0, fep->hwp + FEC_R_DES_ACTIVE);
#ifndef CONFIG_M5272 #ifndef CONFIG_M5272
fecp->fec_hash_table_high = 0; writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
fecp->fec_hash_table_low = 0; writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
#endif #endif
/* The FEC Ethernet specific entries in the device structure. */ /* The FEC Ethernet specific entries in the device structure. */
...@@ -1814,20 +1790,21 @@ int __init fec_enet_init(struct net_device *dev, int index) ...@@ -1814,20 +1790,21 @@ int __init fec_enet_init(struct net_device *dev, int index)
mii_free = mii_cmds; mii_free = mii_cmds;
/* setup MII interface */ /* setup MII interface */
fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
fecp->fec_x_cntrl = 0x00; writel(0, fep->hwp + FEC_X_CNTRL);
/* /*
* Set MII speed to 2.5 MHz * Set MII speed to 2.5 MHz
*/ */
fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999) fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
/ 2500000) / 2) & 0x3F) << 1; / 2500000) / 2) & 0x3F) << 1;
fecp->fec_mii_speed = fep->phy_speed; writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
fec_restart(dev, 0); fec_restart(dev, 0);
/* Clear and enable interrupts */ /* Clear and enable interrupts */
fecp->fec_ievent = 0xffc00000; writel(0xffc00000, fep->hwp + FEC_IEVENT);
fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
fep->hwp + FEC_IMASK);
/* Queue up command to detect the PHY and initialize the /* Queue up command to detect the PHY and initialize the
* remainder of the interface. * remainder of the interface.
...@@ -1846,47 +1823,36 @@ int __init fec_enet_init(struct net_device *dev, int index) ...@@ -1846,47 +1823,36 @@ int __init fec_enet_init(struct net_device *dev, int index)
static void static void
fec_restart(struct net_device *dev, int duplex) fec_restart(struct net_device *dev, int duplex)
{ {
struct fec_enet_private *fep; struct fec_enet_private *fep = netdev_priv(dev);
volatile cbd_t *bdp; volatile cbd_t *bdp;
volatile fec_t *fecp;
int i; int i;
fep = netdev_priv(dev); /* Whack a reset. We should wait for this. */
fecp = fep->hwp; writel(1, fep->hwp + FEC_ECNTRL);
/* Whack a reset. We should wait for this.
*/
fecp->fec_ecntrl = 1;
udelay(10); udelay(10);
/* Clear any outstanding interrupt. /* Clear any outstanding interrupt. */
*/ writel(0xffc00000, fep->hwp + FEC_IEVENT);
fecp->fec_ievent = 0xffc00000;
/* Set station address. /* Set station address. */
*/
fec_set_mac_address(dev); fec_set_mac_address(dev);
/* Reset all multicast. /* Reset all multicast. */
*/ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
fecp->fec_grp_hash_table_high = 0; writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
fecp->fec_grp_hash_table_low = 0;
/* Set maximum receive buffer size. /* Set maximum receive buffer size. */
*/ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
/* Set receive and transmit descriptor base. /* Set receive and transmit descriptor base. */
*/ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
fecp->fec_r_des_start = fep->bd_dma; writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE,
fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) fep->hwp + FEC_X_DES_START);
* RX_RING_SIZE;
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fep->cur_rx = fep->rx_bd_base; fep->cur_rx = fep->rx_bd_base;
/* Reset SKB transmit buffers. /* Reset SKB transmit buffers. */
*/
fep->skb_cur = fep->skb_dirty = 0; fep->skb_cur = fep->skb_dirty = 0;
for (i=0; i<=TX_RING_MOD_MASK; i++) { for (i=0; i<=TX_RING_MOD_MASK; i++) {
if (fep->tx_skbuff[i] != NULL) { if (fep->tx_skbuff[i] != NULL) {
...@@ -1895,96 +1861,81 @@ fec_restart(struct net_device *dev, int duplex) ...@@ -1895,96 +1861,81 @@ fec_restart(struct net_device *dev, int duplex)
} }
} }
/* Initialize the receive buffer descriptors. /* Initialize the receive buffer descriptors. */
*/
bdp = fep->rx_bd_base; bdp = fep->rx_bd_base;
for (i=0; i<RX_RING_SIZE; i++) { for (i=0; i<RX_RING_SIZE; i++) {
/* Initialize the BD for every fragment in the page. /* Initialize the BD for every fragment in the page. */
*/
bdp->cbd_sc = BD_ENET_RX_EMPTY; bdp->cbd_sc = BD_ENET_RX_EMPTY;
bdp++; bdp++;
} }
/* Set the last buffer to wrap. /* Set the last buffer to wrap. */
*/
bdp--; bdp--;
bdp->cbd_sc |= BD_SC_WRAP; bdp->cbd_sc |= BD_SC_WRAP;
/* ...and the same for transmmit. /* ...and the same for transmmit. */
*/
bdp = fep->tx_bd_base; bdp = fep->tx_bd_base;
for (i=0; i<TX_RING_SIZE; i++) { for (i=0; i<TX_RING_SIZE; i++) {
/* Initialize the BD for every fragment in the page. /* Initialize the BD for every fragment in the page. */
*/
bdp->cbd_sc = 0; bdp->cbd_sc = 0;
bdp->cbd_bufaddr = 0; bdp->cbd_bufaddr = 0;
bdp++; bdp++;
} }
/* Set the last buffer to wrap. /* Set the last buffer to wrap. */
*/
bdp--; bdp--;
bdp->cbd_sc |= BD_SC_WRAP; bdp->cbd_sc |= BD_SC_WRAP;
/* Enable MII mode. /* Enable MII mode. */
*/
if (duplex) { if (duplex) {
fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */ /* MII enable / FD enable */
fecp->fec_x_cntrl = 0x04; /* FD enable */ writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
writel(0x04, fep->hwp + FEC_X_CNTRL);
} else { } else {
/* MII enable|No Rcv on Xmit */ /* MII enable / No Rcv on Xmit */
fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06; writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL);
fecp->fec_x_cntrl = 0x00; writel(0x0, fep->hwp + FEC_X_CNTRL);
} }
fep->full_duplex = duplex; fep->full_duplex = duplex;
/* Set MII speed. /* Set MII speed. */
*/ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
fecp->fec_mii_speed = fep->phy_speed;
/* And last, enable the transmit and receive processing. /* And last, enable the transmit and receive processing. */
*/ writel(2, fep->hwp + FEC_ECNTRL);
fecp->fec_ecntrl = 2; writel(0, fep->hwp + FEC_R_DES_ACTIVE);
fecp->fec_r_des_active = 0;
/* Enable interrupts we wish to service. /* Enable interrupts we wish to service. */
*/ writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); fep->hwp + FEC_IMASK);
} }
static void static void
fec_stop(struct net_device *dev) fec_stop(struct net_device *dev)
{ {
volatile fec_t *fecp; struct fec_enet_private *fep = netdev_priv(dev);
struct fec_enet_private *fep;
fep = netdev_priv(dev);
fecp = fep->hwp;
/* /*
** We cannot expect a graceful transmit stop without link !!! ** We cannot expect a graceful transmit stop without link !!!
*/ */
if (fep->link) if (fep->link) {
{ writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */
udelay(10); udelay(10);
if (!(fecp->fec_ievent & FEC_ENET_GRA)) if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
printk("fec_stop : Graceful transmit stop did not complete !\n"); printk("fec_stop : Graceful transmit stop did not complete !\n");
} }
/* Whack a reset. We should wait for this. /* Whack a reset. We should wait for this. */
*/ writel(1, fep->hwp + FEC_ECNTRL);
fecp->fec_ecntrl = 1;
udelay(10); udelay(10);
/* Clear outstanding MII command interrupts. /* Clear outstanding MII command interrupts. */
*/ writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
fecp->fec_ievent = FEC_ENET_MII;
fecp->fec_imask = FEC_ENET_MII; writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
fecp->fec_mii_speed = fep->phy_speed; writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
} }
static int __devinit static int __devinit
......
...@@ -20,82 +20,55 @@ ...@@ -20,82 +20,55 @@
* registers in the same peripheral device on different models * registers in the same peripheral device on different models
* of the ColdFire! * of the ColdFire!
*/ */
typedef struct fec { #define FEC_IEVENT 0x004 /* Interrupt event reg */
unsigned long fec_reserved0; #define FEC_IMASK 0x008 /* Interrupt mask reg */
unsigned long fec_ievent; /* Interrupt event reg */ #define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */
unsigned long fec_imask; /* Interrupt mask reg */ #define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */
unsigned long fec_reserved1; #define FEC_ECNTRL 0x024 /* Ethernet control reg */
unsigned long fec_r_des_active; /* Receive descriptor reg */ #define FEC_MII_DATA 0x040 /* MII manage frame reg */
unsigned long fec_x_des_active; /* Transmit descriptor reg */ #define FEC_MII_SPEED 0x044 /* MII speed control reg */
unsigned long fec_reserved2[3]; #define FEC_MIB_CTRLSTAT 0x064 /* MIB control/status reg */
unsigned long fec_ecntrl; /* Ethernet control reg */ #define FEC_R_CNTRL 0x084 /* Receive control reg */
unsigned long fec_reserved3[6]; #define FEC_X_CNTRL 0x0c4 /* Transmit Control reg */
unsigned long fec_mii_data; /* MII manage frame reg */ #define FEC_ADDR_LOW 0x0e4 /* Low 32bits MAC address */
unsigned long fec_mii_speed; /* MII speed control reg */ #define FEC_ADDR_HIGH 0x0e8 /* High 16bits MAC address */
unsigned long fec_reserved4[7]; #define FEC_OPD 0x0ec /* Opcode + Pause duration */
unsigned long fec_mib_ctrlstat; /* MIB control/status reg */ #define FEC_HASH_TABLE_HIGH 0x118 /* High 32bits hash table */
unsigned long fec_reserved5[7]; #define FEC_HASH_TABLE_LOW 0x11c /* Low 32bits hash table */
unsigned long fec_r_cntrl; /* Receive control reg */ #define FEC_GRP_HASH_TABLE_HIGH 0x120 /* High 32bits hash table */
unsigned long fec_reserved6[15]; #define FEC_GRP_HASH_TABLE_LOW 0x124 /* Low 32bits hash table */
unsigned long fec_x_cntrl; /* Transmit Control reg */ #define FEC_X_WMRK 0x144 /* FIFO transmit water mark */
unsigned long fec_reserved7[7]; #define FEC_R_BOUND 0x14c /* FIFO receive bound reg */
unsigned long fec_addr_low; /* Low 32bits MAC address */ #define FEC_R_FSTART 0x150 /* FIFO receive start reg */
unsigned long fec_addr_high; /* High 16bits MAC address */ #define FEC_R_DES_START 0x180 /* Receive descriptor ring */
unsigned long fec_opd; /* Opcode + Pause duration */ #define FEC_X_DES_START 0x184 /* Transmit descriptor ring */
unsigned long fec_reserved8[10]; #define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */
unsigned long fec_hash_table_high; /* High 32bits hash table */
unsigned long fec_hash_table_low; /* Low 32bits hash table */
unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
unsigned long fec_reserved9[7];
unsigned long fec_x_wmrk; /* FIFO transmit water mark */
unsigned long fec_reserved10;
unsigned long fec_r_bound; /* FIFO receive bound reg */
unsigned long fec_r_fstart; /* FIFO receive start reg */
unsigned long fec_reserved11[11];
unsigned long fec_r_des_start; /* Receive descriptor ring */
unsigned long fec_x_des_start; /* Transmit descriptor ring */
unsigned long fec_r_buff_size; /* Maximum receive buff size */
} fec_t;
#else #else
/* #define FEC_ECNTRL; 0x000 /* Ethernet control reg */
* Define device register set address map. #define FEC_IEVENT; 0x004 /* Interrupt even reg */
*/ #define FEC_IMASK; 0x008 /* Interrupt mask reg */
typedef struct fec { #define FEC_IVEC; 0x00c /* Interrupt vec status reg */
unsigned long fec_ecntrl; /* Ethernet control reg */ #define FEC_R_DES_ACTIVE; 0x010 /* Receive descriptor reg */
unsigned long fec_ievent; /* Interrupt even reg */ #define FEC_X_DES_ACTIVE; 0x01c /* Transmit descriptor reg */
unsigned long fec_imask; /* Interrupt mask reg */ #define FEC_MII_DATA 0x040 /* MII manage frame reg */
unsigned long fec_ivec; /* Interrupt vec status reg */ #define FEC_MII_SPEED 0x044 /* MII speed control reg */
unsigned long fec_r_des_active; /* Receive descriptor reg */ #define FEC_R_BOUND 0x08c /* FIFO receive bound reg */
unsigned long fec_x_des_active; /* Transmit descriptor reg */ #define FEC_R_FSTART 0x090 /* FIFO receive start reg */
unsigned long fec_reserved1[10]; #define FEC_X_WMRK 0x0a4 /* FIFO transmit water mark */
unsigned long fec_mii_data; /* MII manage frame reg */ #define FEC_X_FSTART 0x0ac /* FIFO transmit start reg */
unsigned long fec_mii_speed; /* MII speed control reg */ #define FEC_R_CNTRL 0x104 /* Receive control reg */
unsigned long fec_reserved2[17]; #define FEC_MAX_FRM_LEN 0x108 /* Maximum frame length reg */
unsigned long fec_r_bound; /* FIFO receive bound reg */ #define FEC_X_CNTRL 0x144 /* Transmit Control reg */
unsigned long fec_r_fstart; /* FIFO receive start reg */ #define FEC_ADDR_LOW 0x3c0 /* Low 32bits MAC address */
unsigned long fec_reserved3[4]; #define FEC_ADDR_HIGH 0x3c4 /* High 16bits MAC address */
unsigned long fec_x_wmrk; /* FIFO transmit water mark */ #define FEC_GRP_HASH_TABLE_HIGH 0x3c8 /* High 32bits hash table */
unsigned long fec_reserved4; #define FEC_GRP_HASH_TABLE_LOW 0x3cc /* Low 32bits hash table */
unsigned long fec_x_fstart; /* FIFO transmit start reg */ #define FEC_R_DES_START 0x3d0 /* Receive descriptor ring */
unsigned long fec_reserved5[21]; #define FEC_X_DES_START 0x3d4 /* Transmit descriptor ring */
unsigned long fec_r_cntrl; /* Receive control reg */ #define FEC_R_BUFF_SIZE 0x3d8 /* Maximum receive buff size */
unsigned long fec_max_frm_len; /* Maximum frame length reg */ #define FEC_FIFO_RAM 0x400 /* FIFO RAM buffer */
unsigned long fec_reserved6[14];
unsigned long fec_x_cntrl; /* Transmit Control reg */
unsigned long fec_reserved7[158];
unsigned long fec_addr_low; /* Low 32bits MAC address */
unsigned long fec_addr_high; /* High 16bits MAC address */
unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
unsigned long fec_r_des_start; /* Receive descriptor ring */
unsigned long fec_x_des_start; /* Transmit descriptor ring */
unsigned long fec_r_buff_size; /* Maximum receive buff size */
unsigned long reserved8[9];
unsigned long fec_fifo_ram[112]; /* FIFO RAM buffer */
} fec_t;
#endif /* CONFIG_M5272 */ #endif /* CONFIG_M5272 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册