aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-24 04:22:21 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-24 04:22:21 -0400
commit66643de455c27973ac31ad6de9f859d399916842 (patch)
tree7ebed7f051879007d4b11d6aaa9e65a1bcb0b08f /drivers/net/sky2.c
parent2c23d62abb820e19c54012520f08a198c2233a85 (diff)
parent387e2b0439026aa738a9edca15a57e5c0bcb4dfc (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: include/asm-powerpc/unistd.h include/asm-sparc/unistd.h include/asm-sparc64/unistd.h Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c257
1 files changed, 148 insertions, 109 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 227df9876a2c..60779ebf2ff6 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -51,7 +51,7 @@
51#include "sky2.h" 51#include "sky2.h"
52 52
53#define DRV_NAME "sky2" 53#define DRV_NAME "sky2"
54#define DRV_VERSION "1.2" 54#define DRV_VERSION "1.4"
55#define PFX DRV_NAME " " 55#define PFX DRV_NAME " "
56 56
57/* 57/*
@@ -79,6 +79,8 @@
79#define NAPI_WEIGHT 64 79#define NAPI_WEIGHT 64
80#define PHY_RETRIES 1000 80#define PHY_RETRIES 1000
81 81
82#define RING_NEXT(x,s) (((x)+1) & ((s)-1))
83
82static const u32 default_msg = 84static const u32 default_msg =
83 NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK 85 NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
84 | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR 86 | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
@@ -96,9 +98,14 @@ static int disable_msi = 0;
96module_param(disable_msi, int, 0); 98module_param(disable_msi, int, 0);
97MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); 99MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
98 100
101static int idle_timeout = 100;
102module_param(idle_timeout, int, 0);
103MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)");
104
99static const struct pci_device_id sky2_id_table[] = { 105static const struct pci_device_id sky2_id_table[] = {
100 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, 106 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
101 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, 107 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
108 { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */
102 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, 109 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
103 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, 110 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
104 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, 111 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
@@ -122,6 +129,7 @@ MODULE_DEVICE_TABLE(pci, sky2_id_table);
122/* Avoid conditionals by using array */ 129/* Avoid conditionals by using array */
123static const unsigned txqaddr[] = { Q_XA1, Q_XA2 }; 130static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
124static const unsigned rxqaddr[] = { Q_R1, Q_R2 }; 131static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
132static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 };
125 133
126/* This driver supports yukon2 chipset only */ 134/* This driver supports yukon2 chipset only */
127static const char *yukon2_name[] = { 135static const char *yukon2_name[] = {
@@ -228,6 +236,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state)
228 } 236 }
229 237
230 if (hw->chip_id == CHIP_ID_YUKON_EC_U) { 238 if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
239 sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON);
231 sky2_pci_write32(hw, PCI_DEV_REG3, 0); 240 sky2_pci_write32(hw, PCI_DEV_REG3, 0);
232 reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); 241 reg1 = sky2_pci_read32(hw, PCI_DEV_REG4);
233 reg1 &= P_ASPM_CONTROL_MSK; 242 reg1 &= P_ASPM_CONTROL_MSK;
@@ -298,7 +307,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
298 struct sky2_port *sky2 = netdev_priv(hw->dev[port]); 307 struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
299 u16 ctrl, ct1000, adv, pg, ledctrl, ledover; 308 u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
300 309
301 if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) { 310 if (sky2->autoneg == AUTONEG_ENABLE &&
311 !(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
302 u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); 312 u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
303 313
304 ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | 314 ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
@@ -326,7 +336,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
326 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); 336 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
327 337
328 if (sky2->autoneg == AUTONEG_ENABLE && 338 if (sky2->autoneg == AUTONEG_ENABLE &&
329 hw->chip_id == CHIP_ID_YUKON_XL) { 339 (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
330 ctrl &= ~PHY_M_PC_DSC_MSK; 340 ctrl &= ~PHY_M_PC_DSC_MSK;
331 ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; 341 ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
332 } 342 }
@@ -442,10 +452,11 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
442 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); 452 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
443 453
444 /* set LED Function Control register */ 454 /* set LED Function Control register */
445 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ 455 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
446 PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ 456 (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */
447 PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ 457 PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */
448 PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ 458 PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
459 PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */
449 460
450 /* set Polarity Control register */ 461 /* set Polarity Control register */
451 gm_phy_write(hw, port, PHY_MARV_PHY_STAT, 462 gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
@@ -459,6 +470,25 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
459 /* restore page register */ 470 /* restore page register */
460 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); 471 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
461 break; 472 break;
473 case CHIP_ID_YUKON_EC_U:
474 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
475
476 /* select page 3 to access LED control register */
477 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
478
479 /* set LED Function Control register */
480 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
481 (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */
482 PHY_M_LEDC_INIT_CTRL(8) | /* 10 Mbps */
483 PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
484 PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */
485
486 /* set Blink Rate in LED Timer Control Register */
487 gm_phy_write(hw, port, PHY_MARV_INT_MASK,
488 ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS));
489 /* restore page register */
490 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
491 break;
462 492
463 default: 493 default:
464 /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ 494 /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
@@ -467,19 +497,21 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
467 ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); 497 ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
468 } 498 }
469 499
470 if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { 500 if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) {
471 /* apply fixes in PHY AFE */ 501 /* apply fixes in PHY AFE */
472 gm_phy_write(hw, port, 22, 255); 502 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
503 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
504
473 /* increase differential signal amplitude in 10BASE-T */ 505 /* increase differential signal amplitude in 10BASE-T */
474 gm_phy_write(hw, port, 24, 0xaa99); 506 gm_phy_write(hw, port, 0x18, 0xaa99);
475 gm_phy_write(hw, port, 23, 0x2011); 507 gm_phy_write(hw, port, 0x17, 0x2011);
476 508
477 /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ 509 /* fix for IEEE A/B Symmetry failure in 1000BASE-T */
478 gm_phy_write(hw, port, 24, 0xa204); 510 gm_phy_write(hw, port, 0x18, 0xa204);
479 gm_phy_write(hw, port, 23, 0x2002); 511 gm_phy_write(hw, port, 0x17, 0x2002);
480 512
481 /* set page register to 0 */ 513 /* set page register to 0 */
482 gm_phy_write(hw, port, 22, 0); 514 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
483 } else { 515 } else {
484 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); 516 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
485 517
@@ -553,6 +585,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
553 585
554 if (sky2->duplex == DUPLEX_FULL) 586 if (sky2->duplex == DUPLEX_FULL)
555 reg |= GM_GPCR_DUP_FULL; 587 reg |= GM_GPCR_DUP_FULL;
588
589 /* turn off pause in 10/100mbps half duplex */
590 else if (sky2->speed != SPEED_1000 &&
591 hw->chip_id != CHIP_ID_YUKON_EC_U)
592 sky2->tx_pause = sky2->rx_pause = 0;
556 } else 593 } else
557 reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; 594 reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
558 595
@@ -719,7 +756,7 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
719{ 756{
720 struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod; 757 struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
721 758
722 sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE; 759 sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
723 return le; 760 return le;
724} 761}
725 762
@@ -735,7 +772,7 @@ static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
735static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2) 772static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
736{ 773{
737 struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put; 774 struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
738 sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE; 775 sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
739 return le; 776 return le;
740} 777}
741 778
@@ -985,7 +1022,25 @@ static int sky2_up(struct net_device *dev)
985 struct sky2_hw *hw = sky2->hw; 1022 struct sky2_hw *hw = sky2->hw;
986 unsigned port = sky2->port; 1023 unsigned port = sky2->port;
987 u32 ramsize, rxspace, imask; 1024 u32 ramsize, rxspace, imask;
988 int err = -ENOMEM; 1025 int cap, err = -ENOMEM;
1026 struct net_device *otherdev = hw->dev[sky2->port^1];
1027
1028 /*
1029 * On dual port PCI-X card, there is an problem where status
1030 * can be received out of order due to split transactions
1031 */
1032 if (otherdev && netif_running(otherdev) &&
1033 (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
1034 struct sky2_port *osky2 = netdev_priv(otherdev);
1035 u16 cmd;
1036
1037 cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
1038 cmd &= ~PCI_X_CMD_MAX_SPLIT;
1039 sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
1040
1041 sky2->rx_csum = 0;
1042 osky2->rx_csum = 0;
1043 }
989 1044
990 if (netif_msg_ifup(sky2)) 1045 if (netif_msg_ifup(sky2))
991 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); 1046 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
@@ -1050,7 +1105,7 @@ static int sky2_up(struct net_device *dev)
1050 1105
1051 /* Enable interrupts from phy/mac for port */ 1106 /* Enable interrupts from phy/mac for port */
1052 imask = sky2_read32(hw, B0_IMSK); 1107 imask = sky2_read32(hw, B0_IMSK);
1053 imask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; 1108 imask |= portirq_msk[port];
1054 sky2_write32(hw, B0_IMSK, imask); 1109 sky2_write32(hw, B0_IMSK, imask);
1055 1110
1056 return 0; 1111 return 0;
@@ -1078,7 +1133,7 @@ err_out:
1078/* Modular subtraction in ring */ 1133/* Modular subtraction in ring */
1079static inline int tx_dist(unsigned tail, unsigned head) 1134static inline int tx_dist(unsigned tail, unsigned head)
1080{ 1135{
1081 return (head - tail) % TX_RING_SIZE; 1136 return (head - tail) & (TX_RING_SIZE - 1);
1082} 1137}
1083 1138
1084/* Number of list elements available for next tx */ 1139/* Number of list elements available for next tx */
@@ -1255,7 +1310,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1255 le->opcode = OP_BUFFER | HW_OWNER; 1310 le->opcode = OP_BUFFER | HW_OWNER;
1256 1311
1257 fre = sky2->tx_ring 1312 fre = sky2->tx_ring
1258 + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE; 1313 + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE);
1259 pci_unmap_addr_set(fre, mapaddr, mapping); 1314 pci_unmap_addr_set(fre, mapaddr, mapping);
1260 } 1315 }
1261 1316
@@ -1315,7 +1370,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1315 1370
1316 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 1371 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1317 struct tx_ring_info *fre; 1372 struct tx_ring_info *fre;
1318 fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE; 1373 fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE);
1319 pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr), 1374 pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
1320 skb_shinfo(skb)->frags[i].size, 1375 skb_shinfo(skb)->frags[i].size,
1321 PCI_DMA_TODEVICE); 1376 PCI_DMA_TODEVICE);
@@ -1401,7 +1456,7 @@ static int sky2_down(struct net_device *dev)
1401 1456
1402 /* Disable port IRQ */ 1457 /* Disable port IRQ */
1403 imask = sky2_read32(hw, B0_IMSK); 1458 imask = sky2_read32(hw, B0_IMSK);
1404 imask &= ~(sky2->port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; 1459 imask &= ~portirq_msk[port];
1405 sky2_write32(hw, B0_IMSK, imask); 1460 sky2_write32(hw, B0_IMSK, imask);
1406 1461
1407 /* turn off LED's */ 1462 /* turn off LED's */
@@ -1498,17 +1553,26 @@ static void sky2_link_up(struct sky2_port *sky2)
1498 sky2_write8(hw, SK_REG(port, LNK_LED_REG), 1553 sky2_write8(hw, SK_REG(port, LNK_LED_REG),
1499 LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); 1554 LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
1500 1555
1501 if (hw->chip_id == CHIP_ID_YUKON_XL) { 1556 if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) {
1502 u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); 1557 u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
1558 u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */
1559
1560 switch(sky2->speed) {
1561 case SPEED_10:
1562 led |= PHY_M_LEDC_INIT_CTRL(7);
1563 break;
1564
1565 case SPEED_100:
1566 led |= PHY_M_LEDC_STA1_CTRL(7);
1567 break;
1568
1569 case SPEED_1000:
1570 led |= PHY_M_LEDC_STA0_CTRL(7);
1571 break;
1572 }
1503 1573
1504 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); 1574 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
1505 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ 1575 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, led);
1506 PHY_M_LEDC_INIT_CTRL(sky2->speed ==
1507 SPEED_10 ? 7 : 0) |
1508 PHY_M_LEDC_STA1_CTRL(sky2->speed ==
1509 SPEED_100 ? 7 : 0) |
1510 PHY_M_LEDC_STA0_CTRL(sky2->speed ==
1511 SPEED_1000 ? 7 : 0));
1512 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); 1576 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
1513 } 1577 }
1514 1578
@@ -1583,7 +1647,7 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
1583 sky2->speed = sky2_phy_speed(hw, aux); 1647 sky2->speed = sky2_phy_speed(hw, aux);
1584 1648
1585 /* Pause bits are offset (9..8) */ 1649 /* Pause bits are offset (9..8) */
1586 if (hw->chip_id == CHIP_ID_YUKON_XL) 1650 if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)
1587 aux >>= 6; 1651 aux >>= 6;
1588 1652
1589 sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; 1653 sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0;
@@ -1855,39 +1919,38 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
1855 } 1919 }
1856} 1920}
1857 1921
1922/* Is status ring empty or is there more to do? */
1923static inline int sky2_more_work(const struct sky2_hw *hw)
1924{
1925 return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX));
1926}
1927
1858/* Process status response ring */ 1928/* Process status response ring */
1859static int sky2_status_intr(struct sky2_hw *hw, int to_do) 1929static int sky2_status_intr(struct sky2_hw *hw, int to_do)
1860{ 1930{
1861 int work_done = 0; 1931 int work_done = 0;
1932 u16 hwidx = sky2_read16(hw, STAT_PUT_IDX);
1862 1933
1863 rmb(); 1934 rmb();
1864 1935
1865 for(;;) { 1936 while (hw->st_idx != hwidx) {
1866 struct sky2_status_le *le = hw->st_le + hw->st_idx; 1937 struct sky2_status_le *le = hw->st_le + hw->st_idx;
1867 struct net_device *dev; 1938 struct net_device *dev;
1868 struct sky2_port *sky2; 1939 struct sky2_port *sky2;
1869 struct sk_buff *skb; 1940 struct sk_buff *skb;
1870 u32 status; 1941 u32 status;
1871 u16 length; 1942 u16 length;
1872 u8 link, opcode;
1873 1943
1874 opcode = le->opcode; 1944 hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
1875 if (!opcode)
1876 break;
1877 opcode &= ~HW_OWNER;
1878 1945
1879 hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE; 1946 BUG_ON(le->link >= 2);
1880 le->opcode = 0; 1947 dev = hw->dev[le->link];
1881
1882 link = le->link;
1883 BUG_ON(link >= 2);
1884 dev = hw->dev[link];
1885 1948
1886 sky2 = netdev_priv(dev); 1949 sky2 = netdev_priv(dev);
1887 length = le->length; 1950 length = le->length;
1888 status = le->status; 1951 status = le->status;
1889 1952
1890 switch (opcode) { 1953 switch (le->opcode & ~HW_OWNER) {
1891 case OP_RXSTAT: 1954 case OP_RXSTAT:
1892 skb = sky2_receive(sky2, length, status); 1955 skb = sky2_receive(sky2, length, status);
1893 if (!skb) 1956 if (!skb)
@@ -1927,7 +1990,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
1927 1990
1928 case OP_TXINDEXLE: 1991 case OP_TXINDEXLE:
1929 /* TX index reports status for both ports */ 1992 /* TX index reports status for both ports */
1930 sky2_tx_done(hw->dev[0], status & 0xffff); 1993 BUILD_BUG_ON(TX_RING_SIZE > 0x1000);
1994 sky2_tx_done(hw->dev[0], status & 0xfff);
1931 if (hw->dev[1]) 1995 if (hw->dev[1])
1932 sky2_tx_done(hw->dev[1], 1996 sky2_tx_done(hw->dev[1],
1933 ((status >> 24) & 0xff) 1997 ((status >> 24) & 0xff)
@@ -1937,8 +2001,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
1937 default: 2001 default:
1938 if (net_ratelimit()) 2002 if (net_ratelimit())
1939 printk(KERN_WARNING PFX 2003 printk(KERN_WARNING PFX
1940 "unknown status opcode 0x%x\n", opcode); 2004 "unknown status opcode 0x%x\n", le->opcode);
1941 break; 2005 goto exit_loop;
1942 } 2006 }
1943 } 2007 }
1944 2008
@@ -2089,12 +2153,13 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port,
2089 */ 2153 */
2090static void sky2_idle(unsigned long arg) 2154static void sky2_idle(unsigned long arg)
2091{ 2155{
2092 struct net_device *dev = (struct net_device *) arg; 2156 struct sky2_hw *hw = (struct sky2_hw *) arg;
2157 struct net_device *dev = hw->dev[0];
2093 2158
2094 local_irq_disable();
2095 if (__netif_rx_schedule_prep(dev)) 2159 if (__netif_rx_schedule_prep(dev))
2096 __netif_rx_schedule(dev); 2160 __netif_rx_schedule(dev);
2097 local_irq_enable(); 2161
2162 mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout));
2098} 2163}
2099 2164
2100 2165
@@ -2105,65 +2170,46 @@ static int sky2_poll(struct net_device *dev0, int *budget)
2105 int work_done = 0; 2170 int work_done = 0;
2106 u32 status = sky2_read32(hw, B0_Y2_SP_EISR); 2171 u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
2107 2172
2108 restart_poll: 2173 if (status & Y2_IS_HW_ERR)
2109 if (unlikely(status & ~Y2_IS_STAT_BMU)) { 2174 sky2_hw_intr(hw);
2110 if (status & Y2_IS_HW_ERR)
2111 sky2_hw_intr(hw);
2112 2175
2113 if (status & Y2_IS_IRQ_PHY1) 2176 if (status & Y2_IS_IRQ_PHY1)
2114 sky2_phy_intr(hw, 0); 2177 sky2_phy_intr(hw, 0);
2115 2178
2116 if (status & Y2_IS_IRQ_PHY2) 2179 if (status & Y2_IS_IRQ_PHY2)
2117 sky2_phy_intr(hw, 1); 2180 sky2_phy_intr(hw, 1);
2118 2181
2119 if (status & Y2_IS_IRQ_MAC1) 2182 if (status & Y2_IS_IRQ_MAC1)
2120 sky2_mac_intr(hw, 0); 2183 sky2_mac_intr(hw, 0);
2121 2184
2122 if (status & Y2_IS_IRQ_MAC2) 2185 if (status & Y2_IS_IRQ_MAC2)
2123 sky2_mac_intr(hw, 1); 2186 sky2_mac_intr(hw, 1);
2124 2187
2125 if (status & Y2_IS_CHK_RX1) 2188 if (status & Y2_IS_CHK_RX1)
2126 sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1); 2189 sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1);
2127 2190
2128 if (status & Y2_IS_CHK_RX2) 2191 if (status & Y2_IS_CHK_RX2)
2129 sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2); 2192 sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2);
2130 2193
2131 if (status & Y2_IS_CHK_TXA1) 2194 if (status & Y2_IS_CHK_TXA1)
2132 sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1); 2195 sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1);
2133 2196
2134 if (status & Y2_IS_CHK_TXA2) 2197 if (status & Y2_IS_CHK_TXA2)
2135 sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); 2198 sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
2136 }
2137
2138 if (status & Y2_IS_STAT_BMU) {
2139 work_done += sky2_status_intr(hw, work_limit - work_done);
2140 *budget -= work_done;
2141 dev0->quota -= work_done;
2142 2199
2143 if (work_done >= work_limit) 2200 work_done = sky2_status_intr(hw, work_limit);
2144 return 1; 2201 *budget -= work_done;
2202 dev0->quota -= work_done;
2145 2203
2204 if (status & Y2_IS_STAT_BMU)
2146 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); 2205 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
2147 }
2148
2149 mod_timer(&hw->idle_timer, jiffies + HZ);
2150 2206
2151 local_irq_disable(); 2207 if (sky2_more_work(hw))
2152 __netif_rx_complete(dev0); 2208 return 1;
2153 2209
2154 status = sky2_read32(hw, B0_Y2_SP_LISR); 2210 netif_rx_complete(dev0);
2155
2156 if (unlikely(status)) {
2157 /* More work pending, try and keep going */
2158 if (__netif_rx_schedule_prep(dev0)) {
2159 __netif_rx_reschedule(dev0, work_done);
2160 status = sky2_read32(hw, B0_Y2_SP_EISR);
2161 local_irq_enable();
2162 goto restart_poll;
2163 }
2164 }
2165 2211
2166 local_irq_enable(); 2212 sky2_read32(hw, B0_Y2_SP_LISR);
2167 return 0; 2213 return 0;
2168} 2214}
2169 2215
@@ -2244,13 +2290,6 @@ static int __devinit sky2_reset(struct sky2_hw *hw)
2244 return -EOPNOTSUPP; 2290 return -EOPNOTSUPP;
2245 } 2291 }
2246 2292
2247 /* This chip is new and not tested yet */
2248 if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
2249 pr_info(PFX "%s: is a version of Yukon 2 chipset that has not been tested yet.\n",
2250 pci_name(hw->pdev));
2251 pr_info("Please report success/failure to maintainer <shemminger@osdl.org>\n");
2252 }
2253
2254 /* disable ASF */ 2293 /* disable ASF */
2255 if (hw->chip_id <= CHIP_ID_YUKON_EC) { 2294 if (hw->chip_id <= CHIP_ID_YUKON_EC) {
2256 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); 2295 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
@@ -3054,12 +3093,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3054 sky2->duplex = -1; 3093 sky2->duplex = -1;
3055 sky2->speed = -1; 3094 sky2->speed = -1;
3056 sky2->advertising = sky2_supported_modes(hw); 3095 sky2->advertising = sky2_supported_modes(hw);
3057 3096 sky2->rx_csum = 1;
3058 /* Receive checksum disabled for Yukon XL
3059 * because of observed problems with incorrect
3060 * values when multiple packets are received in one interrupt
3061 */
3062 sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
3063 3097
3064 spin_lock_init(&sky2->phy_lock); 3098 spin_lock_init(&sky2->phy_lock);
3065 sky2->tx_pending = TX_DEF_PENDING; 3099 sky2->tx_pending = TX_DEF_PENDING;
@@ -3302,7 +3336,10 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3302 3336
3303 sky2_write32(hw, B0_IMSK, Y2_IS_BASE); 3337 sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
3304 3338
3305 setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev); 3339 setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
3340 if (idle_timeout > 0)
3341 mod_timer(&hw->idle_timer,
3342 jiffies + msecs_to_jiffies(idle_timeout));
3306 3343
3307 pci_set_drvdata(pdev, hw); 3344 pci_set_drvdata(pdev, hw);
3308 3345
@@ -3342,6 +3379,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
3342 del_timer_sync(&hw->idle_timer); 3379 del_timer_sync(&hw->idle_timer);
3343 3380
3344 sky2_write32(hw, B0_IMSK, 0); 3381 sky2_write32(hw, B0_IMSK, 0);
3382 synchronize_irq(hw->pdev->irq);
3383
3345 dev0 = hw->dev[0]; 3384 dev0 = hw->dev[0];
3346 dev1 = hw->dev[1]; 3385 dev1 = hw->dev[1];
3347 if (dev1) 3386 if (dev1)