diff options
Diffstat (limited to 'drivers/net/ethernet/realtek/r8169.c')
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 69 |
1 files changed, 29 insertions, 40 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 92b45f08858f..c8f47f17186f 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -477,7 +477,6 @@ enum rtl_register_content { | |||
477 | /* Config1 register p.24 */ | 477 | /* Config1 register p.24 */ |
478 | LEDS1 = (1 << 7), | 478 | LEDS1 = (1 << 7), |
479 | LEDS0 = (1 << 6), | 479 | LEDS0 = (1 << 6), |
480 | MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ | ||
481 | Speed_down = (1 << 4), | 480 | Speed_down = (1 << 4), |
482 | MEMMAP = (1 << 3), | 481 | MEMMAP = (1 << 3), |
483 | IOMAP = (1 << 2), | 482 | IOMAP = (1 << 2), |
@@ -485,6 +484,7 @@ enum rtl_register_content { | |||
485 | PMEnable = (1 << 0), /* Power Management Enable */ | 484 | PMEnable = (1 << 0), /* Power Management Enable */ |
486 | 485 | ||
487 | /* Config2 register p. 25 */ | 486 | /* Config2 register p. 25 */ |
487 | MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ | ||
488 | PCI_Clock_66MHz = 0x01, | 488 | PCI_Clock_66MHz = 0x01, |
489 | PCI_Clock_33MHz = 0x00, | 489 | PCI_Clock_33MHz = 0x00, |
490 | 490 | ||
@@ -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 | ||
1186 | static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) | 1186 | static 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 | ||
1193 | static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) | 1195 | static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) |
@@ -1292,7 +1294,7 @@ static void __rtl8169_check_link_status(struct net_device *dev, | |||
1292 | netif_carrier_off(dev); | 1294 | netif_carrier_off(dev); |
1293 | netif_info(tp, ifdown, dev, "link down\n"); | 1295 | netif_info(tp, ifdown, dev, "link down\n"); |
1294 | if (pm) | 1296 | if (pm) |
1295 | pm_schedule_suspend(&tp->pci_dev->dev, 100); | 1297 | pm_schedule_suspend(&tp->pci_dev->dev, 5000); |
1296 | } | 1298 | } |
1297 | spin_unlock_irqrestore(&tp->lock, flags); | 1299 | spin_unlock_irqrestore(&tp->lock, flags); |
1298 | } | 1300 | } |
@@ -3424,22 +3426,24 @@ static const struct rtl_cfg_info { | |||
3424 | }; | 3426 | }; |
3425 | 3427 | ||
3426 | /* Cfg9346_Unlock assumed. */ | 3428 | /* Cfg9346_Unlock assumed. */ |
3427 | static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr, | 3429 | static unsigned rtl_try_msi(struct rtl8169_private *tp, |
3428 | const struct rtl_cfg_info *cfg) | 3430 | const struct rtl_cfg_info *cfg) |
3429 | { | 3431 | { |
3432 | void __iomem *ioaddr = tp->mmio_addr; | ||
3430 | unsigned msi = 0; | 3433 | unsigned msi = 0; |
3431 | u8 cfg2; | 3434 | u8 cfg2; |
3432 | 3435 | ||
3433 | cfg2 = RTL_R8(Config2) & ~MSIEnable; | 3436 | cfg2 = RTL_R8(Config2) & ~MSIEnable; |
3434 | if (cfg->features & RTL_FEATURE_MSI) { | 3437 | if (cfg->features & RTL_FEATURE_MSI) { |
3435 | if (pci_enable_msi(pdev)) { | 3438 | if (pci_enable_msi(tp->pci_dev)) { |
3436 | dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); | 3439 | netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n"); |
3437 | } else { | 3440 | } else { |
3438 | cfg2 |= MSIEnable; | 3441 | cfg2 |= MSIEnable; |
3439 | msi = RTL_FEATURE_MSI; | 3442 | msi = RTL_FEATURE_MSI; |
3440 | } | 3443 | } |
3441 | } | 3444 | } |
3442 | RTL_W8(Config2, cfg2); | 3445 | if (tp->mac_version <= RTL_GIGA_MAC_VER_06) |
3446 | RTL_W8(Config2, cfg2); | ||
3443 | return msi; | 3447 | return msi; |
3444 | } | 3448 | } |
3445 | 3449 | ||
@@ -3933,8 +3937,6 @@ static void rtl_hw_reset(struct rtl8169_private *tp) | |||
3933 | break; | 3937 | break; |
3934 | udelay(100); | 3938 | udelay(100); |
3935 | } | 3939 | } |
3936 | |||
3937 | rtl8169_init_ring_indexes(tp); | ||
3938 | } | 3940 | } |
3939 | 3941 | ||
3940 | static int __devinit | 3942 | static int __devinit |
@@ -4077,7 +4079,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4077 | tp->features |= RTL_FEATURE_WOL; | 4079 | tp->features |= RTL_FEATURE_WOL; |
4078 | if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) | 4080 | if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) |
4079 | tp->features |= RTL_FEATURE_WOL; | 4081 | tp->features |= RTL_FEATURE_WOL; |
4080 | tp->features |= rtl_try_msi(pdev, ioaddr, cfg); | 4082 | tp->features |= rtl_try_msi(tp, cfg); |
4081 | RTL_W8(Cfg9346, Cfg9346_Lock); | 4083 | RTL_W8(Cfg9346, Cfg9346_Lock); |
4082 | 4084 | ||
4083 | if (rtl_tbi_enabled(tp)) { | 4085 | if (rtl_tbi_enabled(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); |
@@ -5389,14 +5395,16 @@ static void rtl8169_reset_task(struct work_struct *work) | |||
5389 | if (!netif_running(dev)) | 5395 | if (!netif_running(dev)) |
5390 | goto out_unlock; | 5396 | goto out_unlock; |
5391 | 5397 | ||
5398 | rtl8169_hw_reset(tp); | ||
5399 | |||
5392 | rtl8169_wait_for_quiescence(dev); | 5400 | rtl8169_wait_for_quiescence(dev); |
5393 | 5401 | ||
5394 | for (i = 0; i < NUM_RX_DESC; i++) | 5402 | for (i = 0; i < NUM_RX_DESC; i++) |
5395 | rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); | 5403 | rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); |
5396 | 5404 | ||
5397 | rtl8169_tx_clear(tp); | 5405 | rtl8169_tx_clear(tp); |
5406 | rtl8169_init_ring_indexes(tp); | ||
5398 | 5407 | ||
5399 | rtl8169_hw_reset(tp); | ||
5400 | rtl_hw_start(dev); | 5408 | rtl_hw_start(dev); |
5401 | netif_wake_queue(dev); | 5409 | netif_wake_queue(dev); |
5402 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | 5410 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); |
@@ -5407,11 +5415,6 @@ out_unlock: | |||
5407 | 5415 | ||
5408 | static void rtl8169_tx_timeout(struct net_device *dev) | 5416 | static void rtl8169_tx_timeout(struct net_device *dev) |
5409 | { | 5417 | { |
5410 | struct rtl8169_private *tp = netdev_priv(dev); | ||
5411 | |||
5412 | rtl8169_hw_reset(tp); | ||
5413 | |||
5414 | /* Let's wait a bit while any (async) irq lands on */ | ||
5415 | rtl8169_schedule_work(dev, rtl8169_reset_task); | 5418 | rtl8169_schedule_work(dev, rtl8169_reset_task); |
5416 | } | 5419 | } |
5417 | 5420 | ||
@@ -5804,6 +5807,10 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
5804 | */ | 5807 | */ |
5805 | status = RTL_R16(IntrStatus); | 5808 | status = RTL_R16(IntrStatus); |
5806 | while (status && status != 0xffff) { | 5809 | while (status && status != 0xffff) { |
5810 | status &= tp->intr_event; | ||
5811 | if (!status) | ||
5812 | break; | ||
5813 | |||
5807 | handled = 1; | 5814 | handled = 1; |
5808 | 5815 | ||
5809 | /* Handle all of the error cases first. These will reset | 5816 | /* Handle all of the error cases first. These will reset |
@@ -5818,27 +5825,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
5818 | switch (tp->mac_version) { | 5825 | switch (tp->mac_version) { |
5819 | /* Work around for rx fifo overflow */ | 5826 | /* Work around for rx fifo overflow */ |
5820 | case RTL_GIGA_MAC_VER_11: | 5827 | 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); | 5828 | netif_stop_queue(dev); |
5824 | rtl8169_tx_timeout(dev); | 5829 | rtl8169_tx_timeout(dev); |
5825 | goto done; | 5830 | 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: | 5831 | default: |
5843 | break; | 5832 | break; |
5844 | } | 5833 | } |