Commit | Line | Data |
---|---|---|
8ceee660 BH |
1 | /**************************************************************************** |
2 | * Driver for Solarflare Solarstorm network controllers and boards | |
3 | * Copyright 2005-2006 Fen Systems Ltd. | |
0a6f40c6 | 4 | * Copyright 2006-2010 Solarflare Communications Inc. |
8ceee660 BH |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License version 2 as published | |
8 | * by the Free Software Foundation, incorporated herein by reference. | |
9 | */ | |
10 | ||
11 | #include <linux/delay.h> | |
12 | #include "net_driver.h" | |
13 | #include "efx.h" | |
744093c9 | 14 | #include "nic.h" |
3e6c4538 | 15 | #include "regs.h" |
12d00cad | 16 | #include "io.h" |
8ceee660 | 17 | #include "mdio_10g.h" |
8ceee660 BH |
18 | #include "workarounds.h" |
19 | ||
8ceee660 BH |
20 | /************************************************************************** |
21 | * | |
22 | * MAC operations | |
23 | * | |
24 | *************************************************************************/ | |
8ceee660 BH |
25 | |
26 | /* Configure the XAUI driver that is an output from Falcon */ | |
b7b40eeb | 27 | void falcon_setup_xaui(struct efx_nic *efx) |
8ceee660 | 28 | { |
c1e5fcc9 | 29 | efx_oword_t sdctl, txdrv; |
8ceee660 BH |
30 | |
31 | /* Move the XAUI into low power, unless there is no PHY, in | |
32 | * which case the XAUI will have to drive a cable. */ | |
33 | if (efx->phy_type == PHY_TYPE_NONE) | |
34 | return; | |
35 | ||
12d00cad | 36 | efx_reado(efx, &sdctl, FR_AB_XX_SD_CTL); |
3e6c4538 BH |
37 | EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVD, FFE_AB_XX_SD_CTL_DRV_DEF); |
38 | EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVD, FFE_AB_XX_SD_CTL_DRV_DEF); | |
39 | EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVC, FFE_AB_XX_SD_CTL_DRV_DEF); | |
40 | EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVC, FFE_AB_XX_SD_CTL_DRV_DEF); | |
41 | EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVB, FFE_AB_XX_SD_CTL_DRV_DEF); | |
42 | EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVB, FFE_AB_XX_SD_CTL_DRV_DEF); | |
43 | EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVA, FFE_AB_XX_SD_CTL_DRV_DEF); | |
44 | EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVA, FFE_AB_XX_SD_CTL_DRV_DEF); | |
12d00cad | 45 | efx_writeo(efx, &sdctl, FR_AB_XX_SD_CTL); |
c1e5fcc9 BH |
46 | |
47 | EFX_POPULATE_OWORD_8(txdrv, | |
3e6c4538 BH |
48 | FRF_AB_XX_DEQD, FFE_AB_XX_TXDRV_DEQ_DEF, |
49 | FRF_AB_XX_DEQC, FFE_AB_XX_TXDRV_DEQ_DEF, | |
50 | FRF_AB_XX_DEQB, FFE_AB_XX_TXDRV_DEQ_DEF, | |
51 | FRF_AB_XX_DEQA, FFE_AB_XX_TXDRV_DEQ_DEF, | |
52 | FRF_AB_XX_DTXD, FFE_AB_XX_TXDRV_DTX_DEF, | |
53 | FRF_AB_XX_DTXC, FFE_AB_XX_TXDRV_DTX_DEF, | |
54 | FRF_AB_XX_DTXB, FFE_AB_XX_TXDRV_DTX_DEF, | |
55 | FRF_AB_XX_DTXA, FFE_AB_XX_TXDRV_DTX_DEF); | |
12d00cad | 56 | efx_writeo(efx, &txdrv, FR_AB_XX_TXDRV_CTL); |
8ceee660 BH |
57 | } |
58 | ||
ef08af03 | 59 | int falcon_reset_xaui(struct efx_nic *efx) |
8ceee660 | 60 | { |
55edc6e6 | 61 | struct falcon_nic_data *nic_data = efx->nic_data; |
c1e5fcc9 | 62 | efx_oword_t reg; |
8ceee660 BH |
63 | int count; |
64 | ||
55edc6e6 BH |
65 | /* Don't fetch MAC statistics over an XMAC reset */ |
66 | WARN_ON(nic_data->stats_disable_count == 0); | |
67 | ||
d4ec09ac | 68 | /* Start reset sequence */ |
80cb9a0f | 69 | EFX_POPULATE_OWORD_1(reg, FRF_AB_XX_RST_XX_EN, 1); |
12d00cad | 70 | efx_writeo(efx, ®, FR_AB_XX_PWR_RST); |
8ceee660 | 71 | |
d4ec09ac BH |
72 | /* Wait up to 10 ms for completion, then reinitialise */ |
73 | for (count = 0; count < 1000; count++) { | |
12d00cad | 74 | efx_reado(efx, ®, FR_AB_XX_PWR_RST); |
3e6c4538 BH |
75 | if (EFX_OWORD_FIELD(reg, FRF_AB_XX_RST_XX_EN) == 0 && |
76 | EFX_OWORD_FIELD(reg, FRF_AB_XX_SD_RST_ACT) == 0) { | |
8ceee660 BH |
77 | falcon_setup_xaui(efx); |
78 | return 0; | |
79 | } | |
80 | udelay(10); | |
81 | } | |
62776d03 BH |
82 | netif_err(efx, hw, efx->net_dev, |
83 | "timed out waiting for XAUI/XGXS reset\n"); | |
8ceee660 BH |
84 | return -ETIMEDOUT; |
85 | } | |
86 | ||
ef524f2e | 87 | static void falcon_ack_status_intr(struct efx_nic *efx) |
8ceee660 | 88 | { |
cef68bde | 89 | struct falcon_nic_data *nic_data = efx->nic_data; |
c1e5fcc9 | 90 | efx_oword_t reg; |
8ceee660 | 91 | |
daeda630 | 92 | if ((efx_nic_rev(efx) != EFX_REV_FALCON_B0) || LOOPBACK_INTERNAL(efx)) |
177dfcd8 | 93 | return; |
8ceee660 | 94 | |
ef524f2e | 95 | /* We expect xgmii faults if the wireside link is down */ |
eb50c0d6 | 96 | if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up) |
177dfcd8 | 97 | return; |
8ceee660 | 98 | |
177dfcd8 BH |
99 | /* We can only use this interrupt to signal the negative edge of |
100 | * xaui_align [we have to poll the positive edge]. */ | |
cef68bde | 101 | if (nic_data->xmac_poll_required) |
8ceee660 BH |
102 | return; |
103 | ||
ef524f2e | 104 | efx_reado(efx, ®, FR_AB_XM_MGT_INT_MSK); |
8ceee660 BH |
105 | } |
106 | ||
a355020a | 107 | static bool falcon_xgxs_link_ok(struct efx_nic *efx) |
8ceee660 | 108 | { |
c1e5fcc9 | 109 | efx_oword_t reg; |
dc8cfa55 BH |
110 | bool align_done, link_ok = false; |
111 | int sync_status; | |
8ceee660 BH |
112 | |
113 | /* Read link status */ | |
12d00cad | 114 | efx_reado(efx, ®, FR_AB_XX_CORE_STAT); |
8ceee660 | 115 | |
3e6c4538 BH |
116 | align_done = EFX_OWORD_FIELD(reg, FRF_AB_XX_ALIGN_DONE); |
117 | sync_status = EFX_OWORD_FIELD(reg, FRF_AB_XX_SYNC_STAT); | |
118 | if (align_done && (sync_status == FFE_AB_XX_STAT_ALL_LANES)) | |
dc8cfa55 | 119 | link_ok = true; |
8ceee660 BH |
120 | |
121 | /* Clear link status ready for next read */ | |
3e6c4538 BH |
122 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_COMMA_DET, FFE_AB_XX_STAT_ALL_LANES); |
123 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_CHAR_ERR, FFE_AB_XX_STAT_ALL_LANES); | |
124 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_DISPERR, FFE_AB_XX_STAT_ALL_LANES); | |
12d00cad | 125 | efx_writeo(efx, ®, FR_AB_XX_CORE_STAT); |
8ceee660 | 126 | |
8ceee660 BH |
127 | return link_ok; |
128 | } | |
129 | ||
a355020a BH |
130 | static bool falcon_xmac_link_ok(struct efx_nic *efx) |
131 | { | |
132 | /* | |
133 | * Check MAC's XGXS link status except when using XGMII loopback | |
134 | * which bypasses the XGXS block. | |
135 | * If possible, check PHY's XGXS link status except when using | |
136 | * MAC loopback. | |
137 | */ | |
138 | return (efx->loopback_mode == LOOPBACK_XGMII || | |
139 | falcon_xgxs_link_ok(efx)) && | |
140 | (!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) || | |
9c636baf | 141 | LOOPBACK_INTERNAL(efx) || |
a355020a BH |
142 | efx_mdio_phyxgxs_lane_sync(efx)); |
143 | } | |
144 | ||
d215697f | 145 | static void falcon_reconfigure_xmac_core(struct efx_nic *efx) |
8ceee660 BH |
146 | { |
147 | unsigned int max_frame_len; | |
c1e5fcc9 | 148 | efx_oword_t reg; |
eb50c0d6 | 149 | bool rx_fc = !!(efx->link_state.fc & EFX_FC_RX); |
4b0d29dc | 150 | bool tx_fc = !!(efx->link_state.fc & EFX_FC_TX); |
8ceee660 BH |
151 | |
152 | /* Configure MAC - cut-thru mode is hard wired on */ | |
80cb9a0f | 153 | EFX_POPULATE_OWORD_3(reg, |
3e6c4538 BH |
154 | FRF_AB_XM_RX_JUMBO_MODE, 1, |
155 | FRF_AB_XM_TX_STAT_EN, 1, | |
156 | FRF_AB_XM_RX_STAT_EN, 1); | |
12d00cad | 157 | efx_writeo(efx, ®, FR_AB_XM_GLB_CFG); |
8ceee660 BH |
158 | |
159 | /* Configure TX */ | |
80cb9a0f | 160 | EFX_POPULATE_OWORD_6(reg, |
3e6c4538 BH |
161 | FRF_AB_XM_TXEN, 1, |
162 | FRF_AB_XM_TX_PRMBL, 1, | |
163 | FRF_AB_XM_AUTO_PAD, 1, | |
164 | FRF_AB_XM_TXCRC, 1, | |
4b0d29dc | 165 | FRF_AB_XM_FCNTL, tx_fc, |
3e6c4538 | 166 | FRF_AB_XM_IPG, 0x3); |
12d00cad | 167 | efx_writeo(efx, ®, FR_AB_XM_TX_CFG); |
8ceee660 BH |
168 | |
169 | /* Configure RX */ | |
80cb9a0f | 170 | EFX_POPULATE_OWORD_5(reg, |
3e6c4538 BH |
171 | FRF_AB_XM_RXEN, 1, |
172 | FRF_AB_XM_AUTO_DEPAD, 0, | |
173 | FRF_AB_XM_ACPT_ALL_MCAST, 1, | |
174 | FRF_AB_XM_ACPT_ALL_UCAST, efx->promiscuous, | |
175 | FRF_AB_XM_PASS_CRC_ERR, 1); | |
12d00cad | 176 | efx_writeo(efx, ®, FR_AB_XM_RX_CFG); |
8ceee660 BH |
177 | |
178 | /* Set frame length */ | |
179 | max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu); | |
80cb9a0f | 180 | EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_MAX_RX_FRM_SIZE, max_frame_len); |
12d00cad | 181 | efx_writeo(efx, ®, FR_AB_XM_RX_PARAM); |
80cb9a0f | 182 | EFX_POPULATE_OWORD_2(reg, |
3e6c4538 BH |
183 | FRF_AB_XM_MAX_TX_FRM_SIZE, max_frame_len, |
184 | FRF_AB_XM_TX_JUMBO_MODE, 1); | |
12d00cad | 185 | efx_writeo(efx, ®, FR_AB_XM_TX_PARAM); |
8ceee660 | 186 | |
80cb9a0f | 187 | EFX_POPULATE_OWORD_2(reg, |
3e6c4538 BH |
188 | FRF_AB_XM_PAUSE_TIME, 0xfffe, /* MAX PAUSE TIME */ |
189 | FRF_AB_XM_DIS_FCNTL, !rx_fc); | |
12d00cad | 190 | efx_writeo(efx, ®, FR_AB_XM_FC); |
8ceee660 BH |
191 | |
192 | /* Set MAC address */ | |
3e6c4538 | 193 | memcpy(®, &efx->net_dev->dev_addr[0], 4); |
12d00cad | 194 | efx_writeo(efx, ®, FR_AB_XM_ADR_LO); |
3e6c4538 | 195 | memcpy(®, &efx->net_dev->dev_addr[4], 2); |
12d00cad | 196 | efx_writeo(efx, ®, FR_AB_XM_ADR_HI); |
8ceee660 BH |
197 | } |
198 | ||
3273c2e8 BH |
199 | static void falcon_reconfigure_xgxs_core(struct efx_nic *efx) |
200 | { | |
c1e5fcc9 | 201 | efx_oword_t reg; |
dc8cfa55 BH |
202 | bool xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS); |
203 | bool xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI); | |
204 | bool xgmii_loopback = (efx->loopback_mode == LOOPBACK_XGMII); | |
3273c2e8 BH |
205 | |
206 | /* XGXS block is flaky and will need to be reset if moving | |
207 | * into our out of XGMII, XGXS or XAUI loopbacks. */ | |
208 | if (EFX_WORKAROUND_5147(efx)) { | |
dc8cfa55 BH |
209 | bool old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback; |
210 | bool reset_xgxs; | |
3273c2e8 | 211 | |
12d00cad | 212 | efx_reado(efx, ®, FR_AB_XX_CORE_STAT); |
3e6c4538 BH |
213 | old_xgxs_loopback = EFX_OWORD_FIELD(reg, FRF_AB_XX_XGXS_LB_EN); |
214 | old_xgmii_loopback = | |
215 | EFX_OWORD_FIELD(reg, FRF_AB_XX_XGMII_LB_EN); | |
3273c2e8 | 216 | |
12d00cad | 217 | efx_reado(efx, ®, FR_AB_XX_SD_CTL); |
3e6c4538 | 218 | old_xaui_loopback = EFX_OWORD_FIELD(reg, FRF_AB_XX_LPBKA); |
3273c2e8 BH |
219 | |
220 | /* The PHY driver may have turned XAUI off */ | |
221 | reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) || | |
222 | (xaui_loopback != old_xaui_loopback) || | |
223 | (xgmii_loopback != old_xgmii_loopback)); | |
8c8661e4 BH |
224 | |
225 | if (reset_xgxs) | |
226 | falcon_reset_xaui(efx); | |
3273c2e8 BH |
227 | } |
228 | ||
12d00cad | 229 | efx_reado(efx, ®, FR_AB_XX_CORE_STAT); |
3e6c4538 | 230 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_FORCE_SIG, |
3273c2e8 | 231 | (xgxs_loopback || xaui_loopback) ? |
3e6c4538 BH |
232 | FFE_AB_XX_FORCE_SIG_ALL_LANES : 0); |
233 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_XGXS_LB_EN, xgxs_loopback); | |
234 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_XGMII_LB_EN, xgmii_loopback); | |
12d00cad | 235 | efx_writeo(efx, ®, FR_AB_XX_CORE_STAT); |
3e6c4538 | 236 | |
12d00cad | 237 | efx_reado(efx, ®, FR_AB_XX_SD_CTL); |
3e6c4538 BH |
238 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKD, xaui_loopback); |
239 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKC, xaui_loopback); | |
240 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKB, xaui_loopback); | |
241 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKA, xaui_loopback); | |
12d00cad | 242 | efx_writeo(efx, ®, FR_AB_XX_SD_CTL); |
3273c2e8 BH |
243 | } |
244 | ||
245 | ||
9007b9fa | 246 | /* Try to bring up the Falcon side of the Falcon-Phy XAUI link */ |
a355020a | 247 | static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries) |
8ceee660 | 248 | { |
a355020a | 249 | bool mac_up = falcon_xmac_link_ok(efx); |
8ceee660 | 250 | |
e58f69f4 | 251 | if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS || |
f8b87c17 | 252 | efx_phy_mode_disabled(efx->phy_mode)) |
177dfcd8 | 253 | /* XAUI link is expected to be down */ |
9007b9fa | 254 | return mac_up; |
8ceee660 | 255 | |
55edc6e6 BH |
256 | falcon_stop_nic_stats(efx); |
257 | ||
9007b9fa | 258 | while (!mac_up && tries) { |
62776d03 | 259 | netif_dbg(efx, hw, efx->net_dev, "bashing xaui\n"); |
91ad757c | 260 | falcon_reset_xaui(efx); |
8ceee660 | 261 | udelay(200); |
8ceee660 | 262 | |
a355020a | 263 | mac_up = falcon_xmac_link_ok(efx); |
177dfcd8 BH |
264 | --tries; |
265 | } | |
55edc6e6 BH |
266 | |
267 | falcon_start_nic_stats(efx); | |
9007b9fa BH |
268 | |
269 | return mac_up; | |
270 | } | |
271 | ||
710b208d | 272 | bool falcon_xmac_check_fault(struct efx_nic *efx) |
9007b9fa | 273 | { |
a355020a | 274 | return !falcon_xmac_link_ok_retry(efx, 5); |
8ceee660 BH |
275 | } |
276 | ||
710b208d | 277 | int falcon_reconfigure_xmac(struct efx_nic *efx) |
8ceee660 | 278 | { |
cef68bde BH |
279 | struct falcon_nic_data *nic_data = efx->nic_data; |
280 | ||
3273c2e8 | 281 | falcon_reconfigure_xgxs_core(efx); |
8ceee660 | 282 | falcon_reconfigure_xmac_core(efx); |
3273c2e8 | 283 | |
8ceee660 BH |
284 | falcon_reconfigure_mac_wrapper(efx); |
285 | ||
cef68bde | 286 | nic_data->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5); |
ef524f2e | 287 | falcon_ack_status_intr(efx); |
d3245b28 BH |
288 | |
289 | return 0; | |
8ceee660 BH |
290 | } |
291 | ||
710b208d | 292 | void falcon_update_stats_xmac(struct efx_nic *efx) |
8ceee660 BH |
293 | { |
294 | struct efx_mac_stats *mac_stats = &efx->mac_stats; | |
8ceee660 BH |
295 | |
296 | /* Update MAC stats from DMAed values */ | |
297 | FALCON_STAT(efx, XgRxOctets, rx_bytes); | |
298 | FALCON_STAT(efx, XgRxOctetsOK, rx_good_bytes); | |
299 | FALCON_STAT(efx, XgRxPkts, rx_packets); | |
300 | FALCON_STAT(efx, XgRxPktsOK, rx_good); | |
301 | FALCON_STAT(efx, XgRxBroadcastPkts, rx_broadcast); | |
302 | FALCON_STAT(efx, XgRxMulticastPkts, rx_multicast); | |
303 | FALCON_STAT(efx, XgRxUnicastPkts, rx_unicast); | |
304 | FALCON_STAT(efx, XgRxUndersizePkts, rx_lt64); | |
305 | FALCON_STAT(efx, XgRxOversizePkts, rx_gtjumbo); | |
306 | FALCON_STAT(efx, XgRxJabberPkts, rx_bad_gtjumbo); | |
307 | FALCON_STAT(efx, XgRxUndersizeFCSerrorPkts, rx_bad_lt64); | |
308 | FALCON_STAT(efx, XgRxDropEvents, rx_overflow); | |
309 | FALCON_STAT(efx, XgRxFCSerrorPkts, rx_bad); | |
310 | FALCON_STAT(efx, XgRxAlignError, rx_align_error); | |
311 | FALCON_STAT(efx, XgRxSymbolError, rx_symbol_error); | |
312 | FALCON_STAT(efx, XgRxInternalMACError, rx_internal_error); | |
313 | FALCON_STAT(efx, XgRxControlPkts, rx_control); | |
314 | FALCON_STAT(efx, XgRxPausePkts, rx_pause); | |
315 | FALCON_STAT(efx, XgRxPkts64Octets, rx_64); | |
316 | FALCON_STAT(efx, XgRxPkts65to127Octets, rx_65_to_127); | |
317 | FALCON_STAT(efx, XgRxPkts128to255Octets, rx_128_to_255); | |
318 | FALCON_STAT(efx, XgRxPkts256to511Octets, rx_256_to_511); | |
319 | FALCON_STAT(efx, XgRxPkts512to1023Octets, rx_512_to_1023); | |
320 | FALCON_STAT(efx, XgRxPkts1024to15xxOctets, rx_1024_to_15xx); | |
321 | FALCON_STAT(efx, XgRxPkts15xxtoMaxOctets, rx_15xx_to_jumbo); | |
322 | FALCON_STAT(efx, XgRxLengthError, rx_length_error); | |
323 | FALCON_STAT(efx, XgTxPkts, tx_packets); | |
324 | FALCON_STAT(efx, XgTxOctets, tx_bytes); | |
325 | FALCON_STAT(efx, XgTxMulticastPkts, tx_multicast); | |
326 | FALCON_STAT(efx, XgTxBroadcastPkts, tx_broadcast); | |
327 | FALCON_STAT(efx, XgTxUnicastPkts, tx_unicast); | |
328 | FALCON_STAT(efx, XgTxControlPkts, tx_control); | |
329 | FALCON_STAT(efx, XgTxPausePkts, tx_pause); | |
330 | FALCON_STAT(efx, XgTxPkts64Octets, tx_64); | |
331 | FALCON_STAT(efx, XgTxPkts65to127Octets, tx_65_to_127); | |
332 | FALCON_STAT(efx, XgTxPkts128to255Octets, tx_128_to_255); | |
333 | FALCON_STAT(efx, XgTxPkts256to511Octets, tx_256_to_511); | |
334 | FALCON_STAT(efx, XgTxPkts512to1023Octets, tx_512_to_1023); | |
335 | FALCON_STAT(efx, XgTxPkts1024to15xxOctets, tx_1024_to_15xx); | |
336 | FALCON_STAT(efx, XgTxPkts1519toMaxOctets, tx_15xx_to_jumbo); | |
337 | FALCON_STAT(efx, XgTxUndersizePkts, tx_lt64); | |
338 | FALCON_STAT(efx, XgTxOversizePkts, tx_gtjumbo); | |
339 | FALCON_STAT(efx, XgTxNonTcpUdpPkt, tx_non_tcpudp); | |
340 | FALCON_STAT(efx, XgTxMacSrcErrPkt, tx_mac_src_error); | |
341 | FALCON_STAT(efx, XgTxIpSrcErrPkt, tx_ip_src_error); | |
342 | ||
343 | /* Update derived statistics */ | |
b7f514af BH |
344 | efx_update_diff_stat(&mac_stats->tx_good_bytes, |
345 | mac_stats->tx_bytes - mac_stats->tx_bad_bytes - | |
346 | mac_stats->tx_control * 64); | |
347 | efx_update_diff_stat(&mac_stats->rx_bad_bytes, | |
348 | mac_stats->rx_bytes - mac_stats->rx_good_bytes - | |
349 | mac_stats->rx_control * 64); | |
8ceee660 BH |
350 | } |
351 | ||
9007b9fa | 352 | void falcon_poll_xmac(struct efx_nic *efx) |
766ca0fa | 353 | { |
cef68bde BH |
354 | struct falcon_nic_data *nic_data = efx->nic_data; |
355 | ||
9007b9fa | 356 | if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up || |
cef68bde | 357 | !nic_data->xmac_poll_required) |
766ca0fa | 358 | return; |
3273c2e8 | 359 | |
cef68bde | 360 | nic_data->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1); |
ef524f2e | 361 | falcon_ack_status_intr(efx); |
8ceee660 | 362 | } |