aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-03-20 18:48:17 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-21 16:00:52 -0500
commite07b1aa8b3ebedd3c7e0e1b4b524f1b2d62707cf (patch)
tree15e96ea55b6463d2b75eb94293230d8ee6345165 /drivers/net/sky2.c
parentc4b1580e8ad1aab13e0d8b97c7af3eebab8791ae (diff)
[PATCH] sky2: rework of NAPI and IRQ management
Redo the interupt handling of sky2 driver based on the IRQ mangement documentation. All interrupts are handled by the device0 NAPI poll routine. Don't need to adjust interrupt mask in IRQ context, done only when changing device under RTNL. Therefore don't need hwlock anymore. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c276
1 files changed, 107 insertions, 169 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 3a6c796eb70e..41dbe588de30 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -500,9 +500,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
500/* Force a renegotiation */ 500/* Force a renegotiation */
501static void sky2_phy_reinit(struct sky2_port *sky2) 501static void sky2_phy_reinit(struct sky2_port *sky2)
502{ 502{
503 down(&sky2->phy_sema); 503 spin_lock_bh(&sky2->phy_lock);
504 sky2_phy_init(sky2->hw, sky2->port); 504 sky2_phy_init(sky2->hw, sky2->port);
505 up(&sky2->phy_sema); 505 spin_unlock_bh(&sky2->phy_lock);
506} 506}
507 507
508static void sky2_mac_init(struct sky2_hw *hw, unsigned port) 508static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
@@ -567,9 +567,9 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
567 567
568 sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC)); 568 sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
569 569
570 down(&sky2->phy_sema); 570 spin_lock_bh(&sky2->phy_lock);
571 sky2_phy_init(hw, port); 571 sky2_phy_init(hw, port);
572 up(&sky2->phy_sema); 572 spin_unlock_bh(&sky2->phy_lock);
573 573
574 /* MIB clear */ 574 /* MIB clear */
575 reg = gma_read16(hw, port, GM_PHY_ADDR); 575 reg = gma_read16(hw, port, GM_PHY_ADDR);
@@ -856,9 +856,9 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
856 case SIOCGMIIREG: { 856 case SIOCGMIIREG: {
857 u16 val = 0; 857 u16 val = 0;
858 858
859 down(&sky2->phy_sema); 859 spin_lock_bh(&sky2->phy_lock);
860 err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val); 860 err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val);
861 up(&sky2->phy_sema); 861 spin_unlock_bh(&sky2->phy_lock);
862 862
863 data->val_out = val; 863 data->val_out = val;
864 break; 864 break;
@@ -868,10 +868,10 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
868 if (!capable(CAP_NET_ADMIN)) 868 if (!capable(CAP_NET_ADMIN))
869 return -EPERM; 869 return -EPERM;
870 870
871 down(&sky2->phy_sema); 871 spin_lock_bh(&sky2->phy_lock);
872 err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f, 872 err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f,
873 data->val_in); 873 data->val_in);
874 up(&sky2->phy_sema); 874 spin_unlock_bh(&sky2->phy_lock);
875 break; 875 break;
876 } 876 }
877 return err; 877 return err;
@@ -983,7 +983,7 @@ static int sky2_up(struct net_device *dev)
983 struct sky2_port *sky2 = netdev_priv(dev); 983 struct sky2_port *sky2 = netdev_priv(dev);
984 struct sky2_hw *hw = sky2->hw; 984 struct sky2_hw *hw = sky2->hw;
985 unsigned port = sky2->port; 985 unsigned port = sky2->port;
986 u32 ramsize, rxspace; 986 u32 ramsize, rxspace, imask;
987 int err = -ENOMEM; 987 int err = -ENOMEM;
988 988
989 if (netif_msg_ifup(sky2)) 989 if (netif_msg_ifup(sky2))
@@ -1048,10 +1048,10 @@ static int sky2_up(struct net_device *dev)
1048 goto err_out; 1048 goto err_out;
1049 1049
1050 /* Enable interrupts from phy/mac for port */ 1050 /* Enable interrupts from phy/mac for port */
1051 spin_lock_irq(&hw->hw_lock); 1051 imask = sky2_read32(hw, B0_IMSK);
1052 hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; 1052 imask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
1053 sky2_write32(hw, B0_IMSK, hw->intr_mask); 1053 sky2_write32(hw, B0_IMSK, imask);
1054 spin_unlock_irq(&hw->hw_lock); 1054
1055 return 0; 1055 return 0;
1056 1056
1057err_out: 1057err_out:
@@ -1343,6 +1343,7 @@ static int sky2_down(struct net_device *dev)
1343 struct sky2_hw *hw = sky2->hw; 1343 struct sky2_hw *hw = sky2->hw;
1344 unsigned port = sky2->port; 1344 unsigned port = sky2->port;
1345 u16 ctrl; 1345 u16 ctrl;
1346 u32 imask;
1346 1347
1347 /* Never really got started! */ 1348 /* Never really got started! */
1348 if (!sky2->tx_le) 1349 if (!sky2->tx_le)
@@ -1354,14 +1355,6 @@ static int sky2_down(struct net_device *dev)
1354 /* Stop more packets from being queued */ 1355 /* Stop more packets from being queued */
1355 netif_stop_queue(dev); 1356 netif_stop_queue(dev);
1356 1357
1357 /* Disable port IRQ */
1358 spin_lock_irq(&hw->hw_lock);
1359 hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
1360 sky2_write32(hw, B0_IMSK, hw->intr_mask);
1361 spin_unlock_irq(&hw->hw_lock);
1362
1363 flush_scheduled_work();
1364
1365 sky2_phy_reset(hw, port); 1358 sky2_phy_reset(hw, port);
1366 1359
1367 /* Stop transmitter */ 1360 /* Stop transmitter */
@@ -1405,6 +1398,11 @@ static int sky2_down(struct net_device *dev)
1405 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); 1398 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
1406 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); 1399 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
1407 1400
1401 /* Disable port IRQ */
1402 imask = sky2_read32(hw, B0_IMSK);
1403 imask &= ~(sky2->port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
1404 sky2_write32(hw, B0_IMSK, imask);
1405
1408 /* turn off LED's */ 1406 /* turn off LED's */
1409 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); 1407 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
1410 1408
@@ -1599,20 +1597,19 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
1599 return 0; 1597 return 0;
1600} 1598}
1601 1599
1602/* 1600/* Interrupt from PHY */
1603 * Interrupt from PHY are handled outside of interrupt context 1601static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
1604 * because accessing phy registers requires spin wait which might
1605 * cause excess interrupt latency.
1606 */
1607static void sky2_phy_task(void *arg)
1608{ 1602{
1609 struct sky2_port *sky2 = arg; 1603 struct net_device *dev = hw->dev[port];
1610 struct sky2_hw *hw = sky2->hw; 1604 struct sky2_port *sky2 = netdev_priv(dev);
1611 u16 istatus, phystat; 1605 u16 istatus, phystat;
1612 1606
1613 down(&sky2->phy_sema); 1607 spin_lock(&sky2->phy_lock);
1614 istatus = gm_phy_read(hw, sky2->port, PHY_MARV_INT_STAT); 1608 istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
1615 phystat = gm_phy_read(hw, sky2->port, PHY_MARV_PHY_STAT); 1609 phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
1610
1611 if (!netif_running(dev))
1612 goto out;
1616 1613
1617 if (netif_msg_intr(sky2)) 1614 if (netif_msg_intr(sky2))
1618 printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", 1615 printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
@@ -1638,12 +1635,7 @@ static void sky2_phy_task(void *arg)
1638 sky2_link_down(sky2); 1635 sky2_link_down(sky2);
1639 } 1636 }
1640out: 1637out:
1641 up(&sky2->phy_sema); 1638 spin_unlock(&sky2->phy_lock);
1642
1643 spin_lock_irq(&hw->hw_lock);
1644 hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2;
1645 sky2_write32(hw, B0_IMSK, hw->intr_mask);
1646 spin_unlock_irq(&hw->hw_lock);
1647} 1639}
1648 1640
1649 1641
@@ -1655,20 +1647,6 @@ static void sky2_tx_timeout(struct net_device *dev)
1655 struct sky2_port *sky2 = netdev_priv(dev); 1647 struct sky2_port *sky2 = netdev_priv(dev);
1656 struct sky2_hw *hw = sky2->hw; 1648 struct sky2_hw *hw = sky2->hw;
1657 unsigned txq = txqaddr[sky2->port]; 1649 unsigned txq = txqaddr[sky2->port];
1658 u16 ridx;
1659
1660 /* Maybe we just missed an status interrupt */
1661 spin_lock(&sky2->tx_lock);
1662 ridx = sky2_read16(hw,
1663 sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX);
1664 sky2_tx_complete(sky2, ridx);
1665 spin_unlock(&sky2->tx_lock);
1666
1667 if (!netif_queue_stopped(dev)) {
1668 if (net_ratelimit())
1669 pr_info(PFX "transmit interrupt missed? recovered\n");
1670 return;
1671 }
1672 1650
1673 if (netif_msg_timer(sky2)) 1651 if (netif_msg_timer(sky2))
1674 printk(KERN_ERR PFX "%s: tx timeout\n", dev->name); 1652 printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
@@ -1698,6 +1676,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1698 struct sky2_hw *hw = sky2->hw; 1676 struct sky2_hw *hw = sky2->hw;
1699 int err; 1677 int err;
1700 u16 ctl, mode; 1678 u16 ctl, mode;
1679 u32 imask;
1701 1680
1702 if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) 1681 if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
1703 return -EINVAL; 1682 return -EINVAL;
@@ -1710,12 +1689,15 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1710 return 0; 1689 return 0;
1711 } 1690 }
1712 1691
1692 imask = sky2_read32(hw, B0_IMSK);
1713 sky2_write32(hw, B0_IMSK, 0); 1693 sky2_write32(hw, B0_IMSK, 0);
1714 1694
1715 dev->trans_start = jiffies; /* prevent tx timeout */ 1695 dev->trans_start = jiffies; /* prevent tx timeout */
1716 netif_stop_queue(dev); 1696 netif_stop_queue(dev);
1717 netif_poll_disable(hw->dev[0]); 1697 netif_poll_disable(hw->dev[0]);
1718 1698
1699 synchronize_irq(hw->pdev->irq);
1700
1719 ctl = gma_read16(hw, sky2->port, GM_GP_CTRL); 1701 ctl = gma_read16(hw, sky2->port, GM_GP_CTRL);
1720 gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); 1702 gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
1721 sky2_rx_stop(sky2); 1703 sky2_rx_stop(sky2);
@@ -1734,7 +1716,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1734 sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD); 1716 sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD);
1735 1717
1736 err = sky2_rx_start(sky2); 1718 err = sky2_rx_start(sky2);
1737 sky2_write32(hw, B0_IMSK, hw->intr_mask); 1719 sky2_write32(hw, B0_IMSK, imask);
1738 1720
1739 if (err) 1721 if (err)
1740 dev_close(dev); 1722 dev_close(dev);
@@ -1838,76 +1820,51 @@ error:
1838 goto resubmit; 1820 goto resubmit;
1839} 1821}
1840 1822
1841/* 1823/* Transmit complete */
1842 * Check for transmit complete 1824static inline void sky2_tx_done(struct net_device *dev, u16 last)
1843 */
1844#define TX_NO_STATUS 0xffff
1845
1846static void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
1847{ 1825{
1848 if (last != TX_NO_STATUS) { 1826 struct sky2_port *sky2 = netdev_priv(dev);
1849 struct net_device *dev = hw->dev[port];
1850 if (dev && netif_running(dev)) {
1851 struct sky2_port *sky2 = netdev_priv(dev);
1852 1827
1853 spin_lock(&sky2->tx_lock); 1828 if (netif_running(dev)) {
1854 sky2_tx_complete(sky2, last); 1829 spin_lock(&sky2->tx_lock);
1855 spin_unlock(&sky2->tx_lock); 1830 sky2_tx_complete(sky2, last);
1856 } 1831 spin_unlock(&sky2->tx_lock);
1857 } 1832 }
1858} 1833}
1859 1834
1860/* 1835/* Process status response ring */
1861 * Both ports share the same status interrupt, therefore there is only 1836static int sky2_status_intr(struct sky2_hw *hw, int to_do)
1862 * one poll routine.
1863 */
1864static int sky2_poll(struct net_device *dev0, int *budget)
1865{ 1837{
1866 struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; 1838 int work_done = 0;
1867 unsigned int to_do = min(dev0->quota, *budget);
1868 unsigned int work_done = 0;
1869 u16 hwidx;
1870 u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
1871
1872 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
1873
1874 /*
1875 * Kick the STAT_LEV_TIMER_CTRL timer.
1876 * This fixes my hangs on Yukon-EC (0xb6) rev 1.
1877 * The if clause is there to start the timer only if it has been
1878 * configured correctly and not been disabled via ethtool.
1879 */
1880 if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) {
1881 sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
1882 sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
1883 }
1884 1839
1885 hwidx = sky2_read16(hw, STAT_PUT_IDX);
1886 BUG_ON(hwidx >= STATUS_RING_SIZE);
1887 rmb(); 1840 rmb();
1888 1841
1889 while (hwidx != hw->st_idx) { 1842 for(;;) {
1890 struct sky2_status_le *le = hw->st_le + hw->st_idx; 1843 struct sky2_status_le *le = hw->st_le + hw->st_idx;
1891 struct net_device *dev; 1844 struct net_device *dev;
1892 struct sky2_port *sky2; 1845 struct sky2_port *sky2;
1893 struct sk_buff *skb; 1846 struct sk_buff *skb;
1894 u32 status; 1847 u32 status;
1895 u16 length; 1848 u16 length;
1849 u8 link, opcode;
1850
1851 opcode = le->opcode;
1852 if (!opcode)
1853 break;
1854 opcode &= ~HW_OWNER;
1896 1855
1897 le = hw->st_le + hw->st_idx;
1898 hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE; 1856 hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE;
1899 prefetch(hw->st_le + hw->st_idx); 1857 le->opcode = 0;
1900 1858
1901 BUG_ON(le->link >= 2); 1859 link = le->link;
1902 dev = hw->dev[le->link]; 1860 BUG_ON(link >= 2);
1903 if (dev == NULL || !netif_running(dev)) 1861 dev = hw->dev[link];
1904 continue;
1905 1862
1906 sky2 = netdev_priv(dev); 1863 sky2 = netdev_priv(dev);
1907 status = le32_to_cpu(le->status); 1864 length = le->length;
1908 length = le16_to_cpu(le->length); 1865 status = le->status;
1909 1866
1910 switch (le->opcode & ~HW_OWNER) { 1867 switch (opcode) {
1911 case OP_RXSTAT: 1868 case OP_RXSTAT:
1912 skb = sky2_receive(sky2, length, status); 1869 skb = sky2_receive(sky2, length, status);
1913 if (!skb) 1870 if (!skb)
@@ -1947,42 +1904,23 @@ static int sky2_poll(struct net_device *dev0, int *budget)
1947 1904
1948 case OP_TXINDEXLE: 1905 case OP_TXINDEXLE:
1949 /* TX index reports status for both ports */ 1906 /* TX index reports status for both ports */
1950 tx_done[0] = status & 0xffff; 1907 sky2_tx_done(hw->dev[0], status & 0xffff);
1951 tx_done[1] = ((status >> 24) & 0xff) 1908 if (hw->dev[1])
1952 | (u16)(length & 0xf) << 8; 1909 sky2_tx_done(hw->dev[1],
1910 ((status >> 24) & 0xff)
1911 | (u16)(length & 0xf) << 8);
1953 break; 1912 break;
1954 1913
1955 default: 1914 default:
1956 if (net_ratelimit()) 1915 if (net_ratelimit())
1957 printk(KERN_WARNING PFX 1916 printk(KERN_WARNING PFX
1958 "unknown status opcode 0x%x\n", le->opcode); 1917 "unknown status opcode 0x%x\n", opcode);
1959 break; 1918 break;
1960 } 1919 }
1961 } 1920 }
1962 1921
1963exit_loop: 1922exit_loop:
1964 sky2_tx_check(hw, 0, tx_done[0]); 1923 return work_done;
1965 sky2_tx_check(hw, 1, tx_done[1]);
1966
1967 if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
1968 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
1969 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
1970 }
1971
1972 if (likely(work_done < to_do)) {
1973 spin_lock_irq(&hw->hw_lock);
1974 __netif_rx_complete(dev0);
1975
1976 hw->intr_mask |= Y2_IS_STAT_BMU;
1977 sky2_write32(hw, B0_IMSK, hw->intr_mask);
1978 spin_unlock_irq(&hw->hw_lock);
1979
1980 return 0;
1981 } else {
1982 *budget -= work_done;
1983 dev0->quota -= work_done;
1984 return 1;
1985 }
1986} 1924}
1987 1925
1988static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status) 1926static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
@@ -2101,42 +2039,17 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
2101 } 2039 }
2102} 2040}
2103 2041
2104static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
2105{
2106 struct net_device *dev = hw->dev[port];
2107 struct sky2_port *sky2 = netdev_priv(dev);
2108
2109 hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
2110 sky2_write32(hw, B0_IMSK, hw->intr_mask);
2111
2112 schedule_work(&sky2->phy_task);
2113}
2114 2042
2115static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) 2043static int sky2_poll(struct net_device *dev0, int *budget)
2116{ 2044{
2117 struct sky2_hw *hw = dev_id; 2045 struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
2118 struct net_device *dev0 = hw->dev[0]; 2046 int work_limit = min(dev0->quota, *budget);
2119 u32 status; 2047 int work_done = 0;
2120 2048 u32 status = sky2_read32(hw, B0_ISRC);
2121 status = sky2_read32(hw, B0_Y2_SP_ISRC2);
2122 if (status == 0 || status == ~0)
2123 return IRQ_NONE;
2124 2049
2125 spin_lock(&hw->hw_lock);
2126 if (status & Y2_IS_HW_ERR) 2050 if (status & Y2_IS_HW_ERR)
2127 sky2_hw_intr(hw); 2051 sky2_hw_intr(hw);
2128 2052
2129 /* Do NAPI for Rx and Tx status */
2130 if (status & Y2_IS_STAT_BMU) {
2131 hw->intr_mask &= ~Y2_IS_STAT_BMU;
2132 sky2_write32(hw, B0_IMSK, hw->intr_mask);
2133
2134 if (likely(__netif_rx_schedule_prep(dev0))) {
2135 prefetch(&hw->st_le[hw->st_idx]);
2136 __netif_rx_schedule(dev0);
2137 }
2138 }
2139
2140 if (status & Y2_IS_IRQ_PHY1) 2053 if (status & Y2_IS_IRQ_PHY1)
2141 sky2_phy_intr(hw, 0); 2054 sky2_phy_intr(hw, 0);
2142 2055
@@ -2149,9 +2062,38 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
2149 if (status & Y2_IS_IRQ_MAC2) 2062 if (status & Y2_IS_IRQ_MAC2)
2150 sky2_mac_intr(hw, 1); 2063 sky2_mac_intr(hw, 1);
2151 2064
2065 if (status & Y2_IS_STAT_BMU) {
2066 work_done = sky2_status_intr(hw, work_limit);
2067 *budget -= work_done;
2068 dev0->quota -= work_done;
2069
2070 if (work_done >= work_limit)
2071 return 1;
2072
2073 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
2074 }
2075
2076 netif_rx_complete(dev0);
2077
2078 /* Ack interrupt and re-enable */
2152 sky2_write32(hw, B0_Y2_SP_ICR, 2); 2079 sky2_write32(hw, B0_Y2_SP_ICR, 2);
2080 return 0;
2081}
2082
2083static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
2084{
2085 struct sky2_hw *hw = dev_id;
2086 struct net_device *dev0 = hw->dev[0];
2087 u32 status;
2088
2089 /* Reading this mask interrupts as side effect */
2090 status = sky2_read32(hw, B0_Y2_SP_ISRC2);
2091 if (status == 0 || status == ~0)
2092 return IRQ_NONE;
2153 2093
2154 spin_unlock(&hw->hw_lock); 2094 prefetch(&hw->st_le[hw->st_idx]);
2095 if (likely(__netif_rx_schedule_prep(dev0)))
2096 __netif_rx_schedule(dev0);
2155 2097
2156 return IRQ_HANDLED; 2098 return IRQ_HANDLED;
2157} 2099}
@@ -2320,7 +2262,6 @@ static int sky2_reset(struct sky2_hw *hw)
2320 /* Set the list last index */ 2262 /* Set the list last index */
2321 sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); 2263 sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);
2322 2264
2323 /* These status setup values are copied from SysKonnect's driver */
2324 sky2_write16(hw, STAT_TX_IDX_TH, 10); 2265 sky2_write16(hw, STAT_TX_IDX_TH, 10);
2325 sky2_write8(hw, STAT_FIFO_WM, 16); 2266 sky2_write8(hw, STAT_FIFO_WM, 16);
2326 2267
@@ -2714,7 +2655,7 @@ static int sky2_phys_id(struct net_device *dev, u32 data)
2714 ms = data * 1000; 2655 ms = data * 1000;
2715 2656
2716 /* save initial values */ 2657 /* save initial values */
2717 down(&sky2->phy_sema); 2658 spin_lock_bh(&sky2->phy_lock);
2718 if (hw->chip_id == CHIP_ID_YUKON_XL) { 2659 if (hw->chip_id == CHIP_ID_YUKON_XL) {
2719 u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); 2660 u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
2720 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); 2661 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
@@ -2730,9 +2671,9 @@ static int sky2_phys_id(struct net_device *dev, u32 data)
2730 sky2_led(hw, port, onoff); 2671 sky2_led(hw, port, onoff);
2731 onoff = !onoff; 2672 onoff = !onoff;
2732 2673
2733 up(&sky2->phy_sema); 2674 spin_unlock_bh(&sky2->phy_lock);
2734 interrupted = msleep_interruptible(250); 2675 interrupted = msleep_interruptible(250);
2735 down(&sky2->phy_sema); 2676 spin_lock_bh(&sky2->phy_lock);
2736 2677
2737 ms -= 250; 2678 ms -= 250;
2738 } 2679 }
@@ -2747,7 +2688,7 @@ static int sky2_phys_id(struct net_device *dev, u32 data)
2747 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); 2688 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
2748 gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); 2689 gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
2749 } 2690 }
2750 up(&sky2->phy_sema); 2691 spin_unlock_bh(&sky2->phy_lock);
2751 2692
2752 return 0; 2693 return 0;
2753} 2694}
@@ -3023,8 +2964,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3023 */ 2964 */
3024 sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); 2965 sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
3025 2966
3026 INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2); 2967 spin_lock_init(&sky2->phy_lock);
3027 init_MUTEX(&sky2->phy_sema);
3028 sky2->tx_pending = TX_DEF_PENDING; 2968 sky2->tx_pending = TX_DEF_PENDING;
3029 sky2->rx_pending = RX_DEF_PENDING; 2969 sky2->rx_pending = RX_DEF_PENDING;
3030 sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN); 2970 sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
@@ -3136,7 +3076,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3136 goto err_out_free_hw; 3076 goto err_out_free_hw;
3137 } 3077 }
3138 hw->pm_cap = pm_cap; 3078 hw->pm_cap = pm_cap;
3139 spin_lock_init(&hw->hw_lock);
3140 3079
3141#ifdef __BIG_ENDIAN 3080#ifdef __BIG_ENDIAN
3142 /* byte swap descriptors in hardware */ 3081 /* byte swap descriptors in hardware */
@@ -3196,8 +3135,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3196 goto err_out_unregister; 3135 goto err_out_unregister;
3197 } 3136 }
3198 3137
3199 hw->intr_mask = Y2_IS_BASE; 3138 sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
3200 sky2_write32(hw, B0_IMSK, hw->intr_mask);
3201 3139
3202 pci_set_drvdata(pdev, hw); 3140 pci_set_drvdata(pdev, hw);
3203 3141