diff options
author | shemminger@osdl.org <shemminger@osdl.org> | 2005-11-30 14:45:13 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-12-01 02:20:19 -0500 |
commit | 42eeea0145a1c7570624ddeaa15d3f357a52edf8 (patch) | |
tree | 4829f52d291508b251e2782e0b6d2d921fd9c858 /drivers/net | |
parent | ef743d3359813795fb38c4308bff2311eb30651f (diff) |
[PATCH] sky2: fix receive flush/pause issues
Fix issues with pause and flush. This code works on
all chip versions tested.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sky2.c | 20 |
1 files changed, 7 insertions, 13 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 0b9b70174168..83361aed49f6 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -485,8 +485,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
485 | int i; | 485 | int i; |
486 | const u8 *addr = hw->dev[port]->dev_addr; | 486 | const u8 *addr = hw->dev[port]->dev_addr; |
487 | 487 | ||
488 | sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); | 488 | sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
489 | sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); | 489 | sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE); |
490 | 490 | ||
491 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); | 491 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); |
492 | 492 | ||
@@ -589,11 +589,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
589 | GMF_RX_CTRL_DEF); | 589 | GMF_RX_CTRL_DEF); |
590 | 590 | ||
591 | /* Flush Rx MAC FIFO on any flow control or error */ | 591 | /* Flush Rx MAC FIFO on any flow control or error */ |
592 | reg = GMR_FS_ANY_ERR; | 592 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); |
593 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev <= 1) | ||
594 | reg = 0; /* WA dev #4.115 */ | ||
595 | 593 | ||
596 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), reg); | ||
597 | /* Set threshold to 0xa (64 bytes) | 594 | /* Set threshold to 0xa (64 bytes) |
598 | * ASF disabled so no need to do WA dev #4.30 | 595 | * ASF disabled so no need to do WA dev #4.30 |
599 | */ | 596 | */ |
@@ -1363,9 +1360,6 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
1363 | unsigned port = sky2->port; | 1360 | unsigned port = sky2->port; |
1364 | u16 reg; | 1361 | u16 reg; |
1365 | 1362 | ||
1366 | /* disable Rx GMAC FIFO flush mode */ | ||
1367 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RX_F_FL_OFF); | ||
1368 | |||
1369 | /* Enable Transmit FIFO Underrun */ | 1363 | /* Enable Transmit FIFO Underrun */ |
1370 | sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); | 1364 | sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); |
1371 | 1365 | ||
@@ -1611,9 +1605,12 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, | |||
1611 | 1605 | ||
1612 | sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; | 1606 | sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; |
1613 | 1607 | ||
1614 | if (!(status & GMR_FS_RX_OK) || (status & GMR_FS_ANY_ERR)) | 1608 | if (status & GMR_FS_ANY_ERR) |
1615 | goto error; | 1609 | goto error; |
1616 | 1610 | ||
1611 | if (!(status & GMR_FS_RX_OK)) | ||
1612 | goto resubmit; | ||
1613 | |||
1617 | if (length < RX_COPY_THRESHOLD) { | 1614 | if (length < RX_COPY_THRESHOLD) { |
1618 | skb = alloc_skb(length + 2, GFP_ATOMIC); | 1615 | skb = alloc_skb(length + 2, GFP_ATOMIC); |
1619 | if (!skb) | 1616 | if (!skb) |
@@ -1662,9 +1659,6 @@ resubmit: | |||
1662 | return skb; | 1659 | return skb; |
1663 | 1660 | ||
1664 | error: | 1661 | error: |
1665 | if (status & GMR_FS_GOOD_FC) | ||
1666 | goto resubmit; | ||
1667 | |||
1668 | if (netif_msg_rx_err(sky2)) | 1662 | if (netif_msg_rx_err(sky2)) |
1669 | printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", | 1663 | printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", |
1670 | sky2->netdev->name, status, length); | 1664 | sky2->netdev->name, status, length); |