aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIshizaki Kou <kou.ishizaki@toshiba.co.jp>2008-04-10 23:32:30 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-16 20:06:50 -0400
commit9a11fcb5215d6ecade9aca1f1fba272746a3882d (patch)
treeadf3d70d05fefb026557417b673a7fb0aac5b2a5
parentfcfcfa205ef59f10d80e67a1762ad27e765d4868 (diff)
spidernet: fix error interrupt handling
In addition to the value of GHIINT0STS, spidernet interrupt handler should check the values of GHIINT1STS/GHIINT2STS registers at the beginning of spider_net_interrupt() so as not to drop error interrupts. GHIINT1STS/GHIINT2STS registers indicates some of erroneous conditions in spidernet, and a few bits of GHIINT0STS register reflects these conditions. But GHIINT0MSK masks these bits, so you should check these conditions by reading GHIINT1STS/GHIINT2STS registers directly. Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp> Acked-by: Jens Osterkamp <jens@de.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/net/spider_net.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index f7781ec181f3..e8b3b0802e73 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1415,18 +1415,12 @@ spider_net_link_reset(struct net_device *netdev)
1415 * found when an interrupt is presented 1415 * found when an interrupt is presented
1416 */ 1416 */
1417static void 1417static void
1418spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) 1418spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
1419 u32 error_reg1, u32 error_reg2)
1419{ 1420{
1420 u32 error_reg1, error_reg2;
1421 u32 i; 1421 u32 i;
1422 int show_error = 1; 1422 int show_error = 1;
1423 1423
1424 error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
1425 error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
1426
1427 error_reg1 &= SPIDER_NET_INT1_MASK_VALUE;
1428 error_reg2 &= SPIDER_NET_INT2_MASK_VALUE;
1429
1430 /* check GHIINT0STS ************************************/ 1424 /* check GHIINT0STS ************************************/
1431 if (status_reg) 1425 if (status_reg)
1432 for (i = 0; i < 32; i++) 1426 for (i = 0; i < 32; i++)
@@ -1656,12 +1650,15 @@ spider_net_interrupt(int irq, void *ptr)
1656{ 1650{
1657 struct net_device *netdev = ptr; 1651 struct net_device *netdev = ptr;
1658 struct spider_net_card *card = netdev_priv(netdev); 1652 struct spider_net_card *card = netdev_priv(netdev);
1659 u32 status_reg; 1653 u32 status_reg, error_reg1, error_reg2;
1660 1654
1661 status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS); 1655 status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS);
1662 status_reg &= SPIDER_NET_INT0_MASK_VALUE; 1656 error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
1657 error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
1663 1658
1664 if (!status_reg) 1659 if (!(status_reg & SPIDER_NET_INT0_MASK_VALUE) &&
1660 !(error_reg1 & SPIDER_NET_INT1_MASK_VALUE) &&
1661 !(error_reg2 & SPIDER_NET_INT2_MASK_VALUE))
1665 return IRQ_NONE; 1662 return IRQ_NONE;
1666 1663
1667 if (status_reg & SPIDER_NET_RXINT ) { 1664 if (status_reg & SPIDER_NET_RXINT ) {
@@ -1676,7 +1673,8 @@ spider_net_interrupt(int irq, void *ptr)
1676 spider_net_link_reset(netdev); 1673 spider_net_link_reset(netdev);
1677 1674
1678 if (status_reg & SPIDER_NET_ERRINT ) 1675 if (status_reg & SPIDER_NET_ERRINT )
1679 spider_net_handle_error_irq(card, status_reg); 1676 spider_net_handle_error_irq(card, status_reg,
1677 error_reg1, error_reg2);
1680 1678
1681 /* clear interrupt sources */ 1679 /* clear interrupt sources */
1682 spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg); 1680 spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg);