aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-05-09 13:18:35 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-05-09 13:18:35 -0400
commit3cd73eedde34c5fd88d62d8523c4260970fdc6fb (patch)
tree8aa8915ae6befb482a649365c32d7e5526d9755d /drivers/net/sky2.c
parentc51e078f82096a7d35ac8ec2416272e843a0e1c4 (diff)
parent23aee82e75c1ced9492cbff6090b8e213d95945e (diff)
Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/netdev-2.6
* 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/netdev-2.6: [PATCH] bcm43xx: Fix access to non-existent PHY registers [PATCH] bcm43xx: Fix array overrun in bcm43xx_geo_init [PATCH] bcm43xx: check for valid MAC address in SPROM [PATCH] ieee80211: Fix A band channel count (resent) [PATCH] bcm43xx: fix iwmode crash when down [PATCH] softmac: make non-operational after being stopped [PATCH] softmac: don't reassociate if user asked for deauthentication spidernet: enable support for bcm5461 ethernet phy spidernet: introduce new setting Fix RTL8019AS init for Toshiba RBTX49xx boards au1000_eth.c: use ether_crc() from <linux/crc32.h> sky2: version 1.3 Add more support for the Yukon Ultra chip found in dual core centino laptops. sky2: synchronize irq on remove sky2: dont write status ring sky2: edge triggered workaround enhancement sky2: use mask instead of modulo operation sky2: tx ring index mask fix sky2: status irq hang fix sky2: backout NAPI reschedule
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c217
1 files changed, 117 insertions, 100 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 227df9876a2c..60cdfcabe1fd 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.3"
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,6 +98,10 @@ 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) },
@@ -298,7 +304,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
298 struct sky2_port *sky2 = netdev_priv(hw->dev[port]); 304 struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
299 u16 ctrl, ct1000, adv, pg, ledctrl, ledover; 305 u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
300 306
301 if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) { 307 if (sky2->autoneg == AUTONEG_ENABLE &&
308 (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); 309 u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
303 310
304 ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | 311 ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
@@ -326,7 +333,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
326 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); 333 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
327 334
328 if (sky2->autoneg == AUTONEG_ENABLE && 335 if (sky2->autoneg == AUTONEG_ENABLE &&
329 hw->chip_id == CHIP_ID_YUKON_XL) { 336 (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
330 ctrl &= ~PHY_M_PC_DSC_MSK; 337 ctrl &= ~PHY_M_PC_DSC_MSK;
331 ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; 338 ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
332 } 339 }
@@ -442,10 +449,11 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
442 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); 449 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
443 450
444 /* set LED Function Control register */ 451 /* set LED Function Control register */
445 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ 452 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
446 PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ 453 (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */
447 PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ 454 PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */
448 PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ 455 PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
456 PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */
449 457
450 /* set Polarity Control register */ 458 /* set Polarity Control register */
451 gm_phy_write(hw, port, PHY_MARV_PHY_STAT, 459 gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
@@ -459,6 +467,25 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
459 /* restore page register */ 467 /* restore page register */
460 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); 468 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
461 break; 469 break;
470 case CHIP_ID_YUKON_EC_U:
471 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
472
473 /* select page 3 to access LED control register */
474 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
475
476 /* set LED Function Control register */
477 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
478 (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */
479 PHY_M_LEDC_INIT_CTRL(8) | /* 10 Mbps */
480 PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
481 PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */
482
483 /* set Blink Rate in LED Timer Control Register */
484 gm_phy_write(hw, port, PHY_MARV_INT_MASK,
485 ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS));
486 /* restore page register */
487 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
488 break;
462 489
463 default: 490 default:
464 /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ 491 /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
@@ -467,19 +494,21 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
467 ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); 494 ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
468 } 495 }
469 496
470 if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { 497 if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) {
471 /* apply fixes in PHY AFE */ 498 /* apply fixes in PHY AFE */
472 gm_phy_write(hw, port, 22, 255); 499 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
500 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
501
473 /* increase differential signal amplitude in 10BASE-T */ 502 /* increase differential signal amplitude in 10BASE-T */
474 gm_phy_write(hw, port, 24, 0xaa99); 503 gm_phy_write(hw, port, 0x18, 0xaa99);
475 gm_phy_write(hw, port, 23, 0x2011); 504 gm_phy_write(hw, port, 0x17, 0x2011);
476 505
477 /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ 506 /* fix for IEEE A/B Symmetry failure in 1000BASE-T */
478 gm_phy_write(hw, port, 24, 0xa204); 507 gm_phy_write(hw, port, 0x18, 0xa204);
479 gm_phy_write(hw, port, 23, 0x2002); 508 gm_phy_write(hw, port, 0x17, 0x2002);
480 509
481 /* set page register to 0 */ 510 /* set page register to 0 */
482 gm_phy_write(hw, port, 22, 0); 511 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
483 } else { 512 } else {
484 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); 513 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
485 514
@@ -553,6 +582,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
553 582
554 if (sky2->duplex == DUPLEX_FULL) 583 if (sky2->duplex == DUPLEX_FULL)
555 reg |= GM_GPCR_DUP_FULL; 584 reg |= GM_GPCR_DUP_FULL;
585
586 /* turn off pause in 10/100mbps half duplex */
587 else if (sky2->speed != SPEED_1000 &&
588 hw->chip_id != CHIP_ID_YUKON_EC_U)
589 sky2->tx_pause = sky2->rx_pause = 0;
556 } else 590 } else
557 reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; 591 reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
558 592
@@ -719,7 +753,7 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
719{ 753{
720 struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod; 754 struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
721 755
722 sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE; 756 sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
723 return le; 757 return le;
724} 758}
725 759
@@ -735,7 +769,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) 769static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
736{ 770{
737 struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put; 771 struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
738 sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE; 772 sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
739 return le; 773 return le;
740} 774}
741 775
@@ -1078,7 +1112,7 @@ err_out:
1078/* Modular subtraction in ring */ 1112/* Modular subtraction in ring */
1079static inline int tx_dist(unsigned tail, unsigned head) 1113static inline int tx_dist(unsigned tail, unsigned head)
1080{ 1114{
1081 return (head - tail) % TX_RING_SIZE; 1115 return (head - tail) & (TX_RING_SIZE - 1);
1082} 1116}
1083 1117
1084/* Number of list elements available for next tx */ 1118/* Number of list elements available for next tx */
@@ -1255,7 +1289,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1255 le->opcode = OP_BUFFER | HW_OWNER; 1289 le->opcode = OP_BUFFER | HW_OWNER;
1256 1290
1257 fre = sky2->tx_ring 1291 fre = sky2->tx_ring
1258 + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE; 1292 + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE);
1259 pci_unmap_addr_set(fre, mapaddr, mapping); 1293 pci_unmap_addr_set(fre, mapaddr, mapping);
1260 } 1294 }
1261 1295
@@ -1315,7 +1349,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1315 1349
1316 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 1350 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1317 struct tx_ring_info *fre; 1351 struct tx_ring_info *fre;
1318 fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE; 1352 fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE);
1319 pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr), 1353 pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
1320 skb_shinfo(skb)->frags[i].size, 1354 skb_shinfo(skb)->frags[i].size,
1321 PCI_DMA_TODEVICE); 1355 PCI_DMA_TODEVICE);
@@ -1498,17 +1532,26 @@ static void sky2_link_up(struct sky2_port *sky2)
1498 sky2_write8(hw, SK_REG(port, LNK_LED_REG), 1532 sky2_write8(hw, SK_REG(port, LNK_LED_REG),
1499 LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); 1533 LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
1500 1534
1501 if (hw->chip_id == CHIP_ID_YUKON_XL) { 1535 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); 1536 u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
1537 u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */
1538
1539 switch(sky2->speed) {
1540 case SPEED_10:
1541 led |= PHY_M_LEDC_INIT_CTRL(7);
1542 break;
1543
1544 case SPEED_100:
1545 led |= PHY_M_LEDC_STA1_CTRL(7);
1546 break;
1547
1548 case SPEED_1000:
1549 led |= PHY_M_LEDC_STA0_CTRL(7);
1550 break;
1551 }
1503 1552
1504 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); 1553 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 */ 1554 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); 1555 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
1513 } 1556 }
1514 1557
@@ -1583,7 +1626,7 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
1583 sky2->speed = sky2_phy_speed(hw, aux); 1626 sky2->speed = sky2_phy_speed(hw, aux);
1584 1627
1585 /* Pause bits are offset (9..8) */ 1628 /* Pause bits are offset (9..8) */
1586 if (hw->chip_id == CHIP_ID_YUKON_XL) 1629 if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)
1587 aux >>= 6; 1630 aux >>= 6;
1588 1631
1589 sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; 1632 sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0;
@@ -1859,35 +1902,28 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
1859static int sky2_status_intr(struct sky2_hw *hw, int to_do) 1902static int sky2_status_intr(struct sky2_hw *hw, int to_do)
1860{ 1903{
1861 int work_done = 0; 1904 int work_done = 0;
1905 u16 hwidx = sky2_read16(hw, STAT_PUT_IDX);
1862 1906
1863 rmb(); 1907 rmb();
1864 1908
1865 for(;;) { 1909 while (hw->st_idx != hwidx) {
1866 struct sky2_status_le *le = hw->st_le + hw->st_idx; 1910 struct sky2_status_le *le = hw->st_le + hw->st_idx;
1867 struct net_device *dev; 1911 struct net_device *dev;
1868 struct sky2_port *sky2; 1912 struct sky2_port *sky2;
1869 struct sk_buff *skb; 1913 struct sk_buff *skb;
1870 u32 status; 1914 u32 status;
1871 u16 length; 1915 u16 length;
1872 u8 link, opcode;
1873 1916
1874 opcode = le->opcode; 1917 hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
1875 if (!opcode)
1876 break;
1877 opcode &= ~HW_OWNER;
1878
1879 hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE;
1880 le->opcode = 0;
1881 1918
1882 link = le->link; 1919 BUG_ON(le->link >= 2);
1883 BUG_ON(link >= 2); 1920 dev = hw->dev[le->link];
1884 dev = hw->dev[link];
1885 1921
1886 sky2 = netdev_priv(dev); 1922 sky2 = netdev_priv(dev);
1887 length = le->length; 1923 length = le->length;
1888 status = le->status; 1924 status = le->status;
1889 1925
1890 switch (opcode) { 1926 switch (le->opcode & ~HW_OWNER) {
1891 case OP_RXSTAT: 1927 case OP_RXSTAT:
1892 skb = sky2_receive(sky2, length, status); 1928 skb = sky2_receive(sky2, length, status);
1893 if (!skb) 1929 if (!skb)
@@ -1927,7 +1963,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
1927 1963
1928 case OP_TXINDEXLE: 1964 case OP_TXINDEXLE:
1929 /* TX index reports status for both ports */ 1965 /* TX index reports status for both ports */
1930 sky2_tx_done(hw->dev[0], status & 0xffff); 1966 BUILD_BUG_ON(TX_RING_SIZE > 0x1000);
1967 sky2_tx_done(hw->dev[0], status & 0xfff);
1931 if (hw->dev[1]) 1968 if (hw->dev[1])
1932 sky2_tx_done(hw->dev[1], 1969 sky2_tx_done(hw->dev[1],
1933 ((status >> 24) & 0xff) 1970 ((status >> 24) & 0xff)
@@ -1937,8 +1974,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
1937 default: 1974 default:
1938 if (net_ratelimit()) 1975 if (net_ratelimit())
1939 printk(KERN_WARNING PFX 1976 printk(KERN_WARNING PFX
1940 "unknown status opcode 0x%x\n", opcode); 1977 "unknown status opcode 0x%x\n", le->opcode);
1941 break; 1978 goto exit_loop;
1942 } 1979 }
1943 } 1980 }
1944 1981
@@ -2089,12 +2126,13 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port,
2089 */ 2126 */
2090static void sky2_idle(unsigned long arg) 2127static void sky2_idle(unsigned long arg)
2091{ 2128{
2092 struct net_device *dev = (struct net_device *) arg; 2129 struct sky2_hw *hw = (struct sky2_hw *) arg;
2130 struct net_device *dev = hw->dev[0];
2093 2131
2094 local_irq_disable();
2095 if (__netif_rx_schedule_prep(dev)) 2132 if (__netif_rx_schedule_prep(dev))
2096 __netif_rx_schedule(dev); 2133 __netif_rx_schedule(dev);
2097 local_irq_enable(); 2134
2135 mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout));
2098} 2136}
2099 2137
2100 2138
@@ -2105,65 +2143,46 @@ static int sky2_poll(struct net_device *dev0, int *budget)
2105 int work_done = 0; 2143 int work_done = 0;
2106 u32 status = sky2_read32(hw, B0_Y2_SP_EISR); 2144 u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
2107 2145
2108 restart_poll: 2146 if (status & Y2_IS_HW_ERR)
2109 if (unlikely(status & ~Y2_IS_STAT_BMU)) { 2147 sky2_hw_intr(hw);
2110 if (status & Y2_IS_HW_ERR)
2111 sky2_hw_intr(hw);
2112
2113 if (status & Y2_IS_IRQ_PHY1)
2114 sky2_phy_intr(hw, 0);
2115
2116 if (status & Y2_IS_IRQ_PHY2)
2117 sky2_phy_intr(hw, 1);
2118 2148
2119 if (status & Y2_IS_IRQ_MAC1) 2149 if (status & Y2_IS_IRQ_PHY1)
2120 sky2_mac_intr(hw, 0); 2150 sky2_phy_intr(hw, 0);
2121 2151
2122 if (status & Y2_IS_IRQ_MAC2) 2152 if (status & Y2_IS_IRQ_PHY2)
2123 sky2_mac_intr(hw, 1); 2153 sky2_phy_intr(hw, 1);
2124 2154
2125 if (status & Y2_IS_CHK_RX1) 2155 if (status & Y2_IS_IRQ_MAC1)
2126 sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1); 2156 sky2_mac_intr(hw, 0);
2127 2157
2128 if (status & Y2_IS_CHK_RX2) 2158 if (status & Y2_IS_IRQ_MAC2)
2129 sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2); 2159 sky2_mac_intr(hw, 1);
2130 2160
2131 if (status & Y2_IS_CHK_TXA1) 2161 if (status & Y2_IS_CHK_RX1)
2132 sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1); 2162 sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1);
2133 2163
2134 if (status & Y2_IS_CHK_TXA2) 2164 if (status & Y2_IS_CHK_RX2)
2135 sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); 2165 sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2);
2136 }
2137 2166
2138 if (status & Y2_IS_STAT_BMU) { 2167 if (status & Y2_IS_CHK_TXA1)
2139 work_done += sky2_status_intr(hw, work_limit - work_done); 2168 sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1);
2140 *budget -= work_done;
2141 dev0->quota -= work_done;
2142 2169
2143 if (work_done >= work_limit) 2170 if (status & Y2_IS_CHK_TXA2)
2144 return 1; 2171 sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
2145 2172
2173 if (status & Y2_IS_STAT_BMU)
2146 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); 2174 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
2147 }
2148
2149 mod_timer(&hw->idle_timer, jiffies + HZ);
2150 2175
2151 local_irq_disable(); 2176 work_done = sky2_status_intr(hw, work_limit);
2152 __netif_rx_complete(dev0); 2177 *budget -= work_done;
2178 dev0->quota -= work_done;
2153 2179
2154 status = sky2_read32(hw, B0_Y2_SP_LISR); 2180 if (work_done >= work_limit)
2181 return 1;
2155 2182
2156 if (unlikely(status)) { 2183 netif_rx_complete(dev0);
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 2184
2166 local_irq_enable(); 2185 status = sky2_read32(hw, B0_Y2_SP_LISR);
2167 return 0; 2186 return 0;
2168} 2187}
2169 2188
@@ -2244,13 +2263,6 @@ static int __devinit sky2_reset(struct sky2_hw *hw)
2244 return -EOPNOTSUPP; 2263 return -EOPNOTSUPP;
2245 } 2264 }
2246 2265
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 */ 2266 /* disable ASF */
2255 if (hw->chip_id <= CHIP_ID_YUKON_EC) { 2267 if (hw->chip_id <= CHIP_ID_YUKON_EC) {
2256 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); 2268 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
@@ -3302,7 +3314,10 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3302 3314
3303 sky2_write32(hw, B0_IMSK, Y2_IS_BASE); 3315 sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
3304 3316
3305 setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev); 3317 setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
3318 if (idle_timeout > 0)
3319 mod_timer(&hw->idle_timer,
3320 jiffies + msecs_to_jiffies(idle_timeout));
3306 3321
3307 pci_set_drvdata(pdev, hw); 3322 pci_set_drvdata(pdev, hw);
3308 3323
@@ -3342,6 +3357,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
3342 del_timer_sync(&hw->idle_timer); 3357 del_timer_sync(&hw->idle_timer);
3343 3358
3344 sky2_write32(hw, B0_IMSK, 0); 3359 sky2_write32(hw, B0_IMSK, 0);
3360 synchronize_irq(hw->pdev->irq);
3361
3345 dev0 = hw->dev[0]; 3362 dev0 = hw->dev[0];
3346 dev1 = hw->dev[1]; 3363 dev1 = hw->dev[1];
3347 if (dev1) 3364 if (dev1)