Browse Source

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>
Sathya Perla 12 years ago
parent
commit
c5b3ad4c67

+ 1 - 0
drivers/net/ethernet/emulex/benet/be.h

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

+ 9 - 6
drivers/net/ethernet/emulex/benet/be_cmds.c

@@ -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);
-	*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)
 int lancer_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;
 
 

+ 2 - 2
drivers/net/ethernet/emulex/benet/be_hw.h

@@ -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_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_STAGE_MASK				0x0000FFFF
 #define POST_ERR_MASK				0x1
 #define POST_ERR_MASK				0x1
 #define POST_ERR_SHIFT				31
 #define POST_ERR_SHIFT				31

+ 10 - 0
drivers/net/ethernet/emulex/benet/be_main.c

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