diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sky2.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index e65689ebe147..d98f28c34e5c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -65,6 +65,7 @@ | |||
65 | #define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) | 65 | #define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) |
66 | #define RX_DEF_PENDING RX_MAX_PENDING | 66 | #define RX_DEF_PENDING RX_MAX_PENDING |
67 | #define RX_SKB_ALIGN 8 | 67 | #define RX_SKB_ALIGN 8 |
68 | #define RX_BUF_WRITE 16 | ||
68 | 69 | ||
69 | #define TX_RING_SIZE 512 | 70 | #define TX_RING_SIZE 512 |
70 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) | 71 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) |
@@ -1390,7 +1391,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1390 | } | 1391 | } |
1391 | 1392 | ||
1392 | sky2->tx_cons = put; | 1393 | sky2->tx_cons = put; |
1393 | if (tx_avail(sky2) > MAX_SKB_TX_LE) | 1394 | if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) |
1394 | netif_wake_queue(dev); | 1395 | netif_wake_queue(dev); |
1395 | } | 1396 | } |
1396 | 1397 | ||
@@ -1889,9 +1890,6 @@ resubmit: | |||
1889 | re->skb->ip_summed = CHECKSUM_NONE; | 1890 | re->skb->ip_summed = CHECKSUM_NONE; |
1890 | sky2_rx_add(sky2, re->mapaddr); | 1891 | sky2_rx_add(sky2, re->mapaddr); |
1891 | 1892 | ||
1892 | /* Tell receiver about new buffers. */ | ||
1893 | sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put); | ||
1894 | |||
1895 | return skb; | 1893 | return skb; |
1896 | 1894 | ||
1897 | oversize: | 1895 | oversize: |
@@ -1938,7 +1936,9 @@ static inline int sky2_more_work(const struct sky2_hw *hw) | |||
1938 | /* Process status response ring */ | 1936 | /* Process status response ring */ |
1939 | static int sky2_status_intr(struct sky2_hw *hw, int to_do) | 1937 | static int sky2_status_intr(struct sky2_hw *hw, int to_do) |
1940 | { | 1938 | { |
1939 | struct sky2_port *sky2; | ||
1941 | int work_done = 0; | 1940 | int work_done = 0; |
1941 | unsigned buf_write[2] = { 0, 0 }; | ||
1942 | u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); | 1942 | u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); |
1943 | 1943 | ||
1944 | rmb(); | 1944 | rmb(); |
@@ -1946,7 +1946,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1946 | while (hw->st_idx != hwidx) { | 1946 | while (hw->st_idx != hwidx) { |
1947 | struct sky2_status_le *le = hw->st_le + hw->st_idx; | 1947 | struct sky2_status_le *le = hw->st_le + hw->st_idx; |
1948 | struct net_device *dev; | 1948 | struct net_device *dev; |
1949 | struct sky2_port *sky2; | ||
1950 | struct sk_buff *skb; | 1949 | struct sk_buff *skb; |
1951 | u32 status; | 1950 | u32 status; |
1952 | u16 length; | 1951 | u16 length; |
@@ -1979,6 +1978,14 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1979 | #endif | 1978 | #endif |
1980 | netif_receive_skb(skb); | 1979 | netif_receive_skb(skb); |
1981 | 1980 | ||
1981 | /* Update receiver after 16 frames */ | ||
1982 | if (++buf_write[le->link] == RX_BUF_WRITE) { | ||
1983 | sky2_put_idx(hw, rxqaddr[le->link], | ||
1984 | sky2->rx_put); | ||
1985 | buf_write[le->link] = 0; | ||
1986 | } | ||
1987 | |||
1988 | /* Stop after net poll weight */ | ||
1982 | if (++work_done >= to_do) | 1989 | if (++work_done >= to_do) |
1983 | goto exit_loop; | 1990 | goto exit_loop; |
1984 | break; | 1991 | break; |
@@ -2017,6 +2024,16 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
2017 | } | 2024 | } |
2018 | 2025 | ||
2019 | exit_loop: | 2026 | exit_loop: |
2027 | if (buf_write[0]) { | ||
2028 | sky2 = netdev_priv(hw->dev[0]); | ||
2029 | sky2_put_idx(hw, Q_R1, sky2->rx_put); | ||
2030 | } | ||
2031 | |||
2032 | if (buf_write[1]) { | ||
2033 | sky2 = netdev_priv(hw->dev[1]); | ||
2034 | sky2_put_idx(hw, Q_R2, sky2->rx_put); | ||
2035 | } | ||
2036 | |||
2020 | return work_done; | 2037 | return work_done; |
2021 | } | 2038 | } |
2022 | 2039 | ||