]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/bnx2x-eeh.patch
Disable build of xen kernel.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / bnx2x-eeh.patch
1 From: Yitchak Gertner <gertner@broadcom.com>
2 Subject: bnx2x: EEH recovery fix
3 Acked-by: Karsten Keil <kkeil@novell.com>
4 Reference: bnc#433875
5
6
7 When 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