Does this fix your problems? I don't have dual port boards but have an old SK-9843 fiber board. ====
The XM PHY can give IRQ on lost carrier, which is better than polling. This version also solves an number of bonding/carrier related bugs. Signed-off-by: Stephen Hemminger <[EMAIL PROTECTED]> --- a/drivers/net/skge.c 2007-07-12 14:19:55.000000000 -0700 +++ b/drivers/net/skge.c 2007-07-12 14:53:39.000000000 -0700 @@ -1091,13 +1091,7 @@ static void xm_link_down(struct skge_hw { struct net_device *dev = hw->dev[port]; struct skge_port *skge = netdev_priv(dev); - u16 cmd, msk; - - if (hw->phy_type == SK_PHY_XMAC) { - msk = xm_read16(hw, port, XM_IMSK); - msk |= XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND; - xm_write16(hw, port, XM_IMSK, msk); - } + u16 cmd; cmd = xm_read16(hw, port, XM_MMU_CMD); cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); @@ -1107,6 +1101,10 @@ static void xm_link_down(struct skge_hw if (netif_carrier_ok(dev)) skge_link_down(skge); + + /* If needed start polling for link to come up */ + if (netif_running(dev) && hw->phy_type == SK_PHY_XMAC) + mod_timer(&skge->link_timer, jiffies + LINK_HZ); } static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val) @@ -1434,30 +1432,25 @@ static void xm_phy_init(struct skge_port xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl); - /* Poll PHY for status changes */ - mod_timer(&skge->link_timer, jiffies + LINK_HZ); + /* Poll for link coming up */ + mod_timer(&skge->link_timer, jiffies); } -static void xm_check_link(struct net_device *dev) +/* Check status of link and change state */ +static void xm_link_up(struct skge_port *skge) { - struct skge_port *skge = netdev_priv(dev); + struct net_device *dev = skge->netdev; struct skge_hw *hw = skge->hw; int port = skge->port; - u16 status; - - /* read twice because of latch */ - (void) xm_phy_read(hw, port, PHY_XMAC_STAT); - status = xm_phy_read(hw, port, PHY_XMAC_STAT); + u16 isrc = xm_read16(hw, port, XM_ISRC); - if ((status & PHY_ST_LSYNC) == 0) { - xm_link_down(hw, port); - return; - } + if (netif_msg_intr(skge)) + printk(KERN_DEBUG PFX "%s: fiber status %#x\n", dev->name, isrc); if (skge->autoneg == AUTONEG_ENABLE) { u16 lpa, res; - if (!(status & PHY_ST_AN_OVER)) + if (!(isrc & XM_IS_AND)) return; lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP); @@ -1506,10 +1499,7 @@ static void xm_check_link(struct net_dev genesis_link_up(skge); } -/* Poll to check for link coming up. - * Since internal PHY is wired to a level triggered pin, can't - * get an interrupt when carrier is detected. - */ +/* Poll to check for link coming up. */ static void xm_link_timer(unsigned long arg) { struct skge_port *skge = (struct skge_port *) arg; @@ -1520,23 +1510,18 @@ static void xm_link_timer(unsigned long if (!netif_running(dev)) return; - if (netif_carrier_ok(dev)) { - xm_read16(hw, port, XM_ISRC); - if (!(xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS)) - goto nochange; - } else { - if (xm_read32(hw, port, XM_GP_PORT) & XM_GP_INP_ASS) - goto nochange; - xm_read16(hw, port, XM_ISRC); - if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS) - goto nochange; - } + if (xm_read32(hw, port, XM_GP_PORT) & XM_GP_INP_ASS) + goto resync; spin_lock(&hw->phy_lock); - xm_check_link(dev); + xm_link_up(skge); spin_unlock(&hw->phy_lock); -nochange: + /* Link up, timer no longer needed */ + if (netif_carrier_ok(dev)) + return; + +resync: if (netif_running(dev)) mod_timer(&skge->link_timer, jiffies + LINK_HZ); } @@ -1593,6 +1578,9 @@ static void genesis_mac_init(struct skge bcom_check_link(hw, port); } + /* Clear any irq */ + xm_read16(hw, port, XM_ISRC); + /* Set Station Address */ xm_outaddr(hw, port, XM_SA, dev->dev_addr); @@ -1782,8 +1770,7 @@ static void genesis_mac_intr(struct skge printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", skge->netdev->name, status); - if (hw->phy_type == SK_PHY_XMAC && - (status & (XM_IS_INP_ASS | XM_IS_LIPA_RC))) + if (hw->phy_type == SK_PHY_XMAC && (status & XM_IS_INP_ASS)) xm_link_down(hw, port); if (status & XM_IS_TXF_UR) { - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/