diff options
author | Divy Le Ray <divy@chelsio.com> | 2007-03-18 16:10:12 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-03-23 01:48:34 -0400 |
commit | fc90664e3438c990d280f179ccb0642711d5c553 (patch) | |
tree | 8ece58a4eec002186f1c569385830f03336b50af /drivers/net/cxgb3/cxgb3_main.c | |
parent | 2e2839627a957714808f98a802d137a7a2a1df46 (diff) |
cxgb3 - Fix potential MAC hang
Under rare conditions, the MAC might hang while generating a pause frame.
This patch fine tunes the MAC settings to avoid the issue, allows for
periodic MAC state check, and triggers a recovery if hung.
Also fix one MAC statistics counter for the rev board T3B2.
Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/cxgb3/cxgb3_main.c')
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index b9bcda821f7c..d55383610559 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -1056,7 +1056,11 @@ static char stats_strings[][ETH_GSTRING_LEN] = { | |||
1056 | "VLANinsertions ", | 1056 | "VLANinsertions ", |
1057 | "TxCsumOffload ", | 1057 | "TxCsumOffload ", |
1058 | "RxCsumGood ", | 1058 | "RxCsumGood ", |
1059 | "RxDrops " | 1059 | "RxDrops ", |
1060 | |||
1061 | "CheckTXEnToggled ", | ||
1062 | "CheckResets ", | ||
1063 | |||
1060 | }; | 1064 | }; |
1061 | 1065 | ||
1062 | static int get_stats_count(struct net_device *dev) | 1066 | static int get_stats_count(struct net_device *dev) |
@@ -1170,6 +1174,9 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, | |||
1170 | *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM); | 1174 | *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM); |
1171 | *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD); | 1175 | *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD); |
1172 | *data++ = s->rx_cong_drops; | 1176 | *data++ = s->rx_cong_drops; |
1177 | |||
1178 | *data++ = s->num_toggled; | ||
1179 | *data++ = s->num_resets; | ||
1173 | } | 1180 | } |
1174 | 1181 | ||
1175 | static inline void reg_block_dump(struct adapter *ap, void *buf, | 1182 | static inline void reg_block_dump(struct adapter *ap, void *buf, |
@@ -2095,6 +2102,40 @@ static void check_link_status(struct adapter *adapter) | |||
2095 | } | 2102 | } |
2096 | } | 2103 | } |
2097 | 2104 | ||
2105 | static void check_t3b2_mac(struct adapter *adapter) | ||
2106 | { | ||
2107 | int i; | ||
2108 | |||
2109 | rtnl_lock(); /* synchronize with ifdown */ | ||
2110 | for_each_port(adapter, i) { | ||
2111 | struct net_device *dev = adapter->port[i]; | ||
2112 | struct port_info *p = netdev_priv(dev); | ||
2113 | int status; | ||
2114 | |||
2115 | if (!netif_running(dev)) | ||
2116 | continue; | ||
2117 | |||
2118 | status = 0; | ||
2119 | if (netif_running(dev)) | ||
2120 | status = t3b2_mac_watchdog_task(&p->mac); | ||
2121 | if (status == 1) | ||
2122 | p->mac.stats.num_toggled++; | ||
2123 | else if (status == 2) { | ||
2124 | struct cmac *mac = &p->mac; | ||
2125 | |||
2126 | t3_mac_set_mtu(mac, dev->mtu); | ||
2127 | t3_mac_set_address(mac, 0, dev->dev_addr); | ||
2128 | cxgb_set_rxmode(dev); | ||
2129 | t3_link_start(&p->phy, mac, &p->link_config); | ||
2130 | t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); | ||
2131 | t3_port_intr_enable(adapter, p->port_id); | ||
2132 | p->mac.stats.num_resets++; | ||
2133 | } | ||
2134 | } | ||
2135 | rtnl_unlock(); | ||
2136 | } | ||
2137 | |||
2138 | |||
2098 | static void t3_adap_check_task(struct work_struct *work) | 2139 | static void t3_adap_check_task(struct work_struct *work) |
2099 | { | 2140 | { |
2100 | struct adapter *adapter = container_of(work, struct adapter, | 2141 | struct adapter *adapter = container_of(work, struct adapter, |
@@ -2115,6 +2156,9 @@ static void t3_adap_check_task(struct work_struct *work) | |||
2115 | adapter->check_task_cnt = 0; | 2156 | adapter->check_task_cnt = 0; |
2116 | } | 2157 | } |
2117 | 2158 | ||
2159 | if (p->rev == T3_REV_B2) | ||
2160 | check_t3b2_mac(adapter); | ||
2161 | |||
2118 | /* Schedule the next check update if any port is active. */ | 2162 | /* Schedule the next check update if any port is active. */ |
2119 | spin_lock(&adapter->work_lock); | 2163 | spin_lock(&adapter->work_lock); |
2120 | if (adapter->open_device_map & PORT_MASK) | 2164 | if (adapter->open_device_map & PORT_MASK) |