]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.drivers/bnx2x-eeh.patch
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / bnx2x-eeh.patch
CommitLineData
00e5a55c
BS
1From: Yitchak Gertner <gertner@broadcom.com>
2Subject: bnx2x: EEH recovery fix
3Acked-by: Karsten Keil <kkeil@novell.com>
4Reference: bnc#433875
5
6
7When EEH detects an i/o error it resets the device thus it cannot be accessed.
8 In this case the driver needs to unload its interface only with OS, kernel and
9 network stack but not with the device.
10 After successful recovery, the driver can load normally.
11
12 Signed-off-by: Yitchak Gertner <gertner@broadcom.com>
13 Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
14 Signed-off-by: David S. Miller <davem@davemloft.net>
15
16
17---
18 drivers/net/bnx2x_main.c | 95 +++++++++++++++++++++++++++++++++++++++++------
19 1 file changed, 83 insertions(+), 12 deletions(-)
20
21--- a/drivers/net/bnx2x_main.c
22+++ b/drivers/net/bnx2x_main.c
23@@ -59,8 +59,8 @@
24 #include "bnx2x.h"
25 #include "bnx2x_init.h"
26
27-#define DRV_MODULE_VERSION "1.45.21"
28-#define DRV_MODULE_RELDATE "2008/09/03"
29+#define DRV_MODULE_VERSION "1.45.22"
30+#define DRV_MODULE_RELDATE "2008/09/09"
31 #define BNX2X_BC_VER 0x040200
32
33 /* Time in jiffies before concluding the transmitter is hung */
34@@ -649,15 +649,16 @@ static void bnx2x_int_disable(struct bnx
35 BNX2X_ERR("BUG! proper val not read from IGU!\n");
36 }
37
38-static void bnx2x_int_disable_sync(struct bnx2x *bp)
39+static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
40 {
41 int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
42 int i;
43
44 /* disable interrupt handling */
45 atomic_inc(&bp->intr_sem);
46- /* prevent the HW from sending interrupts */
47- bnx2x_int_disable(bp);
48+ if (disable_hw)
49+ /* prevent the HW from sending interrupts */
50+ bnx2x_int_disable(bp);
51
52 /* make sure all ISRs are done */
53 if (msix) {
54@@ -6086,9 +6087,9 @@ static void bnx2x_netif_start(struct bnx
55 }
56 }
57
58-static void bnx2x_netif_stop(struct bnx2x *bp)
59+static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
60 {
61- bnx2x_int_disable_sync(bp);
62+ bnx2x_int_disable_sync(bp, disable_hw);
63 if (netif_running(bp->dev)) {
64 bnx2x_napi_disable(bp);
65 netif_tx_disable(bp->dev);
66@@ -6475,7 +6476,7 @@ load_rings_free:
67 for_each_queue(bp, i)
68 bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
69 load_int_disable:
70- bnx2x_int_disable_sync(bp);
71+ bnx2x_int_disable_sync(bp, 1);
72 /* Release IRQs */
73 bnx2x_free_irq(bp);
74 load_error:
75@@ -6651,7 +6652,7 @@ static int bnx2x_nic_unload(struct bnx2x
76 bp->rx_mode = BNX2X_RX_MODE_NONE;
77 bnx2x_set_storm_rx_mode(bp);
78
79- bnx2x_netif_stop(bp);
80+ bnx2x_netif_stop(bp, 1);
81 if (!netif_running(bp->dev))
82 bnx2x_napi_disable(bp);
83 del_timer_sync(&bp->timer);
84@@ -8796,7 +8797,7 @@ static int bnx2x_test_loopback(struct bn
85 if (!netif_running(bp->dev))
86 return BNX2X_LOOPBACK_FAILED;
87
88- bnx2x_netif_stop(bp);
89+ bnx2x_netif_stop(bp, 1);
90
91 if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
92 DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
93@@ -10351,6 +10352,74 @@ static int bnx2x_resume(struct pci_dev *
94 return rc;
95 }
96
97+static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
98+{
99+ int i;
100+
101+ bp->state = BNX2X_STATE_ERROR;
102+
103+ bp->rx_mode = BNX2X_RX_MODE_NONE;
104+
105+ bnx2x_netif_stop(bp, 0);
106+
107+ del_timer_sync(&bp->timer);
108+ bp->stats_state = STATS_STATE_DISABLED;
109+ DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
110+
111+ /* Release IRQs */
112+ bnx2x_free_irq(bp);
113+
114+ if (CHIP_IS_E1(bp)) {
115+ struct mac_configuration_cmd *config =
116+ bnx2x_sp(bp, mcast_config);
117+
118+ for (i = 0; i < config->hdr.length_6b; i++)
119+ CAM_INVALIDATE(config->config_table[i]);
120+ }
121+
122+ /* Free SKBs, SGEs, TPA pool and driver internals */
123+ bnx2x_free_skbs(bp);
124+ for_each_queue(bp, i)
125+ bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
126+ bnx2x_free_mem(bp);
127+
128+ bp->state = BNX2X_STATE_CLOSED;
129+
130+ netif_carrier_off(bp->dev);
131+
132+ return 0;
133+}
134+
135+static void bnx2x_eeh_recover(struct bnx2x *bp)
136+{
137+ u32 val;
138+
139+ mutex_init(&bp->port.phy_mutex);
140+
141+ bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
142+ bp->link_params.shmem_base = bp->common.shmem_base;
143+ BNX2X_DEV_INFO("shmem offset is 0x%x\n", bp->common.shmem_base);
144+
145+ if (!bp->common.shmem_base ||
146+ (bp->common.shmem_base < 0xA0000) ||
147+ (bp->common.shmem_base >= 0xC0000)) {
148+ BNX2X_DEV_INFO("MCP not active\n");
149+ bp->flags |= NO_MCP_FLAG;
150+ return;
151+ }
152+
153+ val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
154+ if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
155+ != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
156+ BNX2X_ERR("BAD MCP validity signature\n");
157+
158+ if (!BP_NOMCP(bp)) {
159+ bp->fw_seq = (SHMEM_RD(bp, func_mb[BP_FUNC(bp)].drv_mb_header)
160+ & DRV_MSG_SEQ_NUMBER_MASK);
161+ BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
162+ }
163+}
164+
165 /**
166 * bnx2x_io_error_detected - called when PCI error is detected
167 * @pdev: Pointer to PCI device
168@@ -10370,7 +10439,7 @@ static pci_ers_result_t bnx2x_io_error_d
169 netif_device_detach(dev);
170
171 if (netif_running(dev))
172- bnx2x_nic_unload(bp, UNLOAD_CLOSE);
173+ bnx2x_eeh_nic_unload(bp);
174
175 pci_disable_device(pdev);
176
177@@ -10425,8 +10494,10 @@ static void bnx2x_io_resume(struct pci_d
178
179 rtnl_lock();
180
181+ bnx2x_eeh_recover(bp);
182+
183 if (netif_running(dev))
184- bnx2x_nic_load(bp, LOAD_OPEN);
185+ bnx2x_nic_load(bp, LOAD_NORMAL);
186
187 netif_device_attach(dev);
188