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 Diff line number Diff line
@@ -586,6 +586,7 @@ struct rtl8139_private {
	dma_addr_t tx_bufs_dma;
	signed char phys[4];		/* MII device addresses. */
	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 have_thread : 1;
	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 rtl8139_hw_start (struct net_device *dev);
static void rtl8139_thread (void *_data);
static void rtl8139_tx_timeout_task(void *_data);
static struct ethtool_ops rtl8139_ethtool_ops;

/* write MMIO register, with flush */
@@ -1598,13 +1600,14 @@ static void rtl8139_thread (void *_data)
{
	struct net_device *dev = _data;
	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);
		rtnl_unlock ();

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

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 */
}


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

	printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
		"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)
		RTL_W8 (ChipCmd, CmdRxEnb);

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

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

	/* ...and finally, reset everything */
	if (netif_running(dev)) {
		rtl8139_hw_start (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)
{
+7 −6
Original line number Diff line number Diff line
@@ -484,13 +484,12 @@ static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
	int i;

	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 */
		if (!(RTL_R32(PHYAR) & 0x80000000)) 
			break;
		udelay(100);
		udelay(25);
	}
}

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

	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 */
		if (RTL_R32(PHYAR) & 0x80000000) {
			value = (int) (RTL_R32(PHYAR) & 0xFFFF);
			break;
		}
		udelay(100);
		udelay(25);
	}
	return value;
}
@@ -677,6 +675,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,

		if (duplex == DUPLEX_HALF)
			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;