aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/mv643xx_eth.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 910920e21259..d7620c50efb1 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -405,6 +405,17 @@ static void rxq_disable(struct rx_queue *rxq)
405 udelay(10); 405 udelay(10);
406} 406}
407 407
408static void txq_reset_hw_ptr(struct tx_queue *txq)
409{
410 struct mv643xx_eth_private *mp = txq_to_mp(txq);
411 int off = TXQ_CURRENT_DESC_PTR(mp->port_num, txq->index);
412 u32 addr;
413
414 addr = (u32)txq->tx_desc_dma;
415 addr += txq->tx_curr_desc * sizeof(struct tx_desc);
416 wrl(mp, off, addr);
417}
418
408static void txq_enable(struct tx_queue *txq) 419static void txq_enable(struct tx_queue *txq)
409{ 420{
410 struct mv643xx_eth_private *mp = txq_to_mp(txq); 421 struct mv643xx_eth_private *mp = txq_to_mp(txq);
@@ -1545,8 +1556,11 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
1545 1556
1546 tx_desc = (struct tx_desc *)txq->tx_desc_area; 1557 tx_desc = (struct tx_desc *)txq->tx_desc_area;
1547 for (i = 0; i < txq->tx_ring_size; i++) { 1558 for (i = 0; i < txq->tx_ring_size; i++) {
1559 struct tx_desc *txd = tx_desc + i;
1548 int nexti = (i + 1) % txq->tx_ring_size; 1560 int nexti = (i + 1) % txq->tx_ring_size;
1549 tx_desc[i].next_desc_ptr = txq->tx_desc_dma + 1561
1562 txd->cmd_sts = 0;
1563 txd->next_desc_ptr = txq->tx_desc_dma +
1550 nexti * sizeof(struct tx_desc); 1564 nexti * sizeof(struct tx_desc);
1551 } 1565 }
1552 1566
@@ -1583,8 +1597,11 @@ static void txq_reclaim(struct tx_queue *txq, int force)
1583 desc = &txq->tx_desc_area[tx_index]; 1597 desc = &txq->tx_desc_area[tx_index];
1584 cmd_sts = desc->cmd_sts; 1598 cmd_sts = desc->cmd_sts;
1585 1599
1586 if (!force && (cmd_sts & BUFFER_OWNED_BY_DMA)) 1600 if (cmd_sts & BUFFER_OWNED_BY_DMA) {
1587 break; 1601 if (!force)
1602 break;
1603 desc->cmd_sts = cmd_sts & ~BUFFER_OWNED_BY_DMA;
1604 }
1588 1605
1589 txq->tx_used_desc = (tx_index + 1) % txq->tx_ring_size; 1606 txq->tx_used_desc = (tx_index + 1) % txq->tx_ring_size;
1590 txq->tx_desc_count--; 1607 txq->tx_desc_count--;
@@ -1705,8 +1722,6 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
1705 1722
1706 if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) { 1723 if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) {
1707 if (mp->phy_addr == -1 || mii_link_ok(&mp->mii)) { 1724 if (mp->phy_addr == -1 || mii_link_ok(&mp->mii)) {
1708 int i;
1709
1710 if (mp->phy_addr != -1) { 1725 if (mp->phy_addr != -1) {
1711 struct ethtool_cmd cmd; 1726 struct ethtool_cmd cmd;
1712 1727
@@ -1714,17 +1729,24 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
1714 update_pscr(mp, cmd.speed, cmd.duplex); 1729 update_pscr(mp, cmd.speed, cmd.duplex);
1715 } 1730 }
1716 1731
1717 for (i = 0; i < 8; i++)
1718 if (mp->txq_mask & (1 << i))
1719 txq_enable(mp->txq + i);
1720
1721 if (!netif_carrier_ok(dev)) { 1732 if (!netif_carrier_ok(dev)) {
1722 netif_carrier_on(dev); 1733 netif_carrier_on(dev);
1723 __txq_maybe_wake(mp->txq + mp->txq_primary); 1734 netif_wake_queue(dev);
1724 } 1735 }
1725 } else if (netif_carrier_ok(dev)) { 1736 } else if (netif_carrier_ok(dev)) {
1737 int i;
1738
1726 netif_stop_queue(dev); 1739 netif_stop_queue(dev);
1727 netif_carrier_off(dev); 1740 netif_carrier_off(dev);
1741
1742 for (i = 0; i < 8; i++) {
1743 struct tx_queue *txq = mp->txq + i;
1744
1745 if (mp->txq_mask & (1 << i)) {
1746 txq_reclaim(txq, 1);
1747 txq_reset_hw_ptr(txq);
1748 }
1749 }
1728 } 1750 }
1729 } 1751 }
1730 1752
@@ -1762,9 +1784,11 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
1762 * Enough space again in the primary TX queue for a 1784 * Enough space again in the primary TX queue for a
1763 * full packet? 1785 * full packet?
1764 */ 1786 */
1765 spin_lock(&mp->lock); 1787 if (netif_carrier_ok(dev)) {
1766 __txq_maybe_wake(mp->txq + mp->txq_primary); 1788 spin_lock(&mp->lock);
1767 spin_unlock(&mp->lock); 1789 __txq_maybe_wake(mp->txq + mp->txq_primary);
1790 spin_unlock(&mp->lock);
1791 }
1768 } 1792 }
1769 1793
1770 /* 1794 /*
@@ -1851,16 +1875,11 @@ static void port_start(struct mv643xx_eth_private *mp)
1851 tx_set_rate(mp, 1000000000, 16777216); 1875 tx_set_rate(mp, 1000000000, 16777216);
1852 for (i = 0; i < 8; i++) { 1876 for (i = 0; i < 8; i++) {
1853 struct tx_queue *txq = mp->txq + i; 1877 struct tx_queue *txq = mp->txq + i;
1854 int off = TXQ_CURRENT_DESC_PTR(mp->port_num, i);
1855 u32 addr;
1856 1878
1857 if ((mp->txq_mask & (1 << i)) == 0) 1879 if ((mp->txq_mask & (1 << i)) == 0)
1858 continue; 1880 continue;
1859 1881
1860 addr = (u32)txq->tx_desc_dma; 1882 txq_reset_hw_ptr(txq);
1861 addr += txq->tx_curr_desc * sizeof(struct tx_desc);
1862 wrl(mp, off, addr);
1863
1864 txq_set_rate(txq, 1000000000, 16777216); 1883 txq_set_rate(txq, 1000000000, 16777216);
1865 txq_set_fixed_prio_mode(txq); 1884 txq_set_fixed_prio_mode(txq);
1866 } 1885 }