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: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f422d2a04f
commit
c5b3ad4c67
4 changed files with 22 additions and 8 deletions
|
@ -349,6 +349,7 @@ struct be_adapter {
|
|||
struct pci_dev *pdev;
|
||||
struct net_device *netdev;
|
||||
|
||||
u8 __iomem *csr; /* CSR BAR used only for BE2/3 */
|
||||
u8 __iomem *db; /* Door Bell */
|
||||
|
||||
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)
|
|||
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 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH :
|
||||
SLIPORT_SEMAPHORE_OFFSET_BE;
|
||||
|
||||
pci_read_config_dword(adapter->pdev, reg, &sem);
|
||||
*stage = sem & POST_STAGE_MASK;
|
||||
if (BEx_chip(adapter))
|
||||
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)
|
||||
|
@ -574,7 +577,7 @@ int be_fw_wait_ready(struct be_adapter *adapter)
|
|||
}
|
||||
|
||||
do {
|
||||
be_POST_stage_get(adapter, &stage);
|
||||
stage = be_POST_stage_get(adapter);
|
||||
if (stage == POST_STAGE_ARMFW_RDY)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
#define MPU_EP_CONTROL 0
|
||||
|
||||
/********** MPU semphore: used for SH & BE *************/
|
||||
#define SLIPORT_SEMAPHORE_OFFSET_BE 0x7c
|
||||
#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94
|
||||
#define SLIPORT_SEMAPHORE_OFFSET_BEx 0xac /* CSR BAR offset */
|
||||
#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 /* PCI-CFG offset */
|
||||
#define POST_STAGE_MASK 0x0000FFFF
|
||||
#define POST_ERR_MASK 0x1
|
||||
#define POST_ERR_SHIFT 31
|
||||
|
|
|
@ -3688,6 +3688,8 @@ static void be_netdev_init(struct net_device *netdev)
|
|||
|
||||
static void be_unmap_pci_bars(struct be_adapter *adapter)
|
||||
{
|
||||
if (adapter->csr)
|
||||
pci_iounmap(adapter->pdev, adapter->csr);
|
||||
if (adapter->db)
|
||||
pci_iounmap(adapter->pdev, adapter->db);
|
||||
}
|
||||
|
@ -3721,6 +3723,12 @@ static int be_map_pci_bars(struct be_adapter *adapter)
|
|||
adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
|
||||
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);
|
||||
if (addr == NULL)
|
||||
goto pci_map_err;
|
||||
|
@ -4329,6 +4337,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
|
|||
pci_restore_state(pdev);
|
||||
|
||||
/* 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);
|
||||
if (status)
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
|
|
Loading…
Reference in a new issue