Commit 25848c90 authored by Suresh Reddy's avatar Suresh Reddy Committed by David S. Miller

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: default avatarGavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: default avatarSuresh Reddy <Suresh.Reddy@emulex.com>
Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c8ba4ad0
...@@ -424,6 +424,7 @@ struct be_adapter { ...@@ -424,6 +424,7 @@ struct be_adapter {
u8 __iomem *csr; /* CSR BAR used only for BE2/3 */ u8 __iomem *csr; /* CSR BAR used only for BE2/3 */
u8 __iomem *db; /* Door Bell */ 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 mutex mbox_lock; /* For serializing mbox cmds to BE card */
struct be_dma_mem mbox_mem; struct be_dma_mem mbox_mem;
......
...@@ -2823,14 +2823,12 @@ void be_detect_error(struct be_adapter *adapter) ...@@ -2823,14 +2823,12 @@ void be_detect_error(struct be_adapter *adapter)
} }
} }
} else { } else {
pci_read_config_dword(adapter->pdev, ue_lo = ioread32(adapter->pcicfg + PCICFG_UE_STATUS_LOW);
PCICFG_UE_STATUS_LOW, &ue_lo); ue_hi = ioread32(adapter->pcicfg + PCICFG_UE_STATUS_HIGH);
pci_read_config_dword(adapter->pdev, ue_lo_mask = ioread32(adapter->pcicfg +
PCICFG_UE_STATUS_HIGH, &ue_hi); PCICFG_UE_STATUS_LOW_MASK);
pci_read_config_dword(adapter->pdev, ue_hi_mask = ioread32(adapter->pcicfg +
PCICFG_UE_STATUS_LOW_MASK, &ue_lo_mask); PCICFG_UE_STATUS_HI_MASK);
pci_read_config_dword(adapter->pdev,
PCICFG_UE_STATUS_HI_MASK, &ue_hi_mask);
ue_lo = (ue_lo & ~ue_lo_mask); ue_lo = (ue_lo & ~ue_lo_mask);
ue_hi = (ue_hi & ~ue_hi_mask); ue_hi = (ue_hi & ~ue_hi_mask);
...@@ -4874,24 +4872,37 @@ static int be_roce_map_pci_bars(struct be_adapter *adapter) ...@@ -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) static int be_map_pci_bars(struct be_adapter *adapter)
{ {
struct pci_dev *pdev = adapter->pdev;
u8 __iomem *addr; u8 __iomem *addr;
if (BEx_chip(adapter) && be_physfn(adapter)) { 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) if (!adapter->csr)
return -ENOMEM; return -ENOMEM;
} }
addr = pci_iomap(adapter->pdev, db_bar(adapter), 0); addr = pci_iomap(pdev, db_bar(adapter), 0);
if (!addr) if (!addr)
goto pci_map_err; goto pci_map_err;
adapter->db = addr; 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); be_roce_map_pci_bars(adapter);
return 0; return 0;
pci_map_err: 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); be_unmap_pci_bars(adapter);
return -ENOMEM; return -ENOMEM;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment