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

Commit 5d06a99f authored by Francois Romieu's avatar Francois Romieu
Browse files

r8169: fix broken ring index handling in suspend/resume



rtl8169_hw_start() requires that the descriptor ring indexes be
set to zero. Let a deferred invocation of rtl8169_reset_task()
handle it. Enabling a few power management bits will not hurt
either.

suspend/resume is issued with irq on: the spinlock do not need
to save the irq flag.

Signed-off-by: default avatarFrancois Romieu <romieu@fr.zoreil.com>
parent 791917de
Loading
Loading
Loading
Loading
+59 −43
Original line number Original line Diff line number Diff line
@@ -287,6 +287,12 @@ enum RTL8169_register_content {
	TxInterFrameGapShift = 24,
	TxInterFrameGapShift = 24,
	TxDMAShift = 8,	/* DMA burst value (0-7) is shift this many bits */
	TxDMAShift = 8,	/* DMA burst value (0-7) is shift this many bits */


	/* Config1 register p.24 */
	PMEnable	= (1 << 0),	/* Power Management Enable */

	/* Config5 register p.27 */
	PMEStatus	= (1 << 0),	/* PME status can be reset by PCI RST# */

	/* TBICSR p.28 */
	/* TBICSR p.28 */
	TBIReset	= 0x80000000,
	TBIReset	= 0x80000000,
	TBILoopback	= 0x40000000,
	TBILoopback	= 0x40000000,
@@ -1442,6 +1448,11 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
	}
	}
	tp->chipset = i;
	tp->chipset = i;


	RTL_W8(Cfg9346, Cfg9346_Unlock);
	RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
	RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
	RTL_W8(Cfg9346, Cfg9346_Lock);

	*ioaddr_out = ioaddr;
	*ioaddr_out = ioaddr;
	*dev_out = dev;
	*dev_out = dev;
out:
out:
@@ -1612,49 +1623,6 @@ rtl8169_remove_one(struct pci_dev *pdev)
	pci_set_drvdata(pdev, NULL);
	pci_set_drvdata(pdev, NULL);
}
}


#ifdef CONFIG_PM

static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct net_device *dev = pci_get_drvdata(pdev);
	struct rtl8169_private *tp = netdev_priv(dev);
	void __iomem *ioaddr = tp->mmio_addr;
	unsigned long flags;

	if (!netif_running(dev))
		return 0;
	
	netif_device_detach(dev);
	netif_stop_queue(dev);
	spin_lock_irqsave(&tp->lock, flags);

	/* Disable interrupts, stop Rx and Tx */
	RTL_W16(IntrMask, 0);
	RTL_W8(ChipCmd, 0);
		
	/* Update the error counts. */
	tp->stats.rx_missed_errors += RTL_R32(RxMissed);
	RTL_W32(RxMissed, 0);
	spin_unlock_irqrestore(&tp->lock, flags);
	
	return 0;
}

static int rtl8169_resume(struct pci_dev *pdev)
{
	struct net_device *dev = pci_get_drvdata(pdev);

	if (!netif_running(dev))
	    return 0;

	netif_device_attach(dev);
	rtl8169_hw_start(dev);

	return 0;
}
                                                                                
#endif /* CONFIG_PM */

static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
				  struct net_device *dev)
				  struct net_device *dev)
{
{
@@ -2700,6 +2668,54 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
	return &tp->stats;
	return &tp->stats;
}
}


#ifdef CONFIG_PM

static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct net_device *dev = pci_get_drvdata(pdev);
	struct rtl8169_private *tp = netdev_priv(dev);
	void __iomem *ioaddr = tp->mmio_addr;

	if (!netif_running(dev))
		goto out;

	netif_device_detach(dev);
	netif_stop_queue(dev);

	spin_lock_irq(&tp->lock);

	rtl8169_asic_down(ioaddr);

	tp->stats.rx_missed_errors += RTL_R32(RxMissed);
	RTL_W32(RxMissed, 0);

	spin_unlock_irq(&tp->lock);

	pci_save_state(pdev);
	pci_set_power_state(pdev, pci_choose_state(pdev, state));
out:
	return 0;
}

static int rtl8169_resume(struct pci_dev *pdev)
{
	struct net_device *dev = pci_get_drvdata(pdev);

	if (!netif_running(dev))
		goto out;

	netif_device_attach(dev);

	pci_set_power_state(pdev, PCI_D0);
	pci_restore_state(pdev);

	rtl8169_schedule_work(dev, rtl8169_reset_task);
out:
	return 0;
}

#endif /* CONFIG_PM */

static struct pci_driver rtl8169_pci_driver = {
static struct pci_driver rtl8169_pci_driver = {
	.name		= MODULENAME,
	.name		= MODULENAME,
	.id_table	= rtl8169_pci_tbl,
	.id_table	= rtl8169_pci_tbl,