Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3cfc1510 authored by Jeff Garzik's avatar Jeff Garzik
Browse files
parents cc8c6e37 371e8bc2
Loading
Loading
Loading
Loading
+26 −12
Original line number Original line Diff line number Diff line
@@ -586,6 +586,7 @@ struct rtl8139_private {
	dma_addr_t tx_bufs_dma;
	dma_addr_t tx_bufs_dma;
	signed char phys[4];		/* MII device addresses. */
	signed char phys[4];		/* MII device addresses. */
	char twistie, twist_row, twist_col;	/* Twister tune state. */
	char twistie, twist_row, twist_col;	/* Twister tune state. */
	unsigned int watchdog_fired : 1;
	unsigned int default_port : 4;	/* Last dev->if_port value. */
	unsigned int default_port : 4;	/* Last dev->if_port value. */
	unsigned int have_thread : 1;
	unsigned int have_thread : 1;
	spinlock_t lock;
	spinlock_t lock;
@@ -638,6 +639,7 @@ static void rtl8139_set_rx_mode (struct net_device *dev);
static void __set_rx_mode (struct net_device *dev);
static void __set_rx_mode (struct net_device *dev);
static void rtl8139_hw_start (struct net_device *dev);
static void rtl8139_hw_start (struct net_device *dev);
static void rtl8139_thread (void *_data);
static void rtl8139_thread (void *_data);
static void rtl8139_tx_timeout_task(void *_data);
static struct ethtool_ops rtl8139_ethtool_ops;
static struct ethtool_ops rtl8139_ethtool_ops;


/* write MMIO register, with flush */
/* write MMIO register, with flush */
@@ -1598,13 +1600,14 @@ static void rtl8139_thread (void *_data)
{
{
	struct net_device *dev = _data;
	struct net_device *dev = _data;
	struct rtl8139_private *tp = netdev_priv(dev);
	struct rtl8139_private *tp = netdev_priv(dev);
	unsigned long thr_delay;
	unsigned long thr_delay = next_tick;


	if (rtnl_shlock_nowait() == 0) {
	if (tp->watchdog_fired) {
		tp->watchdog_fired = 0;
		rtl8139_tx_timeout_task(_data);
	} else if (rtnl_shlock_nowait() == 0) {
		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
		rtnl_unlock ();
		rtnl_unlock ();

		thr_delay = next_tick;
	} else {
	} else {
		/* unlikely race.  mitigate with fast poll. */
		/* unlikely race.  mitigate with fast poll. */
		thr_delay = HZ / 2;
		thr_delay = HZ / 2;
@@ -1631,7 +1634,8 @@ static void rtl8139_stop_thread(struct rtl8139_private *tp)
	if (tp->have_thread) {
	if (tp->have_thread) {
		cancel_rearming_delayed_work(&tp->thread);
		cancel_rearming_delayed_work(&tp->thread);
		tp->have_thread = 0;
		tp->have_thread = 0;
	}
	} else
		flush_scheduled_work();
}
}


static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
@@ -1642,14 +1646,13 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
	/* XXX account for unsent Tx packets in tp->stats.tx_dropped */
	/* XXX account for unsent Tx packets in tp->stats.tx_dropped */
}
}



static void rtl8139_tx_timeout_task (void *_data)
static void rtl8139_tx_timeout (struct net_device *dev)
{
{
	struct net_device *dev = _data;
	struct rtl8139_private *tp = netdev_priv(dev);
	struct rtl8139_private *tp = netdev_priv(dev);
	void __iomem *ioaddr = tp->mmio_addr;
	void __iomem *ioaddr = tp->mmio_addr;
	int i;
	int i;
	u8 tmp8;
	u8 tmp8;
	unsigned long flags;


	printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
	printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
		"media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
		"media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
@@ -1670,23 +1673,34 @@ static void rtl8139_tx_timeout (struct net_device *dev)
	if (tmp8 & CmdTxEnb)
	if (tmp8 & CmdTxEnb)
		RTL_W8 (ChipCmd, CmdRxEnb);
		RTL_W8 (ChipCmd, CmdRxEnb);


	spin_lock(&tp->rx_lock);
	spin_lock_bh(&tp->rx_lock);
	/* Disable interrupts by clearing the interrupt mask. */
	/* Disable interrupts by clearing the interrupt mask. */
	RTL_W16 (IntrMask, 0x0000);
	RTL_W16 (IntrMask, 0x0000);


	/* Stop a shared interrupt from scavenging while we are. */
	/* Stop a shared interrupt from scavenging while we are. */
	spin_lock_irqsave (&tp->lock, flags);
	spin_lock_irq(&tp->lock);
	rtl8139_tx_clear (tp);
	rtl8139_tx_clear (tp);
	spin_unlock_irqrestore (&tp->lock, flags);
	spin_unlock_irq(&tp->lock);


	/* ...and finally, reset everything */
	/* ...and finally, reset everything */
	if (netif_running(dev)) {
	if (netif_running(dev)) {
		rtl8139_hw_start (dev);
		rtl8139_hw_start (dev);
		netif_wake_queue (dev);
		netif_wake_queue (dev);
	}
	}
	spin_unlock(&tp->rx_lock);
	spin_unlock_bh(&tp->rx_lock);
}
}


static void rtl8139_tx_timeout (struct net_device *dev)
{
	struct rtl8139_private *tp = netdev_priv(dev);

	if (!tp->have_thread) {
		INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
		schedule_delayed_work(&tp->thread, next_tick);
	} else
		tp->watchdog_fired = 1;

}


static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
{
+7 −6
Original line number Original line Diff line number Diff line
@@ -484,13 +484,12 @@ static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
	int i;
	int i;


	RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
	RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
	udelay(1000);


	for (i = 2000; i > 0; i--) {
	for (i = 20; i > 0; i--) {
		/* Check if the RTL8169 has completed writing to the specified MII register */
		/* Check if the RTL8169 has completed writing to the specified MII register */
		if (!(RTL_R32(PHYAR) & 0x80000000)) 
		if (!(RTL_R32(PHYAR) & 0x80000000)) 
			break;
			break;
		udelay(100);
		udelay(25);
	}
	}
}
}


@@ -499,15 +498,14 @@ static int mdio_read(void __iomem *ioaddr, int RegAddr)
	int i, value = -1;
	int i, value = -1;


	RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
	RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
	udelay(1000);


	for (i = 2000; i > 0; i--) {
	for (i = 20; i > 0; i--) {
		/* Check if the RTL8169 has completed retrieving data from the specified MII register */
		/* Check if the RTL8169 has completed retrieving data from the specified MII register */
		if (RTL_R32(PHYAR) & 0x80000000) {
		if (RTL_R32(PHYAR) & 0x80000000) {
			value = (int) (RTL_R32(PHYAR) & 0xFFFF);
			value = (int) (RTL_R32(PHYAR) & 0xFFFF);
			break;
			break;
		}
		}
		udelay(100);
		udelay(25);
	}
	}
	return value;
	return value;
}
}
@@ -677,6 +675,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,


		if (duplex == DUPLEX_HALF)
		if (duplex == DUPLEX_HALF)
			auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
			auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);

		if (duplex == DUPLEX_FULL)
			auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
	}
	}


	tp->phy_auto_nego_reg = auto_nego;
	tp->phy_auto_nego_reg = auto_nego;