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:
Sathya Perla 2013-03-05 22:23:20 +00:00 committed by David S. Miller
parent f422d2a04f
commit c5b3ad4c67
4 changed files with 22 additions and 8 deletions

View file

@ -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 */

View file

@ -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;

View file

@ -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

View file

@ -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;