Commit c5b3ad4c authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

be2net: use CSR-BAR SEMAPHORE reg for BE2/BE3

The SLIPORT_SEMAPHORE register shadowed in the
config-space may not reflect the correct POST stage after
an EEH reset in BE2/3; it may return FW_READY state even though
FW is not ready. This causes the driver to prematurely
poll the FW mailbox and fail.

For BE2/3 use the CSR-BAR/0xac instead.
Reported-by: default avatarGavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f422d2a0
...@@ -349,6 +349,7 @@ struct be_adapter { ...@@ -349,6 +349,7 @@ struct be_adapter {
struct pci_dev *pdev; struct pci_dev *pdev;
struct net_device *netdev; struct net_device *netdev;
u8 __iomem *csr; /* CSR BAR used only for BE2/3 */
u8 __iomem *db; /* Door Bell */ u8 __iomem *db; /* Door Bell */
struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
......
...@@ -473,14 +473,17 @@ static int be_mbox_notify_wait(struct be_adapter *adapter) ...@@ -473,14 +473,17 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
return 0; return 0;
} }
static void be_POST_stage_get(struct be_adapter *adapter, u16 *stage) static u16 be_POST_stage_get(struct be_adapter *adapter)
{ {
u32 sem; u32 sem;
u32 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH :
SLIPORT_SEMAPHORE_OFFSET_BE;
pci_read_config_dword(adapter->pdev, reg, &sem); if (BEx_chip(adapter))
*stage = sem & POST_STAGE_MASK; sem = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx);
else
pci_read_config_dword(adapter->pdev,
SLIPORT_SEMAPHORE_OFFSET_SH, &sem);
return sem & POST_STAGE_MASK;
} }
int lancer_wait_ready(struct be_adapter *adapter) int lancer_wait_ready(struct be_adapter *adapter)
...@@ -574,7 +577,7 @@ int be_fw_wait_ready(struct be_adapter *adapter) ...@@ -574,7 +577,7 @@ int be_fw_wait_ready(struct be_adapter *adapter)
} }
do { do {
be_POST_stage_get(adapter, &stage); stage = be_POST_stage_get(adapter);
if (stage == POST_STAGE_ARMFW_RDY) if (stage == POST_STAGE_ARMFW_RDY)
return 0; return 0;
......
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
#define MPU_EP_CONTROL 0 #define MPU_EP_CONTROL 0
/********** MPU semphore: used for SH & BE *************/ /********** MPU semphore: used for SH & BE *************/
#define SLIPORT_SEMAPHORE_OFFSET_BE 0x7c #define SLIPORT_SEMAPHORE_OFFSET_BEx 0xac /* CSR BAR offset */
#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 #define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 /* PCI-CFG offset */
#define POST_STAGE_MASK 0x0000FFFF #define POST_STAGE_MASK 0x0000FFFF
#define POST_ERR_MASK 0x1 #define POST_ERR_MASK 0x1
#define POST_ERR_SHIFT 31 #define POST_ERR_SHIFT 31
......
...@@ -3688,6 +3688,8 @@ static void be_netdev_init(struct net_device *netdev) ...@@ -3688,6 +3688,8 @@ static void be_netdev_init(struct net_device *netdev)
static void be_unmap_pci_bars(struct be_adapter *adapter) static void be_unmap_pci_bars(struct be_adapter *adapter)
{ {
if (adapter->csr)
pci_iounmap(adapter->pdev, adapter->csr);
if (adapter->db) if (adapter->db)
pci_iounmap(adapter->pdev, adapter->db); pci_iounmap(adapter->pdev, adapter->db);
} }
...@@ -3721,6 +3723,12 @@ static int be_map_pci_bars(struct be_adapter *adapter) ...@@ -3721,6 +3723,12 @@ static int be_map_pci_bars(struct be_adapter *adapter)
adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
SLI_INTF_IF_TYPE_SHIFT; SLI_INTF_IF_TYPE_SHIFT;
if (BEx_chip(adapter) && be_physfn(adapter)) {
adapter->csr = pci_iomap(adapter->pdev, 2, 0);
if (adapter->csr == NULL)
return -ENOMEM;
}
addr = pci_iomap(adapter->pdev, db_bar(adapter), 0); addr = pci_iomap(adapter->pdev, db_bar(adapter), 0);
if (addr == NULL) if (addr == NULL)
goto pci_map_err; goto pci_map_err;
...@@ -4329,6 +4337,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) ...@@ -4329,6 +4337,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
pci_restore_state(pdev); pci_restore_state(pdev);
/* Check if card is ok and fw is ready */ /* Check if card is ok and fw is ready */
dev_info(&adapter->pdev->dev,
"Waiting for FW to be ready after EEH reset\n");
status = be_fw_wait_ready(adapter); status = be_fw_wait_ready(adapter);
if (status) if (status)
return PCI_ERS_RESULT_DISCONNECT; return PCI_ERS_RESULT_DISCONNECT;
......
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