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>
This commit is contained in:
parent
a52b839752
commit
6c6aa15fde
@ -736,8 +736,7 @@ struct ring_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum features {
|
enum features {
|
||||||
RTL_FEATURE_MSI = (1 << 0),
|
RTL_FEATURE_GMII = (1 << 0),
|
||||||
RTL_FEATURE_GMII = (1 << 1),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rtl8169_counters {
|
struct rtl8169_counters {
|
||||||
@ -7847,7 +7846,7 @@ static int rtl8169_close(struct net_device *dev)
|
|||||||
|
|
||||||
cancel_work_sync(&tp->wk.work);
|
cancel_work_sync(&tp->wk.work);
|
||||||
|
|
||||||
free_irq(pdev->irq, dev);
|
pci_free_irq(pdev, 0, dev);
|
||||||
|
|
||||||
dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
|
dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
|
||||||
tp->RxPhyAddr);
|
tp->RxPhyAddr);
|
||||||
@ -7903,9 +7902,8 @@ static int rtl_open(struct net_device *dev)
|
|||||||
|
|
||||||
rtl_request_firmware(tp);
|
rtl_request_firmware(tp);
|
||||||
|
|
||||||
retval = request_irq(pdev->irq, rtl8169_interrupt,
|
retval = pci_request_irq(pdev, 0, rtl8169_interrupt, NULL, dev,
|
||||||
(tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED,
|
dev->name);
|
||||||
dev->name, dev);
|
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_release_fw_2;
|
goto err_release_fw_2;
|
||||||
|
|
||||||
@ -8253,7 +8251,7 @@ static const struct rtl_cfg_info {
|
|||||||
.region = 2,
|
.region = 2,
|
||||||
.align = 8,
|
.align = 8,
|
||||||
.event_slow = SYSErr | LinkChg | RxOverflow,
|
.event_slow = SYSErr | LinkChg | RxOverflow,
|
||||||
.features = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
|
.features = RTL_FEATURE_GMII,
|
||||||
.coalesce_info = rtl_coalesce_info_8168_8136,
|
.coalesce_info = rtl_coalesce_info_8168_8136,
|
||||||
.default_ver = RTL_GIGA_MAC_VER_11,
|
.default_ver = RTL_GIGA_MAC_VER_11,
|
||||||
},
|
},
|
||||||
@ -8263,32 +8261,26 @@ static const struct rtl_cfg_info {
|
|||||||
.align = 8,
|
.align = 8,
|
||||||
.event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver |
|
.event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver |
|
||||||
PCSTimeout,
|
PCSTimeout,
|
||||||
.features = RTL_FEATURE_MSI,
|
|
||||||
.coalesce_info = rtl_coalesce_info_8168_8136,
|
.coalesce_info = rtl_coalesce_info_8168_8136,
|
||||||
.default_ver = RTL_GIGA_MAC_VER_13,
|
.default_ver = RTL_GIGA_MAC_VER_13,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Cfg9346_Unlock assumed. */
|
static int rtl_alloc_irq(struct rtl8169_private *tp)
|
||||||
static unsigned rtl_try_msi(struct rtl8169_private *tp,
|
|
||||||
const struct rtl_cfg_info *cfg)
|
|
||||||
{
|
{
|
||||||
void __iomem *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
unsigned msi = 0;
|
unsigned int flags;
|
||||||
u8 cfg2;
|
|
||||||
|
|
||||||
cfg2 = RTL_R8(Config2) & ~MSIEnable;
|
if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
|
||||||
if (cfg->features & RTL_FEATURE_MSI) {
|
RTL_W8(Cfg9346, Cfg9346_Unlock);
|
||||||
if (pci_enable_msi(tp->pci_dev)) {
|
RTL_W8(Config2, RTL_R8(Config2) & ~MSIEnable);
|
||||||
netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n");
|
RTL_W8(Cfg9346, Cfg9346_Lock);
|
||||||
} else {
|
flags = PCI_IRQ_LEGACY;
|
||||||
cfg2 |= MSIEnable;
|
} else {
|
||||||
msi = RTL_FEATURE_MSI;
|
flags = PCI_IRQ_ALL_TYPES;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
|
|
||||||
RTL_W8(Config2, cfg2);
|
return pci_alloc_irq_vectors(tp->pci_dev, 1, 1, flags);
|
||||||
return msi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_RTL_COND(rtl_link_list_ready_cond)
|
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)
|
|||||||
chipset = tp->mac_version;
|
chipset = tp->mac_version;
|
||||||
tp->txd_version = rtl_chip_infos[chipset].txd_version;
|
tp->txd_version = rtl_chip_infos[chipset].txd_version;
|
||||||
|
|
||||||
RTL_W8(Cfg9346, Cfg9346_Unlock);
|
rc = rtl_alloc_irq(tp);
|
||||||
tp->features |= rtl_try_msi(tp, cfg);
|
if (rc < 0) {
|
||||||
RTL_W8(Cfg9346, Cfg9346_Lock);
|
netif_err(tp, probe, dev, "Can't allocate interrupt\n");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* override BIOS settings, use userspace tools to enable WOL */
|
/* override BIOS settings, use userspace tools to enable WOL */
|
||||||
__rtl8169_set_wol(tp, 0);
|
__rtl8169_set_wol(tp, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user