diff options
| -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 | ||
