Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 104942
b: refs/heads/master
c: fec3a23
h: refs/heads/master
v: v3
  • Loading branch information
Florian Fainelli authored and Jeff Garzik committed Jul 22, 2008
1 parent e1b53e5 commit 6d110c3
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 42 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3d25434816356e8d1e3167c5f7a56d3d81aeb239
refs/heads/master: fec3a23be0daceeb0695f8296aea07ea1ad073d8
99 changes: 58 additions & 41 deletions trunk/drivers/net/r6040.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,6 @@ static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring,
static void r6040_rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
{
struct r6040_descriptor *descptr;
void __iomem *ioaddr = lp->base;

descptr = lp->rx_insert_ptr;
while (lp->rx_free_desc < RX_DCNT) {
Expand All @@ -309,68 +308,99 @@ static void r6040_rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
descptr->status = 0x8000;
descptr = descptr->vndescp;
lp->rx_free_desc++;
/* Trigger RX DMA */
iowrite16(lp->mcr0 | 0x0002, ioaddr);
}
lp->rx_insert_ptr = descptr;
}

static void r6040_alloc_txbufs(struct net_device *dev)
{
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;

lp->tx_free_desc = TX_DCNT;

lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring;
r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);

iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0);
iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1);
}

static void r6040_alloc_rxbufs(struct net_device *dev)
{
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;

lp->rx_free_desc = 0;

lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);

r6040_rx_buf_alloc(lp, dev);
}

static void r6040_init_mac_regs(struct net_device *dev)
{
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
int limit = 2048;
u16 cmd;

/* Mask Off Interrupt */
iowrite16(MSK_INT, ioaddr + MIER);

/* Reset RDC MAC */
iowrite16(MAC_RST, ioaddr + MCR1);
while (limit--) {
cmd = ioread16(ioaddr + MCR1);
if (cmd & 0x1)
break;
}
/* Reset internal state machine */
iowrite16(2, ioaddr + MAC_SM);
iowrite16(0, ioaddr + MAC_SM);
udelay(5000);

/* MAC Bus Control Register */
iowrite16(MBCR_DEFAULT, ioaddr + MBCR);

/* Buffer Size Register */
iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR);

/* Write TX ring start address */
iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0);
iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1);

/* Write RX ring start address */
iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0);
iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1);

/* Set interrupt waiting time and packet numbers */
iowrite16(0x0F06, ioaddr + MT_ICR);
iowrite16(0x0F06, ioaddr + MR_ICR);

/* Enable interrupts */
iowrite16(INT_MASK, ioaddr + MIER);

/* Enable TX and RX */
iowrite16(lp->mcr0 | 0x0002, ioaddr);

/* Let TX poll the descriptors
* we may got called by r6040_tx_timeout which has left
* some unsent tx buffers */
iowrite16(0x01, ioaddr + MTPR);
}

static void r6040_tx_timeout(struct net_device *dev)
{
struct r6040_private *priv = netdev_priv(dev);
void __iomem *ioaddr = priv->base;

printk(KERN_WARNING "%s: transmit timed out, status %4.4x, PHY status "
"%4.4x\n",
printk(KERN_WARNING "%s: transmit timed out, int enable %4.4x "
"status %4.4x, PHY status %4.4x\n",
dev->name, ioread16(ioaddr + MIER),
ioread16(ioaddr + MISR),
r6040_mdio_read(dev, priv->mii_if.phy_id, MII_BMSR));

disable_irq(dev->irq);
napi_disable(&priv->napi);
spin_lock(&priv->lock);
/* Clear all descriptors */
r6040_free_txbufs(dev);
r6040_free_rxbufs(dev);
r6040_alloc_txbufs(dev);
r6040_alloc_rxbufs(dev);

/* Reset MAC */
iowrite16(MAC_RST, ioaddr + MCR1);
spin_unlock(&priv->lock);
enable_irq(dev->irq);

dev->stats.tx_errors++;
netif_wake_queue(dev);

/* Reset MAC and re-init all registers */
r6040_init_mac_regs(dev);
}

static struct net_device_stats *r6040_get_stats(struct net_device *dev)
Expand Down Expand Up @@ -676,8 +706,6 @@ static void r6040_up(struct net_device *dev)
r6040_alloc_txbufs(dev);
r6040_alloc_rxbufs(dev);

/* Buffer Size Register */
iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR);
/* Read the PHY ID */
lp->switch_sig = r6040_phy_read(ioaddr, 0, 2);

Expand All @@ -694,29 +722,18 @@ static void r6040_up(struct net_device *dev)
else
lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0;
}
/* MAC Bus Control Register :
* - wait 1 host clock SDRAM bus request
* - RX FIFO : 32 bytes
* - TX FIFO : 64 bytes
* - FIFO transfer lenght : 16 bytes */
iowrite16(MBCR_DEFAULT, ioaddr + MBCR);

/* MAC TX/RX Enable */
/* Set duplex mode */
lp->mcr0 |= lp->phy_mode;
iowrite16(lp->mcr0, ioaddr);

/* set interrupt waiting time and packet numbers */
iowrite16(0x0F06, ioaddr + MT_ICR);
iowrite16(0x0F06, ioaddr + MR_ICR);

/* improve performance (by RDC guys) */
r6040_phy_write(ioaddr, 30, 17, (r6040_phy_read(ioaddr, 30, 17) | 0x4000));
r6040_phy_write(ioaddr, 30, 17, ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000));
r6040_phy_write(ioaddr, 0, 19, 0x0000);
r6040_phy_write(ioaddr, 0, 30, 0x01F0);

/* Interrupt Mask Register */
iowrite16(INT_MASK, ioaddr + MIER);
/* Initialize all MAC registers */
r6040_init_mac_regs(dev);
}

/*
Expand Down

0 comments on commit 6d110c3

Please sign in to comment.