aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike McCormack <mikem@ring3k.org>2009-08-14 01:15:12 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-14 18:29:55 -0400
commit9b289c3374d2891aac6c12de58e49a16cfbcb6b1 (patch)
tree78943955fe3f116c8d33577d2a77a9fd51ee7dfa /drivers
parenta8519de4a030d130e0d18147a2af3112b7951e0b (diff)
sky2: Avoid rewinding sky2->tx_prod
Keep sky2->tx_prod consistent since int might be examined by an softirq poll or restart. Signed-off-by: Mike McCormack <mikem@ring3k.org> Acked-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sky2.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 1415a8375093..a52b86317837 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -989,11 +989,11 @@ static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
989 sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL)); 989 sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL));
990} 990}
991 991
992static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2) 992static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot)
993{ 993{
994 struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod; 994 struct sky2_tx_le *le = sky2->tx_le + *slot;
995 995
996 sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE); 996 *slot = RING_NEXT(*slot, TX_RING_SIZE);
997 le->ctrl = 0; 997 le->ctrl = 0;
998 return le; 998 return le;
999} 999}
@@ -1006,7 +1006,7 @@ static void tx_init(struct sky2_port *sky2)
1006 sky2->tx_tcpsum = 0; 1006 sky2->tx_tcpsum = 0;
1007 sky2->tx_last_mss = 0; 1007 sky2->tx_last_mss = 0;
1008 1008
1009 le = get_tx_le(sky2); 1009 le = get_tx_le(sky2, &sky2->tx_prod);
1010 le->addr = 0; 1010 le->addr = 0;
1011 le->opcode = OP_ADDR64 | HW_OWNER; 1011 le->opcode = OP_ADDR64 | HW_OWNER;
1012} 1012}
@@ -1572,7 +1572,8 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1572 struct sky2_hw *hw = sky2->hw; 1572 struct sky2_hw *hw = sky2->hw;
1573 struct sky2_tx_le *le = NULL; 1573 struct sky2_tx_le *le = NULL;
1574 struct tx_ring_info *re; 1574 struct tx_ring_info *re;
1575 unsigned i, len, first_slot; 1575 unsigned i, len;
1576 u16 slot;
1576 dma_addr_t mapping; 1577 dma_addr_t mapping;
1577 u16 mss; 1578 u16 mss;
1578 u8 ctrl; 1579 u8 ctrl;
@@ -1586,14 +1587,14 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1586 if (pci_dma_mapping_error(hw->pdev, mapping)) 1587 if (pci_dma_mapping_error(hw->pdev, mapping))
1587 goto mapping_error; 1588 goto mapping_error;
1588 1589
1589 first_slot = sky2->tx_prod; 1590 slot = sky2->tx_prod;
1590 if (unlikely(netif_msg_tx_queued(sky2))) 1591 if (unlikely(netif_msg_tx_queued(sky2)))
1591 printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n", 1592 printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
1592 dev->name, first_slot, skb->len); 1593 dev->name, slot, skb->len);
1593 1594
1594 /* Send high bits if needed */ 1595 /* Send high bits if needed */
1595 if (sizeof(dma_addr_t) > sizeof(u32)) { 1596 if (sizeof(dma_addr_t) > sizeof(u32)) {
1596 le = get_tx_le(sky2); 1597 le = get_tx_le(sky2, &slot);
1597 le->addr = cpu_to_le32(upper_32_bits(mapping)); 1598 le->addr = cpu_to_le32(upper_32_bits(mapping));
1598 le->opcode = OP_ADDR64 | HW_OWNER; 1599 le->opcode = OP_ADDR64 | HW_OWNER;
1599 } 1600 }
@@ -1606,7 +1607,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1606 mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); 1607 mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
1607 1608
1608 if (mss != sky2->tx_last_mss) { 1609 if (mss != sky2->tx_last_mss) {
1609 le = get_tx_le(sky2); 1610 le = get_tx_le(sky2, &slot);
1610 le->addr = cpu_to_le32(mss); 1611 le->addr = cpu_to_le32(mss);
1611 1612
1612 if (hw->flags & SKY2_HW_NEW_LE) 1613 if (hw->flags & SKY2_HW_NEW_LE)
@@ -1622,7 +1623,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1622 /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */ 1623 /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
1623 if (sky2->vlgrp && vlan_tx_tag_present(skb)) { 1624 if (sky2->vlgrp && vlan_tx_tag_present(skb)) {
1624 if (!le) { 1625 if (!le) {
1625 le = get_tx_le(sky2); 1626 le = get_tx_le(sky2, &slot);
1626 le->addr = 0; 1627 le->addr = 0;
1627 le->opcode = OP_VLAN|HW_OWNER; 1628 le->opcode = OP_VLAN|HW_OWNER;
1628 } else 1629 } else
@@ -1651,7 +1652,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1651 if (tcpsum != sky2->tx_tcpsum) { 1652 if (tcpsum != sky2->tx_tcpsum) {
1652 sky2->tx_tcpsum = tcpsum; 1653 sky2->tx_tcpsum = tcpsum;
1653 1654
1654 le = get_tx_le(sky2); 1655 le = get_tx_le(sky2, &slot);
1655 le->addr = cpu_to_le32(tcpsum); 1656 le->addr = cpu_to_le32(tcpsum);
1656 le->length = 0; /* initial checksum value */ 1657 le->length = 0; /* initial checksum value */
1657 le->ctrl = 1; /* one packet */ 1658 le->ctrl = 1; /* one packet */
@@ -1660,7 +1661,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1660 } 1661 }
1661 } 1662 }
1662 1663
1663 le = get_tx_le(sky2); 1664 le = get_tx_le(sky2, &slot);
1664 le->addr = cpu_to_le32((u32) mapping); 1665 le->addr = cpu_to_le32((u32) mapping);
1665 le->length = cpu_to_le16(len); 1666 le->length = cpu_to_le16(len);
1666 le->ctrl = ctrl; 1667 le->ctrl = ctrl;
@@ -1681,13 +1682,13 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1681 goto mapping_unwind; 1682 goto mapping_unwind;
1682 1683
1683 if (sizeof(dma_addr_t) > sizeof(u32)) { 1684 if (sizeof(dma_addr_t) > sizeof(u32)) {
1684 le = get_tx_le(sky2); 1685 le = get_tx_le(sky2, &slot);
1685 le->addr = cpu_to_le32(upper_32_bits(mapping)); 1686 le->addr = cpu_to_le32(upper_32_bits(mapping));
1686 le->ctrl = 0; 1687 le->ctrl = 0;
1687 le->opcode = OP_ADDR64 | HW_OWNER; 1688 le->opcode = OP_ADDR64 | HW_OWNER;
1688 } 1689 }
1689 1690
1690 le = get_tx_le(sky2); 1691 le = get_tx_le(sky2, &slot);
1691 le->addr = cpu_to_le32((u32) mapping); 1692 le->addr = cpu_to_le32((u32) mapping);
1692 le->length = cpu_to_le16(frag->size); 1693 le->length = cpu_to_le16(frag->size);
1693 le->ctrl = ctrl; 1694 le->ctrl = ctrl;
@@ -1701,6 +1702,8 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1701 1702
1702 le->ctrl |= EOP; 1703 le->ctrl |= EOP;
1703 1704
1705 sky2->tx_prod = slot;
1706
1704 if (tx_avail(sky2) <= MAX_SKB_TX_LE) 1707 if (tx_avail(sky2) <= MAX_SKB_TX_LE)
1705 netif_stop_queue(dev); 1708 netif_stop_queue(dev);
1706 1709
@@ -1709,7 +1712,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1709 return NETDEV_TX_OK; 1712 return NETDEV_TX_OK;
1710 1713
1711mapping_unwind: 1714mapping_unwind:
1712 for (i = first_slot; i != sky2->tx_prod; i = RING_NEXT(i, TX_RING_SIZE)) { 1715 for (i = sky2->tx_prod; i != slot; i = RING_NEXT(i, TX_RING_SIZE)) {
1713 le = sky2->tx_le + i; 1716 le = sky2->tx_le + i;
1714 re = sky2->tx_ring + i; 1717 re = sky2->tx_ring + i;
1715 1718
@@ -1729,7 +1732,6 @@ mapping_unwind:
1729 } 1732 }
1730 } 1733 }
1731 1734
1732 sky2->tx_prod = first_slot;
1733mapping_error: 1735mapping_error:
1734 if (net_ratelimit()) 1736 if (net_ratelimit())
1735 dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name); 1737 dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);