be2net: use PCI MMIO read instead of config read for errors
When an EEH error occurs, the device/slot is disconnected. This condition is more reliably detected (i.e., returns all ones) with an MMIO read rather than a config read -- especially on power platforms. Hence, this patch fixes EEH error detection by replacing config reads with MMIO reads for reading the error registers. The error registers in Skyhawk-R/BE2/BE3 are accessible both via the config space and the PCICFG (BAR0) memory space. Reported-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Suresh Reddy <Suresh.Reddy@emulex.com> Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
c8ba4ad0b5
Коммит
25848c9015
|
@ -424,6 +424,7 @@ struct be_adapter {
|
|||
|
||||
u8 __iomem *csr; /* CSR BAR used only for BE2/3 */
|
||||
u8 __iomem *db; /* Door Bell */
|
||||
u8 __iomem *pcicfg; /* On SH,BEx only. Shadow of PCI config space */
|
||||
|
||||
struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
|
||||
struct be_dma_mem mbox_mem;
|
||||
|
|
|
@ -2823,14 +2823,12 @@ void be_detect_error(struct be_adapter *adapter)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
pci_read_config_dword(adapter->pdev,
|
||||
PCICFG_UE_STATUS_LOW, &ue_lo);
|
||||
pci_read_config_dword(adapter->pdev,
|
||||
PCICFG_UE_STATUS_HIGH, &ue_hi);
|
||||
pci_read_config_dword(adapter->pdev,
|
||||
PCICFG_UE_STATUS_LOW_MASK, &ue_lo_mask);
|
||||
pci_read_config_dword(adapter->pdev,
|
||||
PCICFG_UE_STATUS_HI_MASK, &ue_hi_mask);
|
||||
ue_lo = ioread32(adapter->pcicfg + PCICFG_UE_STATUS_LOW);
|
||||
ue_hi = ioread32(adapter->pcicfg + PCICFG_UE_STATUS_HIGH);
|
||||
ue_lo_mask = ioread32(adapter->pcicfg +
|
||||
PCICFG_UE_STATUS_LOW_MASK);
|
||||
ue_hi_mask = ioread32(adapter->pcicfg +
|
||||
PCICFG_UE_STATUS_HI_MASK);
|
||||
|
||||
ue_lo = (ue_lo & ~ue_lo_mask);
|
||||
ue_hi = (ue_hi & ~ue_hi_mask);
|
||||
|
@ -4874,24 +4872,37 @@ static int be_roce_map_pci_bars(struct be_adapter *adapter)
|
|||
|
||||
static int be_map_pci_bars(struct be_adapter *adapter)
|
||||
{
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
u8 __iomem *addr;
|
||||
|
||||
if (BEx_chip(adapter) && be_physfn(adapter)) {
|
||||
adapter->csr = pci_iomap(adapter->pdev, 2, 0);
|
||||
adapter->csr = pci_iomap(pdev, 2, 0);
|
||||
if (!adapter->csr)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
addr = pci_iomap(adapter->pdev, db_bar(adapter), 0);
|
||||
addr = pci_iomap(pdev, db_bar(adapter), 0);
|
||||
if (!addr)
|
||||
goto pci_map_err;
|
||||
adapter->db = addr;
|
||||
|
||||
if (skyhawk_chip(adapter) || BEx_chip(adapter)) {
|
||||
if (be_physfn(adapter)) {
|
||||
/* PCICFG is the 2nd BAR in BE2 */
|
||||
addr = pci_iomap(pdev, BE2_chip(adapter) ? 1 : 0, 0);
|
||||
if (!addr)
|
||||
goto pci_map_err;
|
||||
adapter->pcicfg = addr;
|
||||
} else {
|
||||
adapter->pcicfg = adapter->db + SRIOV_VF_PCICFG_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
be_roce_map_pci_bars(adapter);
|
||||
return 0;
|
||||
|
||||
pci_map_err:
|
||||
dev_err(&adapter->pdev->dev, "Error in mapping PCI BARs\n");
|
||||
dev_err(&pdev->dev, "Error in mapping PCI BARs\n");
|
||||
be_unmap_pci_bars(adapter);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче