diff options
author | Suresh Reddy <Suresh.Reddy@emulex.com> | 2015-03-20 06:28:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-20 13:25:51 -0400 |
commit | 25848c9015964d9d97dffd48bbb88b75a25d0a1b (patch) | |
tree | 0e321b8836c83eb8a757bfdaabb339b1ee938318 /drivers/net | |
parent | c8ba4ad0b59c511578f8f706aae711f01c990794 (diff) |
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>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 33 |
2 files changed, 23 insertions, 11 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 92eb0c82bb04..27b9fe99a9bd 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -424,6 +424,7 @@ struct be_adapter { | |||
424 | 424 | ||
425 | u8 __iomem *csr; /* CSR BAR used only for BE2/3 */ | 425 | u8 __iomem *csr; /* CSR BAR used only for BE2/3 */ |
426 | u8 __iomem *db; /* Door Bell */ | 426 | u8 __iomem *db; /* Door Bell */ |
427 | u8 __iomem *pcicfg; /* On SH,BEx only. Shadow of PCI config space */ | ||
427 | 428 | ||
428 | struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ | 429 | struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ |
429 | struct be_dma_mem mbox_mem; | 430 | struct be_dma_mem mbox_mem; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index eb2bed92bf60..e6b790f0d9dc 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -2823,14 +2823,12 @@ void be_detect_error(struct be_adapter *adapter) | |||
2823 | } | 2823 | } |
2824 | } | 2824 | } |
2825 | } else { | 2825 | } else { |
2826 | pci_read_config_dword(adapter->pdev, | 2826 | ue_lo = ioread32(adapter->pcicfg + PCICFG_UE_STATUS_LOW); |
2827 | PCICFG_UE_STATUS_LOW, &ue_lo); | 2827 | ue_hi = ioread32(adapter->pcicfg + PCICFG_UE_STATUS_HIGH); |
2828 | pci_read_config_dword(adapter->pdev, | 2828 | ue_lo_mask = ioread32(adapter->pcicfg + |
2829 | PCICFG_UE_STATUS_HIGH, &ue_hi); | 2829 | PCICFG_UE_STATUS_LOW_MASK); |
2830 | pci_read_config_dword(adapter->pdev, | 2830 | ue_hi_mask = ioread32(adapter->pcicfg + |
2831 | PCICFG_UE_STATUS_LOW_MASK, &ue_lo_mask); | 2831 | PCICFG_UE_STATUS_HI_MASK); |
2832 | pci_read_config_dword(adapter->pdev, | ||
2833 | PCICFG_UE_STATUS_HI_MASK, &ue_hi_mask); | ||
2834 | 2832 | ||
2835 | ue_lo = (ue_lo & ~ue_lo_mask); | 2833 | ue_lo = (ue_lo & ~ue_lo_mask); |
2836 | ue_hi = (ue_hi & ~ue_hi_mask); | 2834 | ue_hi = (ue_hi & ~ue_hi_mask); |
@@ -4874,24 +4872,37 @@ static int be_roce_map_pci_bars(struct be_adapter *adapter) | |||
4874 | 4872 | ||
4875 | static int be_map_pci_bars(struct be_adapter *adapter) | 4873 | static int be_map_pci_bars(struct be_adapter *adapter) |
4876 | { | 4874 | { |
4875 | struct pci_dev *pdev = adapter->pdev; | ||
4877 | u8 __iomem *addr; | 4876 | u8 __iomem *addr; |
4878 | 4877 | ||
4879 | if (BEx_chip(adapter) && be_physfn(adapter)) { | 4878 | if (BEx_chip(adapter) && be_physfn(adapter)) { |
4880 | adapter->csr = pci_iomap(adapter->pdev, 2, 0); | 4879 | adapter->csr = pci_iomap(pdev, 2, 0); |
4881 | if (!adapter->csr) | 4880 | if (!adapter->csr) |
4882 | return -ENOMEM; | 4881 | return -ENOMEM; |
4883 | } | 4882 | } |
4884 | 4883 | ||
4885 | addr = pci_iomap(adapter->pdev, db_bar(adapter), 0); | 4884 | addr = pci_iomap(pdev, db_bar(adapter), 0); |
4886 | if (!addr) | 4885 | if (!addr) |
4887 | goto pci_map_err; | 4886 | goto pci_map_err; |
4888 | adapter->db = addr; | 4887 | adapter->db = addr; |
4889 | 4888 | ||
4889 | if (skyhawk_chip(adapter) || BEx_chip(adapter)) { | ||
4890 | if (be_physfn(adapter)) { | ||
4891 | /* PCICFG is the 2nd BAR in BE2 */ | ||
4892 | addr = pci_iomap(pdev, BE2_chip(adapter) ? 1 : 0, 0); | ||
4893 | if (!addr) | ||
4894 | goto pci_map_err; | ||
4895 | adapter->pcicfg = addr; | ||
4896 | } else { | ||
4897 | adapter->pcicfg = adapter->db + SRIOV_VF_PCICFG_OFFSET; | ||
4898 | } | ||
4899 | } | ||
4900 | |||
4890 | be_roce_map_pci_bars(adapter); | 4901 | be_roce_map_pci_bars(adapter); |
4891 | return 0; | 4902 | return 0; |
4892 | 4903 | ||
4893 | pci_map_err: | 4904 | pci_map_err: |
4894 | dev_err(&adapter->pdev->dev, "Error in mapping PCI BARs\n"); | 4905 | dev_err(&pdev->dev, "Error in mapping PCI BARs\n"); |
4895 | be_unmap_pci_bars(adapter); | 4906 | be_unmap_pci_bars(adapter); |
4896 | return -ENOMEM; | 4907 | return -ENOMEM; |
4897 | } | 4908 | } |