diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 58d35214d12d..7c1880d8b31f 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -64,10 +64,12 @@ | |||
64 | #define RX_MAX_PENDING (RX_LE_SIZE/6 - 2) | 64 | #define RX_MAX_PENDING (RX_LE_SIZE/6 - 2) |
65 | #define RX_DEF_PENDING RX_MAX_PENDING | 65 | #define RX_DEF_PENDING RX_MAX_PENDING |
66 | 66 | ||
67 | #define TX_RING_SIZE 512 | 67 | /* This is the worst case number of transmit list elements for a single skb: |
68 | #define TX_DEF_PENDING 128 | 68 | VLAN + TSO + CKSUM + Data + skb_frags * DMA */ |
69 | #define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) | 69 | #define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) |
70 | #define TX_MIN_PENDING (MAX_SKB_TX_LE+1) | 70 | #define TX_MIN_PENDING (MAX_SKB_TX_LE+1) |
71 | #define TX_MAX_PENDING 4096 | ||
72 | #define TX_DEF_PENDING 127 | ||
71 | 73 | ||
72 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ | 74 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ |
73 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) | 75 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) |
@@ -1000,7 +1002,7 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot) | |||
1000 | { | 1002 | { |
1001 | struct sky2_tx_le *le = sky2->tx_le + *slot; | 1003 | struct sky2_tx_le *le = sky2->tx_le + *slot; |
1002 | 1004 | ||
1003 | *slot = RING_NEXT(*slot, TX_RING_SIZE); | 1005 | *slot = RING_NEXT(*slot, sky2->tx_ring_size); |
1004 | le->ctrl = 0; | 1006 | le->ctrl = 0; |
1005 | return le; | 1007 | return le; |
1006 | } | 1008 | } |
@@ -1433,13 +1435,13 @@ static int sky2_up(struct net_device *dev) | |||
1433 | 1435 | ||
1434 | /* must be power of 2 */ | 1436 | /* must be power of 2 */ |
1435 | sky2->tx_le = pci_alloc_consistent(hw->pdev, | 1437 | sky2->tx_le = pci_alloc_consistent(hw->pdev, |
1436 | TX_RING_SIZE * | 1438 | sky2->tx_ring_size * |
1437 | sizeof(struct sky2_tx_le), | 1439 | sizeof(struct sky2_tx_le), |
1438 | &sky2->tx_le_map); | 1440 | &sky2->tx_le_map); |
1439 | if (!sky2->tx_le) | 1441 | if (!sky2->tx_le) |
1440 | goto err_out; | 1442 | goto err_out; |
1441 | 1443 | ||
1442 | sky2->tx_ring = kcalloc(TX_RING_SIZE, sizeof(struct tx_ring_info), | 1444 | sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info), |
1443 | GFP_KERNEL); | 1445 | GFP_KERNEL); |
1444 | if (!sky2->tx_ring) | 1446 | if (!sky2->tx_ring) |
1445 | goto err_out; | 1447 | goto err_out; |
@@ -1491,7 +1493,7 @@ static int sky2_up(struct net_device *dev) | |||
1491 | sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV); | 1493 | sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV); |
1492 | 1494 | ||
1493 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | 1495 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1494 | TX_RING_SIZE - 1); | 1496 | sky2->tx_ring_size - 1); |
1495 | 1497 | ||
1496 | #ifdef SKY2_VLAN_TAG_USED | 1498 | #ifdef SKY2_VLAN_TAG_USED |
1497 | sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL); | 1499 | sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL); |
@@ -1520,7 +1522,7 @@ err_out: | |||
1520 | } | 1522 | } |
1521 | if (sky2->tx_le) { | 1523 | if (sky2->tx_le) { |
1522 | pci_free_consistent(hw->pdev, | 1524 | pci_free_consistent(hw->pdev, |
1523 | TX_RING_SIZE * sizeof(struct sky2_tx_le), | 1525 | sky2->tx_ring_size * sizeof(struct sky2_tx_le), |
1524 | sky2->tx_le, sky2->tx_le_map); | 1526 | sky2->tx_le, sky2->tx_le_map); |
1525 | sky2->tx_le = NULL; | 1527 | sky2->tx_le = NULL; |
1526 | } | 1528 | } |
@@ -1533,15 +1535,15 @@ err_out: | |||
1533 | } | 1535 | } |
1534 | 1536 | ||
1535 | /* Modular subtraction in ring */ | 1537 | /* Modular subtraction in ring */ |
1536 | static inline int tx_dist(unsigned tail, unsigned head) | 1538 | static inline int tx_inuse(const struct sky2_port *sky2) |
1537 | { | 1539 | { |
1538 | return (head - tail) & (TX_RING_SIZE - 1); | 1540 | return (sky2->tx_prod - sky2->tx_cons) & (sky2->tx_ring_size - 1); |
1539 | } | 1541 | } |
1540 | 1542 | ||
1541 | /* Number of list elements available for next tx */ | 1543 | /* Number of list elements available for next tx */ |
1542 | static inline int tx_avail(const struct sky2_port *sky2) | 1544 | static inline int tx_avail(const struct sky2_port *sky2) |
1543 | { | 1545 | { |
1544 | return sky2->tx_pending - tx_dist(sky2->tx_cons, sky2->tx_prod); | 1546 | return sky2->tx_pending - tx_inuse(sky2); |
1545 | } | 1547 | } |
1546 | 1548 | ||
1547 | /* Estimate of number of transmit list elements required */ | 1549 | /* Estimate of number of transmit list elements required */ |
@@ -1717,7 +1719,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1717 | return NETDEV_TX_OK; | 1719 | return NETDEV_TX_OK; |
1718 | 1720 | ||
1719 | mapping_unwind: | 1721 | mapping_unwind: |
1720 | for (i = sky2->tx_prod; i != slot; i = RING_NEXT(i, TX_RING_SIZE)) { | 1722 | for (i = sky2->tx_prod; i != slot; i = RING_NEXT(i, sky2->tx_ring_size)) { |
1721 | le = sky2->tx_le + i; | 1723 | le = sky2->tx_le + i; |
1722 | re = sky2->tx_ring + i; | 1724 | re = sky2->tx_ring + i; |
1723 | 1725 | ||
@@ -1760,10 +1762,10 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1760 | struct pci_dev *pdev = sky2->hw->pdev; | 1762 | struct pci_dev *pdev = sky2->hw->pdev; |
1761 | unsigned idx; | 1763 | unsigned idx; |
1762 | 1764 | ||
1763 | BUG_ON(done >= TX_RING_SIZE); | 1765 | BUG_ON(done >= sky2->tx_ring_size); |
1764 | 1766 | ||
1765 | for (idx = sky2->tx_cons; idx != done; | 1767 | for (idx = sky2->tx_cons; idx != done; |
1766 | idx = RING_NEXT(idx, TX_RING_SIZE)) { | 1768 | idx = RING_NEXT(idx, sky2->tx_ring_size)) { |
1767 | struct sky2_tx_le *le = sky2->tx_le + idx; | 1769 | struct sky2_tx_le *le = sky2->tx_le + idx; |
1768 | struct tx_ring_info *re = sky2->tx_ring + idx; | 1770 | struct tx_ring_info *re = sky2->tx_ring + idx; |
1769 | 1771 | ||
@@ -1799,7 +1801,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1799 | else | 1801 | else |
1800 | dev_kfree_skb_any(skb); | 1802 | dev_kfree_skb_any(skb); |
1801 | 1803 | ||
1802 | sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE); | 1804 | sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size); |
1803 | } | 1805 | } |
1804 | } | 1806 | } |
1805 | 1807 | ||
@@ -1907,7 +1909,7 @@ static int sky2_down(struct net_device *dev) | |||
1907 | kfree(sky2->rx_ring); | 1909 | kfree(sky2->rx_ring); |
1908 | 1910 | ||
1909 | pci_free_consistent(hw->pdev, | 1911 | pci_free_consistent(hw->pdev, |
1910 | TX_RING_SIZE * sizeof(struct sky2_tx_le), | 1912 | sky2->tx_ring_size * sizeof(struct sky2_tx_le), |
1911 | sky2->tx_le, sky2->tx_le_map); | 1913 | sky2->tx_le, sky2->tx_le_map); |
1912 | kfree(sky2->tx_ring); | 1914 | kfree(sky2->tx_ring); |
1913 | 1915 | ||
@@ -2517,7 +2519,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2517 | 2519 | ||
2518 | case OP_TXINDEXLE: | 2520 | case OP_TXINDEXLE: |
2519 | /* TX index reports status for both ports */ | 2521 | /* TX index reports status for both ports */ |
2520 | BUILD_BUG_ON(TX_RING_SIZE > 0x1000); | ||
2521 | sky2_tx_done(hw->dev[0], status & 0xfff); | 2522 | sky2_tx_done(hw->dev[0], status & 0xfff); |
2522 | if (hw->dev[1]) | 2523 | if (hw->dev[1]) |
2523 | sky2_tx_done(hw->dev[1], | 2524 | sky2_tx_done(hw->dev[1], |
@@ -3669,7 +3670,7 @@ static int sky2_set_coalesce(struct net_device *dev, | |||
3669 | ecmd->rx_coalesce_usecs_irq > tmax) | 3670 | ecmd->rx_coalesce_usecs_irq > tmax) |
3670 | return -EINVAL; | 3671 | return -EINVAL; |
3671 | 3672 | ||
3672 | if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1) | 3673 | if (ecmd->tx_max_coalesced_frames >= sky2->tx_ring_size-1) |
3673 | return -EINVAL; | 3674 | return -EINVAL; |
3674 | if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING) | 3675 | if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING) |
3675 | return -EINVAL; | 3676 | return -EINVAL; |
@@ -3713,7 +3714,7 @@ static void sky2_get_ringparam(struct net_device *dev, | |||
3713 | ering->rx_max_pending = RX_MAX_PENDING; | 3714 | ering->rx_max_pending = RX_MAX_PENDING; |
3714 | ering->rx_mini_max_pending = 0; | 3715 | ering->rx_mini_max_pending = 0; |
3715 | ering->rx_jumbo_max_pending = 0; | 3716 | ering->rx_jumbo_max_pending = 0; |
3716 | ering->tx_max_pending = TX_RING_SIZE - 1; | 3717 | ering->tx_max_pending = TX_MAX_PENDING; |
3717 | 3718 | ||
3718 | ering->rx_pending = sky2->rx_pending; | 3719 | ering->rx_pending = sky2->rx_pending; |
3719 | ering->rx_mini_pending = 0; | 3720 | ering->rx_mini_pending = 0; |
@@ -3728,14 +3729,15 @@ static int sky2_set_ringparam(struct net_device *dev, | |||
3728 | 3729 | ||
3729 | if (ering->rx_pending > RX_MAX_PENDING || | 3730 | if (ering->rx_pending > RX_MAX_PENDING || |
3730 | ering->rx_pending < 8 || | 3731 | ering->rx_pending < 8 || |
3731 | ering->tx_pending < MAX_SKB_TX_LE || | 3732 | ering->tx_pending < TX_MIN_PENDING || |
3732 | ering->tx_pending > TX_RING_SIZE - 1) | 3733 | ering->tx_pending > TX_MAX_PENDING) |
3733 | return -EINVAL; | 3734 | return -EINVAL; |
3734 | 3735 | ||
3735 | sky2_detach(dev); | 3736 | sky2_detach(dev); |
3736 | 3737 | ||
3737 | sky2->rx_pending = ering->rx_pending; | 3738 | sky2->rx_pending = ering->rx_pending; |
3738 | sky2->tx_pending = ering->tx_pending; | 3739 | sky2->tx_pending = ering->tx_pending; |
3740 | sky2->tx_ring_size = roundup_pow_of_two(sky2->tx_pending+1); | ||
3739 | 3741 | ||
3740 | return sky2_reattach(dev); | 3742 | return sky2_reattach(dev); |
3741 | } | 3743 | } |
@@ -4105,8 +4107,8 @@ static int sky2_debug_show(struct seq_file *seq, void *v) | |||
4105 | 4107 | ||
4106 | /* Dump contents of tx ring */ | 4108 | /* Dump contents of tx ring */ |
4107 | sop = 1; | 4109 | sop = 1; |
4108 | for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < TX_RING_SIZE; | 4110 | for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < sky2->tx_ring_size; |
4109 | idx = RING_NEXT(idx, TX_RING_SIZE)) { | 4111 | idx = RING_NEXT(idx, sky2->tx_ring_size)) { |
4110 | const struct sky2_tx_le *le = sky2->tx_le + idx; | 4112 | const struct sky2_tx_le *le = sky2->tx_le + idx; |
4111 | u32 a = le32_to_cpu(le->addr); | 4113 | u32 a = le32_to_cpu(le->addr); |
4112 | 4114 | ||
@@ -4315,7 +4317,9 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
4315 | sky2->wol = wol; | 4317 | sky2->wol = wol; |
4316 | 4318 | ||
4317 | spin_lock_init(&sky2->phy_lock); | 4319 | spin_lock_init(&sky2->phy_lock); |
4320 | |||
4318 | sky2->tx_pending = TX_DEF_PENDING; | 4321 | sky2->tx_pending = TX_DEF_PENDING; |
4322 | sky2->tx_ring_size = roundup_pow_of_two(TX_DEF_PENDING+1); | ||
4319 | sky2->rx_pending = RX_DEF_PENDING; | 4323 | sky2->rx_pending = RX_DEF_PENDING; |
4320 | 4324 | ||
4321 | hw->dev[port] = dev; | 4325 | hw->dev[port] = dev; |