diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2018-02-24 10:53:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-27 11:47:41 -0500 |
commit | 6c6aa15fdea52aa4a19cc0b5478884af591c9351 (patch) | |
tree | 1d45e132b9855d208c88d42e08490c406d5d68b8 | |
parent | a52b839752aab7063c38c1cb7b8e63efc54e3c30 (diff) |
r8169: improve interrupt handling
This patch improves few aspects of interrupt handling:
- update to current interrupt allocation API
(use pci_alloc_irq_vectors() instead of deprecated pci_enable_msi())
- this implicitly will allocate a MSI-X interrupt if available
- get rid of flag RTL_FEATURE_MSI
- remove some dead code, intentionally disabling (unreliable) MSI
being partially available on old PCI chips.
The patch works fine on a RTL8168evl (chip version 34) and on a
RTL8169SB (chip version 04).
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 96db3283eecf..cc51286ee51f 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -736,8 +736,7 @@ struct ring_info { | |||
736 | }; | 736 | }; |
737 | 737 | ||
738 | enum features { | 738 | enum features { |
739 | RTL_FEATURE_MSI = (1 << 0), | 739 | RTL_FEATURE_GMII = (1 << 0), |
740 | RTL_FEATURE_GMII = (1 << 1), | ||
741 | }; | 740 | }; |
742 | 741 | ||
743 | struct rtl8169_counters { | 742 | struct rtl8169_counters { |
@@ -7847,7 +7846,7 @@ static int rtl8169_close(struct net_device *dev) | |||
7847 | 7846 | ||
7848 | cancel_work_sync(&tp->wk.work); | 7847 | cancel_work_sync(&tp->wk.work); |
7849 | 7848 | ||
7850 | free_irq(pdev->irq, dev); | 7849 | pci_free_irq(pdev, 0, dev); |
7851 | 7850 | ||
7852 | dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, | 7851 | dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, |
7853 | tp->RxPhyAddr); | 7852 | tp->RxPhyAddr); |
@@ -7903,9 +7902,8 @@ static int rtl_open(struct net_device *dev) | |||
7903 | 7902 | ||
7904 | rtl_request_firmware(tp); | 7903 | rtl_request_firmware(tp); |
7905 | 7904 | ||
7906 | retval = request_irq(pdev->irq, rtl8169_interrupt, | 7905 | retval = pci_request_irq(pdev, 0, rtl8169_interrupt, NULL, dev, |
7907 | (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED, | 7906 | dev->name); |
7908 | dev->name, dev); | ||
7909 | if (retval < 0) | 7907 | if (retval < 0) |
7910 | goto err_release_fw_2; | 7908 | goto err_release_fw_2; |
7911 | 7909 | ||
@@ -8253,7 +8251,7 @@ static const struct rtl_cfg_info { | |||
8253 | .region = 2, | 8251 | .region = 2, |
8254 | .align = 8, | 8252 | .align = 8, |
8255 | .event_slow = SYSErr | LinkChg | RxOverflow, | 8253 | .event_slow = SYSErr | LinkChg | RxOverflow, |
8256 | .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI, | 8254 | .features = RTL_FEATURE_GMII, |
8257 | .coalesce_info = rtl_coalesce_info_8168_8136, | 8255 | .coalesce_info = rtl_coalesce_info_8168_8136, |
8258 | .default_ver = RTL_GIGA_MAC_VER_11, | 8256 | .default_ver = RTL_GIGA_MAC_VER_11, |
8259 | }, | 8257 | }, |
@@ -8263,32 +8261,26 @@ static const struct rtl_cfg_info { | |||
8263 | .align = 8, | 8261 | .align = 8, |
8264 | .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver | | 8262 | .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver | |
8265 | PCSTimeout, | 8263 | PCSTimeout, |
8266 | .features = RTL_FEATURE_MSI, | ||
8267 | .coalesce_info = rtl_coalesce_info_8168_8136, | 8264 | .coalesce_info = rtl_coalesce_info_8168_8136, |
8268 | .default_ver = RTL_GIGA_MAC_VER_13, | 8265 | .default_ver = RTL_GIGA_MAC_VER_13, |
8269 | } | 8266 | } |
8270 | }; | 8267 | }; |
8271 | 8268 | ||
8272 | /* Cfg9346_Unlock assumed. */ | 8269 | static int rtl_alloc_irq(struct rtl8169_private *tp) |
8273 | static unsigned rtl_try_msi(struct rtl8169_private *tp, | ||
8274 | const struct rtl_cfg_info *cfg) | ||
8275 | { | 8270 | { |
8276 | void __iomem *ioaddr = tp->mmio_addr; | 8271 | void __iomem *ioaddr = tp->mmio_addr; |
8277 | unsigned msi = 0; | 8272 | unsigned int flags; |
8278 | u8 cfg2; | ||
8279 | 8273 | ||
8280 | cfg2 = RTL_R8(Config2) & ~MSIEnable; | 8274 | if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { |
8281 | if (cfg->features & RTL_FEATURE_MSI) { | 8275 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
8282 | if (pci_enable_msi(tp->pci_dev)) { | 8276 | RTL_W8(Config2, RTL_R8(Config2) & ~MSIEnable); |
8283 | netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n"); | 8277 | RTL_W8(Cfg9346, Cfg9346_Lock); |
8284 | } else { | 8278 | flags = PCI_IRQ_LEGACY; |
8285 | cfg2 |= MSIEnable; | 8279 | } else { |
8286 | msi = RTL_FEATURE_MSI; | 8280 | flags = PCI_IRQ_ALL_TYPES; |
8287 | } | ||
8288 | } | 8281 | } |
8289 | if (tp->mac_version <= RTL_GIGA_MAC_VER_06) | 8282 | |
8290 | RTL_W8(Config2, cfg2); | 8283 | return pci_alloc_irq_vectors(tp->pci_dev, 1, 1, flags); |
8291 | return msi; | ||
8292 | } | 8284 | } |
8293 | 8285 | ||
8294 | DECLARE_RTL_COND(rtl_link_list_ready_cond) | 8286 | DECLARE_RTL_COND(rtl_link_list_ready_cond) |
@@ -8497,9 +8489,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
8497 | chipset = tp->mac_version; | 8489 | chipset = tp->mac_version; |
8498 | tp->txd_version = rtl_chip_infos[chipset].txd_version; | 8490 | tp->txd_version = rtl_chip_infos[chipset].txd_version; |
8499 | 8491 | ||
8500 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 8492 | rc = rtl_alloc_irq(tp); |
8501 | tp->features |= rtl_try_msi(tp, cfg); | 8493 | if (rc < 0) { |
8502 | RTL_W8(Cfg9346, Cfg9346_Lock); | 8494 | netif_err(tp, probe, dev, "Can't allocate interrupt\n"); |
8495 | return rc; | ||
8496 | } | ||
8503 | 8497 | ||
8504 | /* override BIOS settings, use userspace tools to enable WOL */ | 8498 | /* override BIOS settings, use userspace tools to enable WOL */ |
8505 | __rtl8169_set_wol(tp, 0); | 8499 | __rtl8169_set_wol(tp, 0); |