diff options
author | Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com> | 2011-03-07 06:08:36 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-08 02:26:56 +0300 |
commit | 37eed1cbbd446dc2808e1bff717010aa978fc0de (patch) | |
tree | 64e4eb4fc3fbe037610d1ba4b9bc349c636dce18 /drivers/net/benet/be_main.c | |
parent | 19fad86f3b34f52eebc511f6cdb99e82f53aee94 (diff) | |
download | linux-37eed1cbbd446dc2808e1bff717010aa978fc0de.tar.xz |
be2net: Add error recovery during load for Lancer
Add error recovery during load for Lancer
Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: Subramanian Seetharaman <subbu.seetharaman@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet/be_main.c')
-rw-r--r-- | drivers/net/benet/be_main.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index ac7ae21bd0d1..665a9b7310f6 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -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); |