aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/realtek
diff options
context:
space:
mode:
authorfrançois romieu <romieu@fr.zoreil.com>2011-12-04 15:30:45 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-05 18:31:42 -0500
commit811fd3010cf512f2e23e6c4c912aad54516dc706 (patch)
tree2b03937f3ccac46b09fa1030108f57b259769143 /drivers/net/ethernet/realtek
parent321f3b8708e853695a4ff4a1a95b6fa0965b06e5 (diff)
r8169: Rx FIFO overflow fixes.
Realtek has specified that the post 8168c gigabit chips and the post 8105e fast ethernet chips recover automatically from a Rx FIFO overflow. The driver does not need to clear the RxFIFOOver bit of IntrStatus and it should rather avoid messing it. The implementation deserves some explanation: 1. events outside of the intr_event bit mask are now ignored. It enforces a no-processing policy for the events that either should not be there or should be ignored. 2. RxFIFOOver was already ignored in rtl_cfg_infos[RTL_CFG_1] for the whole 8168 line of chips with two exceptions: - RTL_GIGA_MAC_VER_22 since b5ba6d12bdac21bc0620a5089e0f24e362645efd ("use RxFIFO overflow workaround for 8168c chipset."). This one should now be correctly handled. - RTL_GIGA_MAC_VER_11 (8168b) which requires a different Rx FIFO overflow processing. Though it does not conform to Realtek suggestion above, the updated driver includes no change for RTL_GIGA_MAC_VER_12 and RTL_GIGA_MAC_VER_17. Both are 8168b. RTL_GIGA_MAC_VER_12 is common and a bit old so I'd rather wait for experimental evidence that the change suggested by Realtek really helps or does not hurt in unexpected ways. Removed case statements in rtl8169_interrupt are only 8168 relevant. 3. RxFIFOOver is masked for post 8105e 810x chips, namely the sole 8105e (RTL_GIGA_MAC_VER_30) itself. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Cc: hayeswang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/realtek')
-rw-r--r--drivers/net/ethernet/realtek/r8169.c42
1 files changed, 17 insertions, 25 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 6f06aa10f0d7..7a1e3a69f193 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1183,11 +1183,13 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
1183 return value; 1183 return value;
1184} 1184}
1185 1185
1186static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) 1186static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp)
1187{ 1187{
1188 RTL_W16(IntrMask, 0x0000); 1188 void __iomem *ioaddr = tp->mmio_addr;
1189 1189
1190 RTL_W16(IntrStatus, 0xffff); 1190 RTL_W16(IntrMask, 0x0000);
1191 RTL_W16(IntrStatus, tp->intr_event);
1192 RTL_R8(ChipCmd);
1191} 1193}
1192 1194
1193static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) 1195static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp)
@@ -4339,7 +4341,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
4339 void __iomem *ioaddr = tp->mmio_addr; 4341 void __iomem *ioaddr = tp->mmio_addr;
4340 4342
4341 /* Disable interrupts */ 4343 /* Disable interrupts */
4342 rtl8169_irq_mask_and_ack(ioaddr); 4344 rtl8169_irq_mask_and_ack(tp);
4343 4345
4344 rtl_rx_close(tp); 4346 rtl_rx_close(tp);
4345 4347
@@ -4885,8 +4887,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
4885 RTL_W16(IntrMitigate, 0x5151); 4887 RTL_W16(IntrMitigate, 0x5151);
4886 4888
4887 /* Work around for RxFIFO overflow. */ 4889 /* Work around for RxFIFO overflow. */
4888 if (tp->mac_version == RTL_GIGA_MAC_VER_11 || 4890 if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
4889 tp->mac_version == RTL_GIGA_MAC_VER_22) {
4890 tp->intr_event |= RxFIFOOver | PCSTimeout; 4891 tp->intr_event |= RxFIFOOver | PCSTimeout;
4891 tp->intr_event &= ~RxOverflow; 4892 tp->intr_event &= ~RxOverflow;
4892 } 4893 }
@@ -5076,6 +5077,11 @@ static void rtl_hw_start_8101(struct net_device *dev)
5076 void __iomem *ioaddr = tp->mmio_addr; 5077 void __iomem *ioaddr = tp->mmio_addr;
5077 struct pci_dev *pdev = tp->pci_dev; 5078 struct pci_dev *pdev = tp->pci_dev;
5078 5079
5080 if (tp->mac_version >= RTL_GIGA_MAC_VER_30) {
5081 tp->intr_event &= ~RxFIFOOver;
5082 tp->napi_event &= ~RxFIFOOver;
5083 }
5084
5079 if (tp->mac_version == RTL_GIGA_MAC_VER_13 || 5085 if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
5080 tp->mac_version == RTL_GIGA_MAC_VER_16) { 5086 tp->mac_version == RTL_GIGA_MAC_VER_16) {
5081 int cap = pci_pcie_cap(pdev); 5087 int cap = pci_pcie_cap(pdev);
@@ -5342,7 +5348,7 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
5342 /* Wait for any pending NAPI task to complete */ 5348 /* Wait for any pending NAPI task to complete */
5343 napi_disable(&tp->napi); 5349 napi_disable(&tp->napi);
5344 5350
5345 rtl8169_irq_mask_and_ack(ioaddr); 5351 rtl8169_irq_mask_and_ack(tp);
5346 5352
5347 tp->intr_mask = 0xffff; 5353 tp->intr_mask = 0xffff;
5348 RTL_W16(IntrMask, tp->intr_event); 5354 RTL_W16(IntrMask, tp->intr_event);
@@ -5804,6 +5810,10 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
5804 */ 5810 */
5805 status = RTL_R16(IntrStatus); 5811 status = RTL_R16(IntrStatus);
5806 while (status && status != 0xffff) { 5812 while (status && status != 0xffff) {
5813 status &= tp->intr_event;
5814 if (!status)
5815 break;
5816
5807 handled = 1; 5817 handled = 1;
5808 5818
5809 /* Handle all of the error cases first. These will reset 5819 /* Handle all of the error cases first. These will reset
@@ -5818,27 +5828,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
5818 switch (tp->mac_version) { 5828 switch (tp->mac_version) {
5819 /* Work around for rx fifo overflow */ 5829 /* Work around for rx fifo overflow */
5820 case RTL_GIGA_MAC_VER_11: 5830 case RTL_GIGA_MAC_VER_11:
5821 case RTL_GIGA_MAC_VER_22:
5822 case RTL_GIGA_MAC_VER_26:
5823 netif_stop_queue(dev); 5831 netif_stop_queue(dev);
5824 rtl8169_tx_timeout(dev); 5832 rtl8169_tx_timeout(dev);
5825 goto done; 5833 goto done;
5826 /* Testers needed. */
5827 case RTL_GIGA_MAC_VER_17:
5828 case RTL_GIGA_MAC_VER_19:
5829 case RTL_GIGA_MAC_VER_20:
5830 case RTL_GIGA_MAC_VER_21:
5831 case RTL_GIGA_MAC_VER_23:
5832 case RTL_GIGA_MAC_VER_24:
5833 case RTL_GIGA_MAC_VER_27:
5834 case RTL_GIGA_MAC_VER_28:
5835 case RTL_GIGA_MAC_VER_31:
5836 /* Experimental science. Pktgen proof. */
5837 case RTL_GIGA_MAC_VER_12:
5838 case RTL_GIGA_MAC_VER_25:
5839 if (status == RxFIFOOver)
5840 goto done;
5841 break;
5842 default: 5834 default:
5843 break; 5835 break;
5844 } 5836 }