diff options
Diffstat (limited to 'drivers/net/ethernet/realtek/r8169.c')
| -rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 67 | 
1 files changed, 28 insertions, 39 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 6f06aa10f0d..c8f47f17186 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -477,7 +477,6 @@ enum rtl_register_content {  	/* Config1 register p.24 */  	LEDS1		= (1 << 7),  	LEDS0		= (1 << 6), -	MSIEnable	= (1 << 5),	/* Enable Message Signaled Interrupt */  	Speed_down	= (1 << 4),  	MEMMAP		= (1 << 3),  	IOMAP		= (1 << 2), @@ -485,6 +484,7 @@ enum rtl_register_content {  	PMEnable	= (1 << 0),	/* Power Management Enable */  	/* Config2 register p. 25 */ +	MSIEnable	= (1 << 5),	/* 8169 only. Reserved in the 8168. */  	PCI_Clock_66MHz = 0x01,  	PCI_Clock_33MHz = 0x00, @@ -1183,11 +1183,13 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)  	return value;  } -static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) +static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp)  { -	RTL_W16(IntrMask, 0x0000); +	void __iomem *ioaddr = tp->mmio_addr; -	RTL_W16(IntrStatus, 0xffff); +	RTL_W16(IntrMask, 0x0000); +	RTL_W16(IntrStatus, tp->intr_event); +	RTL_R8(ChipCmd);  }  static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) @@ -3424,22 +3426,24 @@ static const struct rtl_cfg_info {  };  /* Cfg9346_Unlock assumed. */ -static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr, +static unsigned rtl_try_msi(struct rtl8169_private *tp,  			    const struct rtl_cfg_info *cfg)  { +	void __iomem *ioaddr = tp->mmio_addr;  	unsigned msi = 0;  	u8 cfg2;  	cfg2 = RTL_R8(Config2) & ~MSIEnable;  	if (cfg->features & RTL_FEATURE_MSI) { -		if (pci_enable_msi(pdev)) { -			dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); +		if (pci_enable_msi(tp->pci_dev)) { +			netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n");  		} else {  			cfg2 |= MSIEnable;  			msi = RTL_FEATURE_MSI;  		}  	} -	RTL_W8(Config2, cfg2); +	if (tp->mac_version <= RTL_GIGA_MAC_VER_06) +		RTL_W8(Config2, cfg2);  	return msi;  } @@ -3933,8 +3937,6 @@ static void rtl_hw_reset(struct rtl8169_private *tp)  			break;  		udelay(100);  	} - -	rtl8169_init_ring_indexes(tp);  }  static int __devinit @@ -4077,7 +4079,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  		tp->features |= RTL_FEATURE_WOL;  	if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0)  		tp->features |= RTL_FEATURE_WOL; -	tp->features |= rtl_try_msi(pdev, ioaddr, cfg); +	tp->features |= rtl_try_msi(tp, cfg);  	RTL_W8(Cfg9346, Cfg9346_Lock);  	if (rtl_tbi_enabled(tp)) { @@ -4339,7 +4341,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)  	void __iomem *ioaddr = tp->mmio_addr;  	/* Disable interrupts */ -	rtl8169_irq_mask_and_ack(ioaddr); +	rtl8169_irq_mask_and_ack(tp);  	rtl_rx_close(tp); @@ -4885,8 +4887,7 @@ static void rtl_hw_start_8168(struct net_device *dev)  	RTL_W16(IntrMitigate, 0x5151);  	/* Work around for RxFIFO overflow. */ -	if (tp->mac_version == RTL_GIGA_MAC_VER_11 || -	    tp->mac_version == RTL_GIGA_MAC_VER_22) { +	if (tp->mac_version == RTL_GIGA_MAC_VER_11) {  		tp->intr_event |= RxFIFOOver | PCSTimeout;  		tp->intr_event &= ~RxOverflow;  	} @@ -5076,6 +5077,11 @@ static void rtl_hw_start_8101(struct net_device *dev)  	void __iomem *ioaddr = tp->mmio_addr;  	struct pci_dev *pdev = tp->pci_dev; +	if (tp->mac_version >= RTL_GIGA_MAC_VER_30) { +		tp->intr_event &= ~RxFIFOOver; +		tp->napi_event &= ~RxFIFOOver; +	} +  	if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||  	    tp->mac_version == RTL_GIGA_MAC_VER_16) {  		int cap = pci_pcie_cap(pdev); @@ -5342,7 +5348,7 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)  	/* Wait for any pending NAPI task to complete */  	napi_disable(&tp->napi); -	rtl8169_irq_mask_and_ack(ioaddr); +	rtl8169_irq_mask_and_ack(tp);  	tp->intr_mask = 0xffff;  	RTL_W16(IntrMask, tp->intr_event); @@ -5389,14 +5395,16 @@ static void rtl8169_reset_task(struct work_struct *work)  	if (!netif_running(dev))  		goto out_unlock; +	rtl8169_hw_reset(tp); +  	rtl8169_wait_for_quiescence(dev);  	for (i = 0; i < NUM_RX_DESC; i++)  		rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz);  	rtl8169_tx_clear(tp); +	rtl8169_init_ring_indexes(tp); -	rtl8169_hw_reset(tp);  	rtl_hw_start(dev);  	netif_wake_queue(dev);  	rtl8169_check_link_status(dev, tp, tp->mmio_addr); @@ -5407,11 +5415,6 @@ out_unlock:  static void rtl8169_tx_timeout(struct net_device *dev)  { -	struct rtl8169_private *tp = netdev_priv(dev); - -	rtl8169_hw_reset(tp); - -	/* Let's wait a bit while any (async) irq lands on */  	rtl8169_schedule_work(dev, rtl8169_reset_task);  } @@ -5804,6 +5807,10 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)  	 */  	status = RTL_R16(IntrStatus);  	while (status && status != 0xffff) { +		status &= tp->intr_event; +		if (!status) +			break; +  		handled = 1;  		/* Handle all of the error cases first. These will reset @@ -5818,27 +5825,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)  			switch (tp->mac_version) {  			/* Work around for rx fifo overflow */  			case RTL_GIGA_MAC_VER_11: -			case RTL_GIGA_MAC_VER_22: -			case RTL_GIGA_MAC_VER_26:  				netif_stop_queue(dev);  				rtl8169_tx_timeout(dev);  				goto done; -			/* Testers needed. */ -			case RTL_GIGA_MAC_VER_17: -			case RTL_GIGA_MAC_VER_19: -			case RTL_GIGA_MAC_VER_20: -			case RTL_GIGA_MAC_VER_21: -			case RTL_GIGA_MAC_VER_23: -			case RTL_GIGA_MAC_VER_24: -			case RTL_GIGA_MAC_VER_27: -			case RTL_GIGA_MAC_VER_28: -			case RTL_GIGA_MAC_VER_31: -			/* Experimental science. Pktgen proof. */ -			case RTL_GIGA_MAC_VER_12: -			case RTL_GIGA_MAC_VER_25: -				if (status == RxFIFOOver) -					goto done; -				break;  			default:  				break;  			}  |