diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 418f169a6a31..933e87f1cc68 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include "sky2.h" | 50 | #include "sky2.h" |
51 | 51 | ||
52 | #define DRV_NAME "sky2" | 52 | #define DRV_NAME "sky2" |
53 | #define DRV_VERSION "1.4" | 53 | #define DRV_VERSION "1.5" |
54 | #define PFX DRV_NAME " " | 54 | #define PFX DRV_NAME " " |
55 | 55 | ||
56 | /* | 56 | /* |
@@ -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) |
@@ -232,9 +233,10 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
232 | if (hw->ports > 1) | 233 | if (hw->ports > 1) |
233 | reg1 |= PCI_Y2_PHY2_COMA; | 234 | reg1 |= PCI_Y2_PHY2_COMA; |
234 | } | 235 | } |
236 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
237 | udelay(100); | ||
235 | 238 | ||
236 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | 239 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { |
237 | sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON); | ||
238 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | 240 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
239 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); | 241 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); |
240 | reg1 &= P_ASPM_CONTROL_MSK; | 242 | reg1 &= P_ASPM_CONTROL_MSK; |
@@ -242,8 +244,6 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
242 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); | 244 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); |
243 | } | 245 | } |
244 | 246 | ||
245 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
246 | |||
247 | break; | 247 | break; |
248 | 248 | ||
249 | case PCI_D3hot: | 249 | case PCI_D3hot: |
@@ -255,6 +255,7 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
255 | else | 255 | else |
256 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | 256 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
257 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | 257 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
258 | udelay(100); | ||
258 | 259 | ||
259 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 260 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
260 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 261 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
@@ -1159,7 +1160,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) | |||
1159 | count = sizeof(dma_addr_t) / sizeof(u32); | 1160 | count = sizeof(dma_addr_t) / sizeof(u32); |
1160 | count += skb_shinfo(skb)->nr_frags * count; | 1161 | count += skb_shinfo(skb)->nr_frags * count; |
1161 | 1162 | ||
1162 | if (skb_shinfo(skb)->gso_size) | 1163 | if (skb_is_gso(skb)) |
1163 | ++count; | 1164 | ++count; |
1164 | 1165 | ||
1165 | if (skb->ip_summed == CHECKSUM_HW) | 1166 | if (skb->ip_summed == CHECKSUM_HW) |
@@ -1389,7 +1390,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1389 | } | 1390 | } |
1390 | 1391 | ||
1391 | sky2->tx_cons = put; | 1392 | sky2->tx_cons = put; |
1392 | if (tx_avail(sky2) > MAX_SKB_TX_LE) | 1393 | if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) |
1393 | netif_wake_queue(dev); | 1394 | netif_wake_queue(dev); |
1394 | } | 1395 | } |
1395 | 1396 | ||
@@ -1888,9 +1889,6 @@ resubmit: | |||
1888 | re->skb->ip_summed = CHECKSUM_NONE; | 1889 | re->skb->ip_summed = CHECKSUM_NONE; |
1889 | sky2_rx_add(sky2, re->mapaddr); | 1890 | sky2_rx_add(sky2, re->mapaddr); |
1890 | 1891 | ||
1891 | /* Tell receiver about new buffers. */ | ||
1892 | sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put); | ||
1893 | |||
1894 | return skb; | 1892 | return skb; |
1895 | 1893 | ||
1896 | oversize: | 1894 | oversize: |
@@ -1937,7 +1935,9 @@ static inline int sky2_more_work(const struct sky2_hw *hw) | |||
1937 | /* Process status response ring */ | 1935 | /* Process status response ring */ |
1938 | static int sky2_status_intr(struct sky2_hw *hw, int to_do) | 1936 | static int sky2_status_intr(struct sky2_hw *hw, int to_do) |
1939 | { | 1937 | { |
1938 | struct sky2_port *sky2; | ||
1940 | int work_done = 0; | 1939 | int work_done = 0; |
1940 | unsigned buf_write[2] = { 0, 0 }; | ||
1941 | u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); | 1941 | u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); |
1942 | 1942 | ||
1943 | rmb(); | 1943 | rmb(); |
@@ -1945,7 +1945,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1945 | while (hw->st_idx != hwidx) { | 1945 | while (hw->st_idx != hwidx) { |
1946 | struct sky2_status_le *le = hw->st_le + hw->st_idx; | 1946 | struct sky2_status_le *le = hw->st_le + hw->st_idx; |
1947 | struct net_device *dev; | 1947 | struct net_device *dev; |
1948 | struct sky2_port *sky2; | ||
1949 | struct sk_buff *skb; | 1948 | struct sk_buff *skb; |
1950 | u32 status; | 1949 | u32 status; |
1951 | u16 length; | 1950 | u16 length; |
@@ -1978,6 +1977,14 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1978 | #endif | 1977 | #endif |
1979 | netif_receive_skb(skb); | 1978 | netif_receive_skb(skb); |
1980 | 1979 | ||
1980 | /* Update receiver after 16 frames */ | ||
1981 | if (++buf_write[le->link] == RX_BUF_WRITE) { | ||
1982 | sky2_put_idx(hw, rxqaddr[le->link], | ||
1983 | sky2->rx_put); | ||
1984 | buf_write[le->link] = 0; | ||
1985 | } | ||
1986 | |||
1987 | /* Stop after net poll weight */ | ||
1981 | if (++work_done >= to_do) | 1988 | if (++work_done >= to_do) |
1982 | goto exit_loop; | 1989 | goto exit_loop; |
1983 | break; | 1990 | break; |
@@ -2016,6 +2023,16 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
2016 | } | 2023 | } |
2017 | 2024 | ||
2018 | exit_loop: | 2025 | exit_loop: |
2026 | if (buf_write[0]) { | ||
2027 | sky2 = netdev_priv(hw->dev[0]); | ||
2028 | sky2_put_idx(hw, Q_R1, sky2->rx_put); | ||
2029 | } | ||
2030 | |||
2031 | if (buf_write[1]) { | ||
2032 | sky2 = netdev_priv(hw->dev[1]); | ||
2033 | sky2_put_idx(hw, Q_R2, sky2->rx_put); | ||
2034 | } | ||
2035 | |||
2019 | return work_done; | 2036 | return work_done; |
2020 | } | 2037 | } |
2021 | 2038 | ||
@@ -2186,9 +2203,6 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2186 | int work_done = 0; | 2203 | int work_done = 0; |
2187 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); | 2204 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); |
2188 | 2205 | ||
2189 | if (!~status) | ||
2190 | goto out; | ||
2191 | |||
2192 | if (status & Y2_IS_HW_ERR) | 2206 | if (status & Y2_IS_HW_ERR) |
2193 | sky2_hw_intr(hw); | 2207 | sky2_hw_intr(hw); |
2194 | 2208 | ||
@@ -2225,7 +2239,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2225 | 2239 | ||
2226 | if (sky2_more_work(hw)) | 2240 | if (sky2_more_work(hw)) |
2227 | return 1; | 2241 | return 1; |
2228 | out: | 2242 | |
2229 | netif_rx_complete(dev0); | 2243 | netif_rx_complete(dev0); |
2230 | 2244 | ||
2231 | sky2_read32(hw, B0_Y2_SP_LISR); | 2245 | sky2_read32(hw, B0_Y2_SP_LISR); |
@@ -2286,7 +2300,7 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) | |||
2286 | } | 2300 | } |
2287 | 2301 | ||
2288 | 2302 | ||
2289 | static int __devinit sky2_reset(struct sky2_hw *hw) | 2303 | static int sky2_reset(struct sky2_hw *hw) |
2290 | { | 2304 | { |
2291 | u16 status; | 2305 | u16 status; |
2292 | u8 t8, pmd_type; | 2306 | u8 t8, pmd_type; |
@@ -3437,17 +3451,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3437 | return -EINVAL; | 3451 | return -EINVAL; |
3438 | 3452 | ||
3439 | del_timer_sync(&hw->idle_timer); | 3453 | del_timer_sync(&hw->idle_timer); |
3454 | netif_poll_disable(hw->dev[0]); | ||
3440 | 3455 | ||
3441 | for (i = 0; i < hw->ports; i++) { | 3456 | for (i = 0; i < hw->ports; i++) { |
3442 | struct net_device *dev = hw->dev[i]; | 3457 | struct net_device *dev = hw->dev[i]; |
3443 | 3458 | ||
3444 | if (dev) { | 3459 | if (netif_running(dev)) { |
3445 | if (!netif_running(dev)) | ||
3446 | continue; | ||
3447 | |||
3448 | sky2_down(dev); | 3460 | sky2_down(dev); |
3449 | netif_device_detach(dev); | 3461 | netif_device_detach(dev); |
3450 | netif_poll_disable(dev); | ||
3451 | } | 3462 | } |
3452 | } | 3463 | } |
3453 | 3464 | ||
@@ -3474,9 +3485,8 @@ static int sky2_resume(struct pci_dev *pdev) | |||
3474 | 3485 | ||
3475 | for (i = 0; i < hw->ports; i++) { | 3486 | for (i = 0; i < hw->ports; i++) { |
3476 | struct net_device *dev = hw->dev[i]; | 3487 | struct net_device *dev = hw->dev[i]; |
3477 | if (dev && netif_running(dev)) { | 3488 | if (netif_running(dev)) { |
3478 | netif_device_attach(dev); | 3489 | netif_device_attach(dev); |
3479 | netif_poll_enable(dev); | ||
3480 | 3490 | ||
3481 | err = sky2_up(dev); | 3491 | err = sky2_up(dev); |
3482 | if (err) { | 3492 | if (err) { |
@@ -3488,6 +3498,7 @@ static int sky2_resume(struct pci_dev *pdev) | |||
3488 | } | 3498 | } |
3489 | } | 3499 | } |
3490 | 3500 | ||
3501 | netif_poll_enable(hw->dev[0]); | ||
3491 | sky2_idle_start(hw); | 3502 | sky2_idle_start(hw); |
3492 | out: | 3503 | out: |
3493 | return err; | 3504 | return err; |