From 34701fde8f4bf207ca96d10b8700a8667157854c Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Tue, 7 Jul 2009 19:48:32 +0000 Subject: 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 Signed-off-by: David S. Miller --- drivers/net/cxgb3/cxgb3_main.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) 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) } } +static void enable_tx_fifo_drain(struct adapter *adapter, + struct port_info *pi) +{ + t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + pi->mac.offset, 0, + F_ENDROPPKT); + t3_write_reg(adapter, A_XGM_RX_CTRL + pi->mac.offset, 0); + t3_write_reg(adapter, A_XGM_TX_CTRL + pi->mac.offset, F_TXEN); + t3_write_reg(adapter, A_XGM_RX_CTRL + pi->mac.offset, F_RXEN); +} + +static void disable_tx_fifo_drain(struct adapter *adapter, + struct port_info *pi) +{ + t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + pi->mac.offset, + F_ENDROPPKT, 0); +} + void t3_os_link_fault(struct adapter *adap, int port_id, int state) { 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) netif_carrier_on(dev); + disable_tx_fifo_drain(adap, pi); + /* Clear local faults */ t3_xgm_intr_disable(adap, pi->port_id); 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) t3_xgm_intr_enable(adap, pi->port_id); t3_mac_enable(mac, MAC_DIRECTION_TX); - } else + } else { netif_carrier_off(dev); + /* Flush TX FIFO */ + enable_tx_fifo_drain(adap, pi); + } link_report(dev); } @@ -232,6 +254,8 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat, if (link_stat != netif_carrier_ok(dev)) { if (link_stat) { + disable_tx_fifo_drain(adapter, pi); + t3_mac_enable(mac, MAC_DIRECTION_RX); /* Clear local faults */ @@ -263,6 +287,9 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat, t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); t3_mac_disable(mac, MAC_DIRECTION_RX); t3_link_start(&pi->phy, mac, &pi->link_config); + + /* Flush TX FIFO */ + enable_tx_fifo_drain(adapter, pi); } link_report(dev); -- cgit v1.2.3