diff options
author | Divy Le Ray <divy@chelsio.com> | 2009-07-07 15:48:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-08 13:54:27 -0400 |
commit | 34701fde8f4bf207ca96d10b8700a8667157854c (patch) | |
tree | 9d587019df540965231e045688db348ffde5ef2f /drivers/net/cxgb3 | |
parent | 88045b3cf0f8981129cb489c7b6bc36c21dd33a7 (diff) |
cxgb3: Drain Mac Tx fifo when the port goes down.
Drain the MAC TX fifos when a port goes down.
Back pressure might otherwise occur, leading to both
ports of the same adapter to hang.
Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cxgb3')
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index d4c4076cf087..8c381c696a3d 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -172,6 +172,23 @@ static void link_report(struct net_device *dev) | |||
172 | } | 172 | } |
173 | } | 173 | } |
174 | 174 | ||
175 | static void enable_tx_fifo_drain(struct adapter *adapter, | ||
176 | struct port_info *pi) | ||
177 | { | ||
178 | t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + pi->mac.offset, 0, | ||
179 | F_ENDROPPKT); | ||
180 | t3_write_reg(adapter, A_XGM_RX_CTRL + pi->mac.offset, 0); | ||
181 | t3_write_reg(adapter, A_XGM_TX_CTRL + pi->mac.offset, F_TXEN); | ||
182 | t3_write_reg(adapter, A_XGM_RX_CTRL + pi->mac.offset, F_RXEN); | ||
183 | } | ||
184 | |||
185 | static void disable_tx_fifo_drain(struct adapter *adapter, | ||
186 | struct port_info *pi) | ||
187 | { | ||
188 | t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + pi->mac.offset, | ||
189 | F_ENDROPPKT, 0); | ||
190 | } | ||
191 | |||
175 | void t3_os_link_fault(struct adapter *adap, int port_id, int state) | 192 | void t3_os_link_fault(struct adapter *adap, int port_id, int state) |
176 | { | 193 | { |
177 | struct net_device *dev = adap->port[port_id]; | 194 | struct net_device *dev = adap->port[port_id]; |
@@ -185,6 +202,8 @@ void t3_os_link_fault(struct adapter *adap, int port_id, int state) | |||
185 | 202 | ||
186 | netif_carrier_on(dev); | 203 | netif_carrier_on(dev); |
187 | 204 | ||
205 | disable_tx_fifo_drain(adap, pi); | ||
206 | |||
188 | /* Clear local faults */ | 207 | /* Clear local faults */ |
189 | t3_xgm_intr_disable(adap, pi->port_id); | 208 | t3_xgm_intr_disable(adap, pi->port_id); |
190 | t3_read_reg(adap, A_XGM_INT_STATUS + | 209 | t3_read_reg(adap, A_XGM_INT_STATUS + |
@@ -200,9 +219,12 @@ void t3_os_link_fault(struct adapter *adap, int port_id, int state) | |||
200 | t3_xgm_intr_enable(adap, pi->port_id); | 219 | t3_xgm_intr_enable(adap, pi->port_id); |
201 | 220 | ||
202 | t3_mac_enable(mac, MAC_DIRECTION_TX); | 221 | t3_mac_enable(mac, MAC_DIRECTION_TX); |
203 | } else | 222 | } else { |
204 | netif_carrier_off(dev); | 223 | netif_carrier_off(dev); |
205 | 224 | ||
225 | /* Flush TX FIFO */ | ||
226 | enable_tx_fifo_drain(adap, pi); | ||
227 | } | ||
206 | link_report(dev); | 228 | link_report(dev); |
207 | } | 229 | } |
208 | 230 | ||
@@ -232,6 +254,8 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat, | |||
232 | 254 | ||
233 | if (link_stat != netif_carrier_ok(dev)) { | 255 | if (link_stat != netif_carrier_ok(dev)) { |
234 | if (link_stat) { | 256 | if (link_stat) { |
257 | disable_tx_fifo_drain(adapter, pi); | ||
258 | |||
235 | t3_mac_enable(mac, MAC_DIRECTION_RX); | 259 | t3_mac_enable(mac, MAC_DIRECTION_RX); |
236 | 260 | ||
237 | /* Clear local faults */ | 261 | /* Clear local faults */ |
@@ -263,6 +287,9 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat, | |||
263 | t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); | 287 | t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); |
264 | t3_mac_disable(mac, MAC_DIRECTION_RX); | 288 | t3_mac_disable(mac, MAC_DIRECTION_RX); |
265 | t3_link_start(&pi->phy, mac, &pi->link_config); | 289 | t3_link_start(&pi->phy, mac, &pi->link_config); |
290 | |||
291 | /* Flush TX FIFO */ | ||
292 | enable_tx_fifo_drain(adapter, pi); | ||
266 | } | 293 | } |
267 | 294 | ||
268 | link_report(dev); | 295 | link_report(dev); |