Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37eed1cb authored by Padmanabh Ratnakar's avatar Padmanabh Ratnakar Committed by David S. Miller
Browse files

be2net: Add error recovery during load for Lancer



Add error recovery during load for Lancer

Signed-off-by: default avatarPadmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarSubramanian Seetharaman <subbu.seetharaman@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 19fad86f
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -44,6 +44,18 @@
#define POST_STAGE_BE_RESET		0x3 /* Host wants to reset chip */
#define POST_STAGE_ARMFW_RDY		0xc000	/* FW is done with POST */


/* Lancer SLIPORT_CONTROL SLIPORT_STATUS registers */
#define SLIPORT_STATUS_OFFSET		0x404
#define SLIPORT_CONTROL_OFFSET		0x408

#define SLIPORT_STATUS_ERR_MASK		0x80000000
#define SLIPORT_STATUS_RN_MASK		0x01000000
#define SLIPORT_STATUS_RDY_MASK		0x00800000


#define SLI_PORT_CONTROL_IP_MASK	0x08000000

/********* Memory BAR register ************/
#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 	0xfc
/* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
+56 −0
Original line number Diff line number Diff line
@@ -2901,6 +2901,54 @@ static int be_dev_family_check(struct be_adapter *adapter)
	return 0;
}

static int lancer_wait_ready(struct be_adapter *adapter)
{
#define SLIPORT_READY_TIMEOUT 500
	u32 sliport_status;
	int status = 0, i;

	for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
		sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
		if (sliport_status & SLIPORT_STATUS_RDY_MASK)
			break;

		msleep(20);
	}

	if (i == SLIPORT_READY_TIMEOUT)
		status = -1;

	return status;
}

static int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
{
	int status;
	u32 sliport_status, err, reset_needed;
	status = lancer_wait_ready(adapter);
	if (!status) {
		sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
		err = sliport_status & SLIPORT_STATUS_ERR_MASK;
		reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK;
		if (err && reset_needed) {
			iowrite32(SLI_PORT_CONTROL_IP_MASK,
					adapter->db + SLIPORT_CONTROL_OFFSET);

			/* check adapter has corrected the error */
			status = lancer_wait_ready(adapter);
			sliport_status = ioread32(adapter->db +
							SLIPORT_STATUS_OFFSET);
			sliport_status &= (SLIPORT_STATUS_ERR_MASK |
						SLIPORT_STATUS_RN_MASK);
			if (status || sliport_status)
				status = -1;
		} else if (err || reset_needed) {
			status = -1;
		}
	}
	return status;
}

static int __devinit be_probe(struct pci_dev *pdev,
			const struct pci_device_id *pdev_id)
{
@@ -2950,6 +2998,14 @@ static int __devinit be_probe(struct pci_dev *pdev,
	if (status)
		goto free_netdev;

	if (lancer_chip(adapter)) {
		status = lancer_test_and_set_rdy_state(adapter);
		if (status) {
			dev_err(&pdev->dev, "Adapter in non recoverable error\n");
			goto free_netdev;
		}
	}

	/* sync up with fw's ready state */
	if (be_physfn(adapter)) {
		status = be_cmd_POST(adapter);