diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-21 11:52:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-21 11:52:18 -0500 |
commit | b05005772f34497eb2b7415a651fe785cbe70e16 (patch) | |
tree | b176aeb7fa9baf69e77ddd83e844727490bfcf28 /drivers/net/sky2.c | |
parent | 044f324f6ea5d55391db62fca6a295b2651cb946 (diff) | |
parent | 7705a8792b0fc82fd7d4dd923724606bbfd9fb20 (diff) |
Merge branch 'origin'
Conflicts:
Documentation/video4linux/CARDLIST.cx88
drivers/media/video/cx88/Kconfig
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/saa7134/saa7134-dvb.c
Resolved as in the original merge by Mauro Carvalho Chehab
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 295 |
1 files changed, 194 insertions, 101 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index f8b973a04b65..73260364cba3 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -23,12 +23,6 @@ | |||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | /* | ||
27 | * TOTEST | ||
28 | * - speed setting | ||
29 | * - suspend/resume | ||
30 | */ | ||
31 | |||
32 | #include <linux/config.h> | 26 | #include <linux/config.h> |
33 | #include <linux/crc32.h> | 27 | #include <linux/crc32.h> |
34 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
@@ -57,7 +51,7 @@ | |||
57 | #include "sky2.h" | 51 | #include "sky2.h" |
58 | 52 | ||
59 | #define DRV_NAME "sky2" | 53 | #define DRV_NAME "sky2" |
60 | #define DRV_VERSION "0.13" | 54 | #define DRV_VERSION "0.15" |
61 | #define PFX DRV_NAME " " | 55 | #define PFX DRV_NAME " " |
62 | 56 | ||
63 | /* | 57 | /* |
@@ -80,7 +74,7 @@ | |||
80 | #define TX_RING_SIZE 512 | 74 | #define TX_RING_SIZE 512 |
81 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) | 75 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) |
82 | #define TX_MIN_PENDING 64 | 76 | #define TX_MIN_PENDING 64 |
83 | #define MAX_SKB_TX_LE (4 + 2*MAX_SKB_FRAGS) | 77 | #define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) |
84 | 78 | ||
85 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ | 79 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ |
86 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) | 80 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) |
@@ -197,11 +191,11 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
197 | pr_debug("sky2_set_power_state %d\n", state); | 191 | pr_debug("sky2_set_power_state %d\n", state); |
198 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 192 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
199 | 193 | ||
200 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control); | 194 | power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_PMC); |
201 | vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) && | 195 | vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) && |
202 | (power_control & PCI_PM_CAP_PME_D3cold); | 196 | (power_control & PCI_PM_CAP_PME_D3cold); |
203 | 197 | ||
204 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control); | 198 | power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL); |
205 | 199 | ||
206 | power_control |= PCI_PM_CTRL_PME_STATUS; | 200 | power_control |= PCI_PM_CTRL_PME_STATUS; |
207 | power_control &= ~(PCI_PM_CTRL_STATE_MASK); | 201 | power_control &= ~(PCI_PM_CTRL_STATE_MASK); |
@@ -225,7 +219,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
225 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 219 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
226 | 220 | ||
227 | /* Turn off phy power saving */ | 221 | /* Turn off phy power saving */ |
228 | pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®1); | 222 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
229 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | 223 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
230 | 224 | ||
231 | /* looks like this XL is back asswards .. */ | 225 | /* looks like this XL is back asswards .. */ |
@@ -234,18 +228,28 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
234 | if (hw->ports > 1) | 228 | if (hw->ports > 1) |
235 | reg1 |= PCI_Y2_PHY2_COMA; | 229 | reg1 |= PCI_Y2_PHY2_COMA; |
236 | } | 230 | } |
237 | pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1); | 231 | |
232 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | ||
233 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | ||
234 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); | ||
235 | reg1 &= P_ASPM_CONTROL_MSK; | ||
236 | sky2_pci_write32(hw, PCI_DEV_REG4, reg1); | ||
237 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); | ||
238 | } | ||
239 | |||
240 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
241 | |||
238 | break; | 242 | break; |
239 | 243 | ||
240 | case PCI_D3hot: | 244 | case PCI_D3hot: |
241 | case PCI_D3cold: | 245 | case PCI_D3cold: |
242 | /* Turn on phy power saving */ | 246 | /* Turn on phy power saving */ |
243 | pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®1); | 247 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
244 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 248 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
245 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | 249 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
246 | else | 250 | else |
247 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | 251 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
248 | pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1); | 252 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
249 | 253 | ||
250 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 254 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
251 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 255 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
@@ -267,7 +271,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
267 | ret = -1; | 271 | ret = -1; |
268 | } | 272 | } |
269 | 273 | ||
270 | pci_write_config_byte(hw->pdev, hw->pm_cap + PCI_PM_CTRL, power_control); | 274 | sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control); |
271 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 275 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
272 | return ret; | 276 | return ret; |
273 | } | 277 | } |
@@ -465,16 +469,31 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
465 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); | 469 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); |
466 | } | 470 | } |
467 | 471 | ||
468 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | 472 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { |
473 | /* apply fixes in PHY AFE */ | ||
474 | gm_phy_write(hw, port, 22, 255); | ||
475 | /* increase differential signal amplitude in 10BASE-T */ | ||
476 | gm_phy_write(hw, port, 24, 0xaa99); | ||
477 | gm_phy_write(hw, port, 23, 0x2011); | ||
469 | 478 | ||
470 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { | 479 | /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ |
471 | /* turn on 100 Mbps LED (LED_LINK100) */ | 480 | gm_phy_write(hw, port, 24, 0xa204); |
472 | ledover |= PHY_M_LED_MO_100(MO_LED_ON); | 481 | gm_phy_write(hw, port, 23, 0x2002); |
473 | } | ||
474 | 482 | ||
475 | if (ledover) | 483 | /* set page register to 0 */ |
476 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); | 484 | gm_phy_write(hw, port, 22, 0); |
485 | } else { | ||
486 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | ||
487 | |||
488 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { | ||
489 | /* turn on 100 Mbps LED (LED_LINK100) */ | ||
490 | ledover |= PHY_M_LED_MO_100(MO_LED_ON); | ||
491 | } | ||
492 | |||
493 | if (ledover) | ||
494 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); | ||
477 | 495 | ||
496 | } | ||
478 | /* Enable phy interrupt on auto-negotiation complete (or link up) */ | 497 | /* Enable phy interrupt on auto-negotiation complete (or link up) */ |
479 | if (sky2->autoneg == AUTONEG_ENABLE) | 498 | if (sky2->autoneg == AUTONEG_ENABLE) |
480 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); | 499 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); |
@@ -522,10 +541,16 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
522 | 541 | ||
523 | switch (sky2->speed) { | 542 | switch (sky2->speed) { |
524 | case SPEED_1000: | 543 | case SPEED_1000: |
544 | reg &= ~GM_GPCR_SPEED_100; | ||
525 | reg |= GM_GPCR_SPEED_1000; | 545 | reg |= GM_GPCR_SPEED_1000; |
526 | /* fallthru */ | 546 | break; |
527 | case SPEED_100: | 547 | case SPEED_100: |
548 | reg &= ~GM_GPCR_SPEED_1000; | ||
528 | reg |= GM_GPCR_SPEED_100; | 549 | reg |= GM_GPCR_SPEED_100; |
550 | break; | ||
551 | case SPEED_10: | ||
552 | reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); | ||
553 | break; | ||
529 | } | 554 | } |
530 | 555 | ||
531 | if (sky2->duplex == DUPLEX_FULL) | 556 | if (sky2->duplex == DUPLEX_FULL) |
@@ -597,8 +622,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
597 | 622 | ||
598 | /* Configure Rx MAC FIFO */ | 623 | /* Configure Rx MAC FIFO */ |
599 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 624 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
600 | sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T), | 625 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), |
601 | GMF_RX_CTRL_DEF); | 626 | GMF_OPER_ON | GMF_RX_F_FL_ON); |
602 | 627 | ||
603 | /* Flush Rx MAC FIFO on any flow control or error */ | 628 | /* Flush Rx MAC FIFO on any flow control or error */ |
604 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); | 629 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); |
@@ -949,6 +974,12 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
949 | 974 | ||
950 | sky2->rx_put = sky2->rx_next = 0; | 975 | sky2->rx_put = sky2->rx_next = 0; |
951 | sky2_qset(hw, rxq); | 976 | sky2_qset(hw, rxq); |
977 | |||
978 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { | ||
979 | /* MAC Rx RAM Read is controlled by hardware */ | ||
980 | sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS); | ||
981 | } | ||
982 | |||
952 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); | 983 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); |
953 | 984 | ||
954 | rx_set_checksum(sky2); | 985 | rx_set_checksum(sky2); |
@@ -964,6 +995,10 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
964 | sky2_rx_add(sky2, re->mapaddr); | 995 | sky2_rx_add(sky2, re->mapaddr); |
965 | } | 996 | } |
966 | 997 | ||
998 | /* Truncate oversize frames */ | ||
999 | sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8); | ||
1000 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON); | ||
1001 | |||
967 | /* Tell chip about available buffers */ | 1002 | /* Tell chip about available buffers */ |
968 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); | 1003 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); |
969 | sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX)); | 1004 | sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX)); |
@@ -1031,9 +1066,10 @@ static int sky2_up(struct net_device *dev) | |||
1031 | RB_RST_SET); | 1066 | RB_RST_SET); |
1032 | 1067 | ||
1033 | sky2_qset(hw, txqaddr[port]); | 1068 | sky2_qset(hw, txqaddr[port]); |
1034 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) | ||
1035 | sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0); | ||
1036 | 1069 | ||
1070 | /* Set almost empty threshold */ | ||
1071 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == 1) | ||
1072 | sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0); | ||
1037 | 1073 | ||
1038 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | 1074 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1039 | TX_RING_SIZE - 1); | 1075 | TX_RING_SIZE - 1); |
@@ -1043,8 +1079,10 @@ static int sky2_up(struct net_device *dev) | |||
1043 | goto err_out; | 1079 | goto err_out; |
1044 | 1080 | ||
1045 | /* Enable interrupts from phy/mac for port */ | 1081 | /* Enable interrupts from phy/mac for port */ |
1082 | spin_lock_irq(&hw->hw_lock); | ||
1046 | hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; | 1083 | hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; |
1047 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 1084 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1085 | spin_unlock_irq(&hw->hw_lock); | ||
1048 | return 0; | 1086 | return 0; |
1049 | 1087 | ||
1050 | err_out: | 1088 | err_out: |
@@ -1111,6 +1149,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1111 | struct sky2_tx_le *le = NULL; | 1149 | struct sky2_tx_le *le = NULL; |
1112 | struct tx_ring_info *re; | 1150 | struct tx_ring_info *re; |
1113 | unsigned i, len; | 1151 | unsigned i, len; |
1152 | int avail; | ||
1114 | dma_addr_t mapping; | 1153 | dma_addr_t mapping; |
1115 | u32 addr64; | 1154 | u32 addr64; |
1116 | u16 mss; | 1155 | u16 mss; |
@@ -1253,12 +1292,16 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1253 | re->idx = sky2->tx_prod; | 1292 | re->idx = sky2->tx_prod; |
1254 | le->ctrl |= EOP; | 1293 | le->ctrl |= EOP; |
1255 | 1294 | ||
1295 | avail = tx_avail(sky2); | ||
1296 | if (mss != 0 || avail < TX_MIN_PENDING) { | ||
1297 | le->ctrl |= FRC_STAT; | ||
1298 | if (avail <= MAX_SKB_TX_LE) | ||
1299 | netif_stop_queue(dev); | ||
1300 | } | ||
1301 | |||
1256 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod, | 1302 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod, |
1257 | &sky2->tx_last_put, TX_RING_SIZE); | 1303 | &sky2->tx_last_put, TX_RING_SIZE); |
1258 | 1304 | ||
1259 | if (tx_avail(sky2) <= MAX_SKB_TX_LE) | ||
1260 | netif_stop_queue(dev); | ||
1261 | |||
1262 | out_unlock: | 1305 | out_unlock: |
1263 | spin_unlock(&sky2->tx_lock); | 1306 | spin_unlock(&sky2->tx_lock); |
1264 | 1307 | ||
@@ -1344,10 +1387,10 @@ static int sky2_down(struct net_device *dev) | |||
1344 | netif_stop_queue(dev); | 1387 | netif_stop_queue(dev); |
1345 | 1388 | ||
1346 | /* Disable port IRQ */ | 1389 | /* Disable port IRQ */ |
1347 | local_irq_disable(); | 1390 | spin_lock_irq(&hw->hw_lock); |
1348 | hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); | 1391 | hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); |
1349 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 1392 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1350 | local_irq_enable(); | 1393 | spin_unlock_irq(&hw->hw_lock); |
1351 | 1394 | ||
1352 | flush_scheduled_work(); | 1395 | flush_scheduled_work(); |
1353 | 1396 | ||
@@ -1448,6 +1491,29 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
1448 | sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); | 1491 | sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); |
1449 | 1492 | ||
1450 | reg = gma_read16(hw, port, GM_GP_CTRL); | 1493 | reg = gma_read16(hw, port, GM_GP_CTRL); |
1494 | if (sky2->autoneg == AUTONEG_DISABLE) { | ||
1495 | reg |= GM_GPCR_AU_ALL_DIS; | ||
1496 | |||
1497 | /* Is write/read necessary? Copied from sky2_mac_init */ | ||
1498 | gma_write16(hw, port, GM_GP_CTRL, reg); | ||
1499 | gma_read16(hw, port, GM_GP_CTRL); | ||
1500 | |||
1501 | switch (sky2->speed) { | ||
1502 | case SPEED_1000: | ||
1503 | reg &= ~GM_GPCR_SPEED_100; | ||
1504 | reg |= GM_GPCR_SPEED_1000; | ||
1505 | break; | ||
1506 | case SPEED_100: | ||
1507 | reg &= ~GM_GPCR_SPEED_1000; | ||
1508 | reg |= GM_GPCR_SPEED_100; | ||
1509 | break; | ||
1510 | case SPEED_10: | ||
1511 | reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); | ||
1512 | break; | ||
1513 | } | ||
1514 | } else | ||
1515 | reg &= ~GM_GPCR_AU_ALL_DIS; | ||
1516 | |||
1451 | if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE) | 1517 | if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE) |
1452 | reg |= GM_GPCR_DUP_FULL; | 1518 | reg |= GM_GPCR_DUP_FULL; |
1453 | 1519 | ||
@@ -1606,10 +1672,10 @@ static void sky2_phy_task(void *arg) | |||
1606 | out: | 1672 | out: |
1607 | up(&sky2->phy_sema); | 1673 | up(&sky2->phy_sema); |
1608 | 1674 | ||
1609 | local_irq_disable(); | 1675 | spin_lock_irq(&hw->hw_lock); |
1610 | hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2; | 1676 | hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2; |
1611 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 1677 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1612 | local_irq_enable(); | 1678 | spin_unlock_irq(&hw->hw_lock); |
1613 | } | 1679 | } |
1614 | 1680 | ||
1615 | 1681 | ||
@@ -1650,10 +1716,12 @@ static void sky2_tx_timeout(struct net_device *dev) | |||
1650 | 1716 | ||
1651 | 1717 | ||
1652 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) | 1718 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) |
1653 | /* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */ | 1719 | /* Want receive buffer size to be multiple of 64 bits |
1720 | * and incl room for vlan and truncation | ||
1721 | */ | ||
1654 | static inline unsigned sky2_buf_size(int mtu) | 1722 | static inline unsigned sky2_buf_size(int mtu) |
1655 | { | 1723 | { |
1656 | return roundup(mtu + ETH_HLEN + 4, 8); | 1724 | return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; |
1657 | } | 1725 | } |
1658 | 1726 | ||
1659 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) | 1727 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) |
@@ -1736,7 +1804,7 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, | |||
1736 | if (!(status & GMR_FS_RX_OK)) | 1804 | if (!(status & GMR_FS_RX_OK)) |
1737 | goto resubmit; | 1805 | goto resubmit; |
1738 | 1806 | ||
1739 | if ((status >> 16) != length || length > sky2->rx_bufsize) | 1807 | if (length > sky2->netdev->mtu + ETH_HLEN) |
1740 | goto oversize; | 1808 | goto oversize; |
1741 | 1809 | ||
1742 | if (length < copybreak) { | 1810 | if (length < copybreak) { |
@@ -1834,6 +1902,19 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
1834 | u16 hwidx; | 1902 | u16 hwidx; |
1835 | u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; | 1903 | u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; |
1836 | 1904 | ||
1905 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | ||
1906 | |||
1907 | /* | ||
1908 | * Kick the STAT_LEV_TIMER_CTRL timer. | ||
1909 | * This fixes my hangs on Yukon-EC (0xb6) rev 1. | ||
1910 | * The if clause is there to start the timer only if it has been | ||
1911 | * configured correctly and not been disabled via ethtool. | ||
1912 | */ | ||
1913 | if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) { | ||
1914 | sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP); | ||
1915 | sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START); | ||
1916 | } | ||
1917 | |||
1837 | hwidx = sky2_read16(hw, STAT_PUT_IDX); | 1918 | hwidx = sky2_read16(hw, STAT_PUT_IDX); |
1838 | BUG_ON(hwidx >= STATUS_RING_SIZE); | 1919 | BUG_ON(hwidx >= STATUS_RING_SIZE); |
1839 | rmb(); | 1920 | rmb(); |
@@ -1913,21 +1994,22 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
1913 | } | 1994 | } |
1914 | 1995 | ||
1915 | exit_loop: | 1996 | exit_loop: |
1916 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | ||
1917 | |||
1918 | sky2_tx_check(hw, 0, tx_done[0]); | 1997 | sky2_tx_check(hw, 0, tx_done[0]); |
1919 | sky2_tx_check(hw, 1, tx_done[1]); | 1998 | sky2_tx_check(hw, 1, tx_done[1]); |
1920 | 1999 | ||
1921 | if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) { | 2000 | if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { |
1922 | /* need to restart TX timer */ | 2001 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); |
1923 | if (is_ec_a1(hw)) { | 2002 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); |
1924 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); | 2003 | } |
1925 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); | 2004 | |
1926 | } | 2005 | if (likely(work_done < to_do)) { |
2006 | spin_lock_irq(&hw->hw_lock); | ||
2007 | __netif_rx_complete(dev0); | ||
1927 | 2008 | ||
1928 | netif_rx_complete(dev0); | ||
1929 | hw->intr_mask |= Y2_IS_STAT_BMU; | 2009 | hw->intr_mask |= Y2_IS_STAT_BMU; |
1930 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 2010 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
2011 | spin_unlock_irq(&hw->hw_lock); | ||
2012 | |||
1931 | return 0; | 2013 | return 0; |
1932 | } else { | 2014 | } else { |
1933 | *budget -= work_done; | 2015 | *budget -= work_done; |
@@ -1990,13 +2072,13 @@ static void sky2_hw_intr(struct sky2_hw *hw) | |||
1990 | if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { | 2072 | if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { |
1991 | u16 pci_err; | 2073 | u16 pci_err; |
1992 | 2074 | ||
1993 | pci_read_config_word(hw->pdev, PCI_STATUS, &pci_err); | 2075 | pci_err = sky2_pci_read16(hw, PCI_STATUS); |
1994 | if (net_ratelimit()) | 2076 | if (net_ratelimit()) |
1995 | printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n", | 2077 | printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n", |
1996 | pci_name(hw->pdev), pci_err); | 2078 | pci_name(hw->pdev), pci_err); |
1997 | 2079 | ||
1998 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2080 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
1999 | pci_write_config_word(hw->pdev, PCI_STATUS, | 2081 | sky2_pci_write16(hw, PCI_STATUS, |
2000 | pci_err | PCI_STATUS_ERROR_BITS); | 2082 | pci_err | PCI_STATUS_ERROR_BITS); |
2001 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 2083 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
2002 | } | 2084 | } |
@@ -2005,7 +2087,7 @@ static void sky2_hw_intr(struct sky2_hw *hw) | |||
2005 | /* PCI-Express uncorrectable Error occurred */ | 2087 | /* PCI-Express uncorrectable Error occurred */ |
2006 | u32 pex_err; | 2088 | u32 pex_err; |
2007 | 2089 | ||
2008 | pci_read_config_dword(hw->pdev, PEX_UNC_ERR_STAT, &pex_err); | 2090 | pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT); |
2009 | 2091 | ||
2010 | if (net_ratelimit()) | 2092 | if (net_ratelimit()) |
2011 | printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", | 2093 | printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", |
@@ -2013,7 +2095,7 @@ static void sky2_hw_intr(struct sky2_hw *hw) | |||
2013 | 2095 | ||
2014 | /* clear the interrupt */ | 2096 | /* clear the interrupt */ |
2015 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2097 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2016 | pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, | 2098 | sky2_pci_write32(hw, PEX_UNC_ERR_STAT, |
2017 | 0xffffffffUL); | 2099 | 0xffffffffUL); |
2018 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 2100 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
2019 | 2101 | ||
@@ -2059,6 +2141,7 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) | |||
2059 | 2141 | ||
2060 | hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); | 2142 | hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); |
2061 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 2143 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
2144 | |||
2062 | schedule_work(&sky2->phy_task); | 2145 | schedule_work(&sky2->phy_task); |
2063 | } | 2146 | } |
2064 | 2147 | ||
@@ -2072,6 +2155,7 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2072 | if (status == 0 || status == ~0) | 2155 | if (status == 0 || status == ~0) |
2073 | return IRQ_NONE; | 2156 | return IRQ_NONE; |
2074 | 2157 | ||
2158 | spin_lock(&hw->hw_lock); | ||
2075 | if (status & Y2_IS_HW_ERR) | 2159 | if (status & Y2_IS_HW_ERR) |
2076 | sky2_hw_intr(hw); | 2160 | sky2_hw_intr(hw); |
2077 | 2161 | ||
@@ -2100,7 +2184,7 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2100 | 2184 | ||
2101 | sky2_write32(hw, B0_Y2_SP_ICR, 2); | 2185 | sky2_write32(hw, B0_Y2_SP_ICR, 2); |
2102 | 2186 | ||
2103 | sky2_read32(hw, B0_IMSK); | 2187 | spin_unlock(&hw->hw_lock); |
2104 | 2188 | ||
2105 | return IRQ_HANDLED; | 2189 | return IRQ_HANDLED; |
2106 | } | 2190 | } |
@@ -2141,14 +2225,12 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) | |||
2141 | 2225 | ||
2142 | static int sky2_reset(struct sky2_hw *hw) | 2226 | static int sky2_reset(struct sky2_hw *hw) |
2143 | { | 2227 | { |
2144 | u32 ctst; | ||
2145 | u16 status; | 2228 | u16 status; |
2146 | u8 t8, pmd_type; | 2229 | u8 t8, pmd_type; |
2147 | int i; | 2230 | int i; |
2148 | 2231 | ||
2149 | ctst = sky2_read32(hw, B0_CTST); | ||
2150 | |||
2151 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2232 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2233 | |||
2152 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); | 2234 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); |
2153 | if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { | 2235 | if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { |
2154 | printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", | 2236 | printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", |
@@ -2156,12 +2238,6 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2156 | return -EOPNOTSUPP; | 2238 | return -EOPNOTSUPP; |
2157 | } | 2239 | } |
2158 | 2240 | ||
2159 | /* ring for status responses */ | ||
2160 | hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, | ||
2161 | &hw->st_dma); | ||
2162 | if (!hw->st_le) | ||
2163 | return -ENOMEM; | ||
2164 | |||
2165 | /* disable ASF */ | 2241 | /* disable ASF */ |
2166 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { | 2242 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { |
2167 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); | 2243 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); |
@@ -2173,20 +2249,18 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2173 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2249 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2174 | 2250 | ||
2175 | /* clear PCI errors, if any */ | 2251 | /* clear PCI errors, if any */ |
2176 | pci_read_config_word(hw->pdev, PCI_STATUS, &status); | 2252 | status = sky2_pci_read16(hw, PCI_STATUS); |
2253 | |||
2177 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2254 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2178 | pci_write_config_word(hw->pdev, PCI_STATUS, | 2255 | sky2_pci_write16(hw, PCI_STATUS, status | PCI_STATUS_ERROR_BITS); |
2179 | status | PCI_STATUS_ERROR_BITS); | 2256 | |
2180 | 2257 | ||
2181 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); | 2258 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); |
2182 | 2259 | ||
2183 | /* clear any PEX errors */ | 2260 | /* clear any PEX errors */ |
2184 | if (is_pciex(hw)) { | 2261 | if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) |
2185 | u16 lstat; | 2262 | sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); |
2186 | pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, | 2263 | |
2187 | 0xffffffffUL); | ||
2188 | pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat); | ||
2189 | } | ||
2190 | 2264 | ||
2191 | pmd_type = sky2_read8(hw, B2_PMD_TYP); | 2265 | pmd_type = sky2_read8(hw, B2_PMD_TYP); |
2192 | hw->copper = !(pmd_type == 'L' || pmd_type == 'S'); | 2266 | hw->copper = !(pmd_type == 'L' || pmd_type == 'S'); |
@@ -2285,8 +2359,7 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2285 | sky2_write8(hw, STAT_FIFO_ISR_WM, 16); | 2359 | sky2_write8(hw, STAT_FIFO_ISR_WM, 16); |
2286 | 2360 | ||
2287 | sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); | 2361 | sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); |
2288 | sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100)); | 2362 | sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7)); |
2289 | sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20)); | ||
2290 | } | 2363 | } |
2291 | 2364 | ||
2292 | /* enable status unit */ | 2365 | /* enable status unit */ |
@@ -2551,19 +2624,24 @@ static struct net_device_stats *sky2_get_stats(struct net_device *dev) | |||
2551 | static int sky2_set_mac_address(struct net_device *dev, void *p) | 2624 | static int sky2_set_mac_address(struct net_device *dev, void *p) |
2552 | { | 2625 | { |
2553 | struct sky2_port *sky2 = netdev_priv(dev); | 2626 | struct sky2_port *sky2 = netdev_priv(dev); |
2554 | struct sockaddr *addr = p; | 2627 | struct sky2_hw *hw = sky2->hw; |
2628 | unsigned port = sky2->port; | ||
2629 | const struct sockaddr *addr = p; | ||
2555 | 2630 | ||
2556 | if (!is_valid_ether_addr(addr->sa_data)) | 2631 | if (!is_valid_ether_addr(addr->sa_data)) |
2557 | return -EADDRNOTAVAIL; | 2632 | return -EADDRNOTAVAIL; |
2558 | 2633 | ||
2559 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 2634 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
2560 | memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8, | 2635 | memcpy_toio(hw->regs + B2_MAC_1 + port * 8, |
2561 | dev->dev_addr, ETH_ALEN); | 2636 | dev->dev_addr, ETH_ALEN); |
2562 | memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8, | 2637 | memcpy_toio(hw->regs + B2_MAC_2 + port * 8, |
2563 | dev->dev_addr, ETH_ALEN); | 2638 | dev->dev_addr, ETH_ALEN); |
2564 | 2639 | ||
2565 | if (netif_running(dev)) | 2640 | /* virtual address for data */ |
2566 | sky2_phy_reinit(sky2); | 2641 | gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr); |
2642 | |||
2643 | /* physical address: used for pause frames */ | ||
2644 | gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr); | ||
2567 | 2645 | ||
2568 | return 0; | 2646 | return 0; |
2569 | } | 2647 | } |
@@ -2815,11 +2893,11 @@ static int sky2_set_coalesce(struct net_device *dev, | |||
2815 | (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax)) | 2893 | (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax)) |
2816 | return -EINVAL; | 2894 | return -EINVAL; |
2817 | 2895 | ||
2818 | if (ecmd->tx_max_coalesced_frames > 0xffff) | 2896 | if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1) |
2819 | return -EINVAL; | 2897 | return -EINVAL; |
2820 | if (ecmd->rx_max_coalesced_frames > 0xff) | 2898 | if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING) |
2821 | return -EINVAL; | 2899 | return -EINVAL; |
2822 | if (ecmd->rx_max_coalesced_frames_irq > 0xff) | 2900 | if (ecmd->rx_max_coalesced_frames_irq >RX_MAX_PENDING) |
2823 | return -EINVAL; | 2901 | return -EINVAL; |
2824 | 2902 | ||
2825 | if (ecmd->tx_coalesce_usecs == 0) | 2903 | if (ecmd->tx_coalesce_usecs == 0) |
@@ -2843,7 +2921,7 @@ static int sky2_set_coalesce(struct net_device *dev, | |||
2843 | if (ecmd->rx_coalesce_usecs_irq == 0) | 2921 | if (ecmd->rx_coalesce_usecs_irq == 0) |
2844 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP); | 2922 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP); |
2845 | else { | 2923 | else { |
2846 | sky2_write32(hw, STAT_TX_TIMER_INI, | 2924 | sky2_write32(hw, STAT_ISR_TIMER_INI, |
2847 | sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq)); | 2925 | sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq)); |
2848 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); | 2926 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); |
2849 | } | 2927 | } |
@@ -3106,17 +3184,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3106 | } | 3184 | } |
3107 | } | 3185 | } |
3108 | 3186 | ||
3109 | #ifdef __BIG_ENDIAN | ||
3110 | /* byte swap descriptors in hardware */ | ||
3111 | { | ||
3112 | u32 reg; | ||
3113 | |||
3114 | pci_read_config_dword(pdev, PCI_DEV_REG2, ®); | ||
3115 | reg |= PCI_REV_DESC; | ||
3116 | pci_write_config_dword(pdev, PCI_DEV_REG2, reg); | ||
3117 | } | ||
3118 | #endif | ||
3119 | |||
3120 | err = -ENOMEM; | 3187 | err = -ENOMEM; |
3121 | hw = kzalloc(sizeof(*hw), GFP_KERNEL); | 3188 | hw = kzalloc(sizeof(*hw), GFP_KERNEL); |
3122 | if (!hw) { | 3189 | if (!hw) { |
@@ -3134,6 +3201,24 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3134 | goto err_out_free_hw; | 3201 | goto err_out_free_hw; |
3135 | } | 3202 | } |
3136 | hw->pm_cap = pm_cap; | 3203 | hw->pm_cap = pm_cap; |
3204 | spin_lock_init(&hw->hw_lock); | ||
3205 | |||
3206 | #ifdef __BIG_ENDIAN | ||
3207 | /* byte swap descriptors in hardware */ | ||
3208 | { | ||
3209 | u32 reg; | ||
3210 | |||
3211 | reg = sky2_pci_read32(hw, PCI_DEV_REG2); | ||
3212 | reg |= PCI_REV_DESC; | ||
3213 | sky2_pci_write32(hw, PCI_DEV_REG2, reg); | ||
3214 | } | ||
3215 | #endif | ||
3216 | |||
3217 | /* ring for status responses */ | ||
3218 | hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, | ||
3219 | &hw->st_dma); | ||
3220 | if (!hw->st_le) | ||
3221 | goto err_out_iounmap; | ||
3137 | 3222 | ||
3138 | err = sky2_reset(hw); | 3223 | err = sky2_reset(hw); |
3139 | if (err) | 3224 | if (err) |
@@ -3263,25 +3348,33 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3263 | static int sky2_resume(struct pci_dev *pdev) | 3348 | static int sky2_resume(struct pci_dev *pdev) |
3264 | { | 3349 | { |
3265 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 3350 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
3266 | int i; | 3351 | int i, err; |
3267 | 3352 | ||
3268 | pci_restore_state(pdev); | 3353 | pci_restore_state(pdev); |
3269 | pci_enable_wake(pdev, PCI_D0, 0); | 3354 | pci_enable_wake(pdev, PCI_D0, 0); |
3270 | sky2_set_power_state(hw, PCI_D0); | 3355 | err = sky2_set_power_state(hw, PCI_D0); |
3356 | if (err) | ||
3357 | goto out; | ||
3271 | 3358 | ||
3272 | sky2_reset(hw); | 3359 | err = sky2_reset(hw); |
3360 | if (err) | ||
3361 | goto out; | ||
3273 | 3362 | ||
3274 | for (i = 0; i < 2; i++) { | 3363 | for (i = 0; i < 2; i++) { |
3275 | struct net_device *dev = hw->dev[i]; | 3364 | struct net_device *dev = hw->dev[i]; |
3276 | if (dev) { | 3365 | if (dev && netif_running(dev)) { |
3277 | if (netif_running(dev)) { | 3366 | netif_device_attach(dev); |
3278 | netif_device_attach(dev); | 3367 | err = sky2_up(dev); |
3279 | if (sky2_up(dev)) | 3368 | if (err) { |
3280 | dev_close(dev); | 3369 | printk(KERN_ERR PFX "%s: could not up: %d\n", |
3370 | dev->name, err); | ||
3371 | dev_close(dev); | ||
3372 | break; | ||
3281 | } | 3373 | } |
3282 | } | 3374 | } |
3283 | } | 3375 | } |
3284 | return 0; | 3376 | out: |
3377 | return err; | ||
3285 | } | 3378 | } |
3286 | #endif | 3379 | #endif |
3287 | 3380 | ||