2004-04-16 05:36:31

by Andy Lutomirski

[permalink] [raw]
Subject: r8169 excessive PHY reset

--- ./drivers/net/r8169.c.orig 2004-04-15 22:08:07.962654280 -0700
+++ ./drivers/net/r8169.c 2004-04-15 22:09:22.101383480 -0700
@@ -98,7 +98,6 @@

#define RTL_MIN_IO_SIZE 0x80
#define RTL8169_TX_TIMEOUT (6*HZ)
-#define RTL8169_PHY_TIMEOUT (HZ)

/* write/read MMIO register */
#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
@@ -323,7 +322,6 @@
dma_addr_t RxPhyAddr;
struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */
struct sk_buff *Tx_skbuff[NUM_TX_DESC]; /* Index of Transmit data buffer */
- struct timer_list timer;
unsigned long phy_link_down_cnt;
u16 cp_cmd;
};
@@ -568,90 +566,6 @@
mdio_write(ioaddr, 31, 0x0000); //w 31 2 0 0
}

-static void rtl8169_hw_phy_reset(struct net_device *dev)
-{
- struct rtl8169_private *tp = dev->priv;
- void *ioaddr = tp->mmio_addr;
- int i, val;
-
- printk(KERN_WARNING PFX "%s: Reset RTL8169s PHY\n", dev->name);
-
- val = (mdio_read(ioaddr, 0) | 0x8000) & 0xffff;
- mdio_write(ioaddr, 0, val);
-
- for (i = 50; i >= 0; i--) {
- if (!(mdio_read(ioaddr, 0) & 0x8000))
- break;
- udelay(100); /* Gross */
- }
-
- if (i < 0) {
- printk(KERN_WARNING PFX "%s: no PHY Reset ack. Giving up.\n",
- dev->name);
- }
-}
-
-static void rtl8169_phy_timer(unsigned long __opaque)
-{
- struct net_device *dev = (struct net_device *)__opaque;
- struct rtl8169_private *tp = dev->priv;
- struct timer_list *timer = &tp->timer;
- void *ioaddr = tp->mmio_addr;
-
- assert(tp->mac_version > RTL_GIGA_MAC_VER_B);
- assert(tp->phy_version < RTL_GIGA_PHY_VER_G);
-
- if (RTL_R8(PHYstatus) & LinkStatus)
- tp->phy_link_down_cnt = 0;
- else {
- tp->phy_link_down_cnt++;
- if (tp->phy_link_down_cnt >= 12) {
- int reg;
-
- // If link on 1000, perform phy reset.
- reg = mdio_read(ioaddr, PHY_1000_CTRL_REG);
- if (reg & PHY_Cap_1000_Full)
- rtl8169_hw_phy_reset(dev);
-
- tp->phy_link_down_cnt = 0;
- }
- }
-
- mod_timer(timer, RTL8169_PHY_TIMEOUT);
-}
-
-static inline void rtl8169_delete_timer(struct net_device *dev)
-{
- struct rtl8169_private *tp = dev->priv;
- struct timer_list *timer = &tp->timer;
-
- if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
- (tp->phy_version >= RTL_GIGA_PHY_VER_G))
- return;
-
- del_timer_sync(timer);
-
- tp->phy_link_down_cnt = 0;
-}
-
-static inline void rtl8169_request_timer(struct net_device *dev)
-{
- struct rtl8169_private *tp = dev->priv;
- struct timer_list *timer = &tp->timer;
-
- if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
- (tp->phy_version >= RTL_GIGA_PHY_VER_G))
- return;
-
- tp->phy_link_down_cnt = 0;
-
- init_timer(timer);
- timer->expires = jiffies + RTL8169_PHY_TIMEOUT;
- timer->data = (unsigned long)(dev);
- timer->function = rtl8169_phy_timer;
- add_timer(timer);
-}
-
static int __devinit
rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
void **ioaddr_out)
@@ -1074,8 +988,6 @@
goto err_free_rx;

rtl8169_hw_start(dev);
-
- rtl8169_request_timer(dev);
out:
return retval;

@@ -1587,8 +1499,6 @@

netif_stop_queue(dev);

- rtl8169_delete_timer(dev);
-
spin_lock_irq(&tp->lock);

/* Stop the chip's Tx and Rx DMA processes. */


Attachments:
r8169fix.patch (3.07 kB)

2004-04-16 07:40:40

by Francois Romieu

[permalink] [raw]
Subject: Re: r8169 excessive PHY reset

Andy Lutomirski <[email protected]> :
[r8169 phy issue with 2.6.5-mm5]
> - mod_timer(timer, RTL8169_PHY_TIMEOUT);

I forgot a 'jiffies +' there. It is fixed in current Linus's tree.

--
Ueimor