diff options
author | Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com> | 2011-03-06 22:08:36 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-07 18:26:56 -0500 |
commit | 37eed1cbbd446dc2808e1bff717010aa978fc0de (patch) | |
tree | 64e4eb4fc3fbe037610d1ba4b9bc349c636dce18 | |
parent | 19fad86f3b34f52eebc511f6cdb99e82f53aee94 (diff) |
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>
-rw-r--r-- | drivers/net/benet/be_hw.h | 12 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 56 |
2 files changed, 68 insertions, 0 deletions
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 3f459f76cd1d..dbe67f353e8f 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h | |||
@@ -44,6 +44,18 @@ | |||
44 | #define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */ | 44 | #define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */ |
45 | #define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */ | 45 | #define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */ |
46 | 46 | ||
47 | |||
48 | /* Lancer SLIPORT_CONTROL SLIPORT_STATUS registers */ | ||
49 | #define SLIPORT_STATUS_OFFSET 0x404 | ||
50 | #define SLIPORT_CONTROL_OFFSET 0x408 | ||
51 | |||
52 | #define SLIPORT_STATUS_ERR_MASK 0x80000000 | ||
53 | #define SLIPORT_STATUS_RN_MASK 0x01000000 | ||
54 | #define SLIPORT_STATUS_RDY_MASK 0x00800000 | ||
55 | |||
56 | |||
57 | #define SLI_PORT_CONTROL_IP_MASK 0x08000000 | ||
58 | |||
47 | /********* Memory BAR register ************/ | 59 | /********* Memory BAR register ************/ |
48 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc | 60 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc |
49 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt | 61 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt |
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) | |||
2901 | return 0; | 2901 | return 0; |
2902 | } | 2902 | } |
2903 | 2903 | ||
2904 | static int lancer_wait_ready(struct be_adapter *adapter) | ||
2905 | { | ||
2906 | #define SLIPORT_READY_TIMEOUT 500 | ||
2907 | u32 sliport_status; | ||
2908 | int status = 0, i; | ||
2909 | |||
2910 | for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) { | ||
2911 | sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); | ||
2912 | if (sliport_status & SLIPORT_STATUS_RDY_MASK) | ||
2913 | break; | ||
2914 | |||
2915 | msleep(20); | ||
2916 | } | ||
2917 | |||
2918 | if (i == SLIPORT_READY_TIMEOUT) | ||
2919 | status = -1; | ||
2920 | |||
2921 | return status; | ||
2922 | } | ||
2923 | |||
2924 | static int lancer_test_and_set_rdy_state(struct be_adapter *adapter) | ||
2925 | { | ||
2926 | int status; | ||
2927 | u32 sliport_status, err, reset_needed; | ||
2928 | status = lancer_wait_ready(adapter); | ||
2929 | if (!status) { | ||
2930 | sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); | ||
2931 | err = sliport_status & SLIPORT_STATUS_ERR_MASK; | ||
2932 | reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK; | ||
2933 | if (err && reset_needed) { | ||
2934 | iowrite32(SLI_PORT_CONTROL_IP_MASK, | ||
2935 | adapter->db + SLIPORT_CONTROL_OFFSET); | ||
2936 | |||
2937 | /* check adapter has corrected the error */ | ||
2938 | status = lancer_wait_ready(adapter); | ||
2939 | sliport_status = ioread32(adapter->db + | ||
2940 | SLIPORT_STATUS_OFFSET); | ||
2941 | sliport_status &= (SLIPORT_STATUS_ERR_MASK | | ||
2942 | SLIPORT_STATUS_RN_MASK); | ||
2943 | if (status || sliport_status) | ||
2944 | status = -1; | ||
2945 | } else if (err || reset_needed) { | ||
2946 | status = -1; | ||
2947 | } | ||
2948 | } | ||
2949 | return status; | ||
2950 | } | ||
2951 | |||
2904 | static int __devinit be_probe(struct pci_dev *pdev, | 2952 | static int __devinit be_probe(struct pci_dev *pdev, |
2905 | const struct pci_device_id *pdev_id) | 2953 | const struct pci_device_id *pdev_id) |
2906 | { | 2954 | { |
@@ -2950,6 +2998,14 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2950 | if (status) | 2998 | if (status) |
2951 | goto free_netdev; | 2999 | goto free_netdev; |
2952 | 3000 | ||
3001 | if (lancer_chip(adapter)) { | ||
3002 | status = lancer_test_and_set_rdy_state(adapter); | ||
3003 | if (status) { | ||
3004 | dev_err(&pdev->dev, "Adapter in non recoverable error\n"); | ||
3005 | goto free_netdev; | ||
3006 | } | ||
3007 | } | ||
3008 | |||
2953 | /* sync up with fw's ready state */ | 3009 | /* sync up with fw's ready state */ |
2954 | if (be_physfn(adapter)) { | 3010 | if (be_physfn(adapter)) { |
2955 | status = be_cmd_POST(adapter); | 3011 | status = be_cmd_POST(adapter); |