diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 418f169a6a31..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) |
@@ -234,7 +235,6 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
234 | } | 235 | } |
235 | 236 | ||
236 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | 237 | 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); | 238 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
239 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); | 239 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); |
240 | reg1 &= P_ASPM_CONTROL_MSK; | 240 | reg1 &= P_ASPM_CONTROL_MSK; |
@@ -243,6 +243,7 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | 245 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
246 | udelay(100); | ||
246 | 247 | ||
247 | break; | 248 | break; |
248 | 249 | ||
@@ -255,6 +256,7 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
255 | else | 256 | else |
256 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | 257 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
257 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | 258 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
259 | udelay(100); | ||
258 | 260 | ||
259 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 261 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
260 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 262 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
@@ -1159,7 +1161,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) | |||
1159 | count = sizeof(dma_addr_t) / sizeof(u32); | 1161 | count = sizeof(dma_addr_t) / sizeof(u32); |
1160 | count += skb_shinfo(skb)->nr_frags * count; | 1162 | count += skb_shinfo(skb)->nr_frags * count; |
1161 | 1163 | ||
1162 | if (skb_shinfo(skb)->gso_size) | 1164 | if (skb_is_gso(skb)) |
1163 | ++count; | 1165 | ++count; |
1164 | 1166 | ||
1165 | if (skb->ip_summed == CHECKSUM_HW) | 1167 | if (skb->ip_summed == CHECKSUM_HW) |
@@ -1389,7 +1391,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1389 | } | 1391 | } |
1390 | 1392 | ||
1391 | sky2->tx_cons = put; | 1393 | sky2->tx_cons = put; |
1392 | if (tx_avail(sky2) > MAX_SKB_TX_LE) | 1394 | if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) |
1393 | netif_wake_queue(dev); | 1395 | netif_wake_queue(dev); |
1394 | } | 1396 | } |
1395 | 1397 | ||
@@ -1888,9 +1890,6 @@ resubmit: | |||
1888 | re->skb->ip_summed = CHECKSUM_NONE; | 1890 | re->skb->ip_summed = CHECKSUM_NONE; |
1889 | sky2_rx_add(sky2, re->mapaddr); | 1891 | sky2_rx_add(sky2, re->mapaddr); |
1890 | 1892 | ||
1891 | /* Tell receiver about new buffers. */ | ||
1892 | sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put); | ||
1893 | |||
1894 | return skb; | 1893 | return skb; |
1895 | 1894 | ||
1896 | oversize: | 1895 | oversize: |
@@ -1937,7 +1936,9 @@ static inline int sky2_more_work(const struct sky2_hw *hw) | |||
1937 | /* Process status response ring */ | 1936 | /* Process status response ring */ |
1938 | 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) |
1939 | { | 1938 | { |
1939 | struct sky2_port *sky2; | ||
1940 | int work_done = 0; | 1940 | int work_done = 0; |
1941 | unsigned buf_write[2] = { 0, 0 }; | ||
1941 | u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); | 1942 | u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); |
1942 | 1943 | ||
1943 | rmb(); | 1944 | rmb(); |
@@ -1945,7 +1946,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1945 | while (hw->st_idx != hwidx) { | 1946 | while (hw->st_idx != hwidx) { |
1946 | struct sky2_status_le *le = hw->st_le + hw->st_idx; | 1947 | struct sky2_status_le *le = hw->st_le + hw->st_idx; |
1947 | struct net_device *dev; | 1948 | struct net_device *dev; |
1948 | struct sky2_port *sky2; | ||
1949 | struct sk_buff *skb; | 1949 | struct sk_buff *skb; |
1950 | u32 status; | 1950 | u32 status; |
1951 | u16 length; | 1951 | u16 length; |
@@ -1978,6 +1978,14 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1978 | #endif | 1978 | #endif |
1979 | netif_receive_skb(skb); | 1979 | netif_receive_skb(skb); |
1980 | 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 */ | ||
1981 | if (++work_done >= to_do) | 1989 | if (++work_done >= to_do) |
1982 | goto exit_loop; | 1990 | goto exit_loop; |
1983 | break; | 1991 | break; |
@@ -2016,6 +2024,16 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
2016 | } | 2024 | } |
2017 | 2025 | ||
2018 | 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 | |||
2019 | return work_done; | 2037 | return work_done; |
2020 | } | 2038 | } |
2021 | 2039 | ||
@@ -2286,7 +2304,7 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) | |||
2286 | } | 2304 | } |
2287 | 2305 | ||
2288 | 2306 | ||
2289 | static int __devinit sky2_reset(struct sky2_hw *hw) | 2307 | static int sky2_reset(struct sky2_hw *hw) |
2290 | { | 2308 | { |
2291 | u16 status; | 2309 | u16 status; |
2292 | u8 t8, pmd_type; | 2310 | u8 t8, pmd_type; |
@@ -3437,17 +3455,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3437 | return -EINVAL; | 3455 | return -EINVAL; |
3438 | 3456 | ||
3439 | del_timer_sync(&hw->idle_timer); | 3457 | del_timer_sync(&hw->idle_timer); |
3458 | netif_poll_disable(hw->dev[0]); | ||
3440 | 3459 | ||
3441 | for (i = 0; i < hw->ports; i++) { | 3460 | for (i = 0; i < hw->ports; i++) { |
3442 | struct net_device *dev = hw->dev[i]; | 3461 | struct net_device *dev = hw->dev[i]; |
3443 | 3462 | ||
3444 | if (dev) { | 3463 | if (netif_running(dev)) { |
3445 | if (!netif_running(dev)) | ||
3446 | continue; | ||
3447 | |||
3448 | sky2_down(dev); | 3464 | sky2_down(dev); |
3449 | netif_device_detach(dev); | 3465 | netif_device_detach(dev); |
3450 | netif_poll_disable(dev); | ||
3451 | } | 3466 | } |
3452 | } | 3467 | } |
3453 | 3468 | ||
@@ -3474,9 +3489,8 @@ static int sky2_resume(struct pci_dev *pdev) | |||
3474 | 3489 | ||
3475 | for (i = 0; i < hw->ports; i++) { | 3490 | for (i = 0; i < hw->ports; i++) { |
3476 | struct net_device *dev = hw->dev[i]; | 3491 | struct net_device *dev = hw->dev[i]; |
3477 | if (dev && netif_running(dev)) { | 3492 | if (netif_running(dev)) { |
3478 | netif_device_attach(dev); | 3493 | netif_device_attach(dev); |
3479 | netif_poll_enable(dev); | ||
3480 | 3494 | ||
3481 | err = sky2_up(dev); | 3495 | err = sky2_up(dev); |
3482 | if (err) { | 3496 | if (err) { |
@@ -3488,6 +3502,7 @@ static int sky2_resume(struct pci_dev *pdev) | |||
3488 | } | 3502 | } |
3489 | } | 3503 | } |
3490 | 3504 | ||
3505 | netif_poll_enable(hw->dev[0]); | ||
3491 | sky2_idle_start(hw); | 3506 | sky2_idle_start(hw); |
3492 | out: | 3507 | out: |
3493 | return err; | 3508 | return err; |