blob: 44e65584ee324c92e3505769a74f5db37a90e884 [file] [log] [blame]
Ben Hutchings8ceee662008-04-27 12:55:59 +01001/****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005-2006 Fen Systems Ltd.
4 * Copyright 2006-2008 Solarflare Communications Inc.
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"
14#include "falcon.h"
Ben Hutchings3e6c4532009-10-23 08:30:36 +000015#include "regs.h"
Ben Hutchings8ceee662008-04-27 12:55:59 +010016#include "falcon_io.h"
17#include "mac.h"
Ben Hutchings8ceee662008-04-27 12:55:59 +010018#include "mdio_10g.h"
19#include "phy.h"
Ben Hutchings8ceee662008-04-27 12:55:59 +010020#include "workarounds.h"
21
22/**************************************************************************
23 *
Ben Hutchings8ceee662008-04-27 12:55:59 +010024 * MAC operations
25 *
26 *************************************************************************/
Ben Hutchings8ceee662008-04-27 12:55:59 +010027
28/* Configure the XAUI driver that is an output from Falcon */
29static void falcon_setup_xaui(struct efx_nic *efx)
30{
Ben Hutchingsc1e5fcc2008-09-01 12:48:41 +010031 efx_oword_t sdctl, txdrv;
Ben Hutchings8ceee662008-04-27 12:55:59 +010032
33 /* Move the XAUI into low power, unless there is no PHY, in
34 * which case the XAUI will have to drive a cable. */
35 if (efx->phy_type == PHY_TYPE_NONE)
36 return;
37
Ben Hutchings3e6c4532009-10-23 08:30:36 +000038 falcon_read(efx, &sdctl, FR_AB_XX_SD_CTL);
39 EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVD, FFE_AB_XX_SD_CTL_DRV_DEF);
40 EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVD, FFE_AB_XX_SD_CTL_DRV_DEF);
41 EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVC, FFE_AB_XX_SD_CTL_DRV_DEF);
42 EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVC, FFE_AB_XX_SD_CTL_DRV_DEF);
43 EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVB, FFE_AB_XX_SD_CTL_DRV_DEF);
44 EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVB, FFE_AB_XX_SD_CTL_DRV_DEF);
45 EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVA, FFE_AB_XX_SD_CTL_DRV_DEF);
46 EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVA, FFE_AB_XX_SD_CTL_DRV_DEF);
47 falcon_write(efx, &sdctl, FR_AB_XX_SD_CTL);
Ben Hutchings8ceee662008-04-27 12:55:59 +010048
Ben Hutchingsc1e5fcc2008-09-01 12:48:41 +010049 EFX_POPULATE_OWORD_8(txdrv,
Ben Hutchings3e6c4532009-10-23 08:30:36 +000050 FRF_AB_XX_DEQD, FFE_AB_XX_TXDRV_DEQ_DEF,
51 FRF_AB_XX_DEQC, FFE_AB_XX_TXDRV_DEQ_DEF,
52 FRF_AB_XX_DEQB, FFE_AB_XX_TXDRV_DEQ_DEF,
53 FRF_AB_XX_DEQA, FFE_AB_XX_TXDRV_DEQ_DEF,
54 FRF_AB_XX_DTXD, FFE_AB_XX_TXDRV_DTX_DEF,
55 FRF_AB_XX_DTXC, FFE_AB_XX_TXDRV_DTX_DEF,
56 FRF_AB_XX_DTXB, FFE_AB_XX_TXDRV_DTX_DEF,
57 FRF_AB_XX_DTXA, FFE_AB_XX_TXDRV_DTX_DEF);
58 falcon_write(efx, &txdrv, FR_AB_XX_TXDRV_CTL);
Ben Hutchings8ceee662008-04-27 12:55:59 +010059}
60
Ben Hutchingsef08af02008-09-01 12:49:20 +010061int falcon_reset_xaui(struct efx_nic *efx)
Ben Hutchings8ceee662008-04-27 12:55:59 +010062{
Ben Hutchingsc1e5fcc2008-09-01 12:48:41 +010063 efx_oword_t reg;
Ben Hutchings8ceee662008-04-27 12:55:59 +010064 int count;
65
Ben Hutchingsd4ec09a2009-08-26 08:16:46 +000066 /* Start reset sequence */
Ben Hutchings3e6c4532009-10-23 08:30:36 +000067 EFX_POPULATE_DWORD_1(reg, FRF_AB_XX_RST_XX_EN, 1);
68 falcon_write(efx, &reg, FR_AB_XX_PWR_RST);
Ben Hutchings8ceee662008-04-27 12:55:59 +010069
Ben Hutchingsd4ec09a2009-08-26 08:16:46 +000070 /* Wait up to 10 ms for completion, then reinitialise */
71 for (count = 0; count < 1000; count++) {
Ben Hutchings3e6c4532009-10-23 08:30:36 +000072 falcon_read(efx, &reg, FR_AB_XX_PWR_RST);
73 if (EFX_OWORD_FIELD(reg, FRF_AB_XX_RST_XX_EN) == 0 &&
74 EFX_OWORD_FIELD(reg, FRF_AB_XX_SD_RST_ACT) == 0) {
Ben Hutchings8ceee662008-04-27 12:55:59 +010075 falcon_setup_xaui(efx);
76 return 0;
77 }
78 udelay(10);
79 }
80 EFX_ERR(efx, "timed out waiting for XAUI/XGXS reset\n");
81 return -ETIMEDOUT;
82}
83
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +010084static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
Ben Hutchings8ceee662008-04-27 12:55:59 +010085{
Ben Hutchingsc1e5fcc2008-09-01 12:48:41 +010086 efx_oword_t reg;
Ben Hutchings8ceee662008-04-27 12:55:59 +010087
Ben Hutchings177dfcd2008-12-12 21:50:08 -080088 if ((falcon_rev(efx) != FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
89 return;
90
91 /* We expect xgmii faults if the wireside link is up */
92 if (!EFX_WORKAROUND_5147(efx) || !efx->link_up)
93 return;
94
95 /* We can only use this interrupt to signal the negative edge of
96 * xaui_align [we have to poll the positive edge]. */
97 if (!efx->mac_up)
Ben Hutchings8ceee662008-04-27 12:55:59 +010098 return;
99
100 /* Flush the ISR */
101 if (enable)
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000102 falcon_read(efx, &reg, FR_AB_XM_MGT_INT_MSK);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100103
Ben Hutchingsc1e5fcc2008-09-01 12:48:41 +0100104 EFX_POPULATE_OWORD_2(reg,
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000105 FRF_AB_XM_MSK_RMTFLT, !enable,
106 FRF_AB_XM_MSK_LCLFLT, !enable);
107 falcon_write(efx, &reg, FR_AB_XM_MGT_INT_MASK);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100108}
109
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800110/* Get status of XAUI link */
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +0100111bool falcon_xaui_link_ok(struct efx_nic *efx)
Ben Hutchings8ceee662008-04-27 12:55:59 +0100112{
Ben Hutchingsc1e5fcc2008-09-01 12:48:41 +0100113 efx_oword_t reg;
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +0100114 bool align_done, link_ok = false;
115 int sync_status;
Ben Hutchings8ceee662008-04-27 12:55:59 +0100116
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100117 if (LOOPBACK_INTERNAL(efx))
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +0100118 return true;
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100119
Ben Hutchings8ceee662008-04-27 12:55:59 +0100120 /* Read link status */
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000121 falcon_read(efx, &reg, FR_AB_XX_CORE_STAT);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100122
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000123 align_done = EFX_OWORD_FIELD(reg, FRF_AB_XX_ALIGN_DONE);
124 sync_status = EFX_OWORD_FIELD(reg, FRF_AB_XX_SYNC_STAT);
125 if (align_done && (sync_status == FFE_AB_XX_STAT_ALL_LANES))
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +0100126 link_ok = true;
Ben Hutchings8ceee662008-04-27 12:55:59 +0100127
128 /* Clear link status ready for next read */
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000129 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_COMMA_DET, FFE_AB_XX_STAT_ALL_LANES);
130 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_CHAR_ERR, FFE_AB_XX_STAT_ALL_LANES);
131 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_DISPERR, FFE_AB_XX_STAT_ALL_LANES);
132 falcon_write(efx, &reg, FR_AB_XX_CORE_STAT);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100133
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800134 /* If the link is up, then check the phy side of the xaui link */
135 if (efx->link_up && link_ok)
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +0100136 if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
Ben Hutchings68e7f452009-04-29 08:05:08 +0000137 link_ok = efx_mdio_phyxgxs_lane_sync(efx);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100138
139 return link_ok;
140}
141
142static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
143{
144 unsigned int max_frame_len;
Ben Hutchingsc1e5fcc2008-09-01 12:48:41 +0100145 efx_oword_t reg;
Ben Hutchings04cc8ca2008-12-12 21:50:46 -0800146 bool rx_fc = !!(efx->link_fc & EFX_FC_RX);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100147
148 /* Configure MAC - cut-thru mode is hard wired on */
149 EFX_POPULATE_DWORD_3(reg,
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000150 FRF_AB_XM_RX_JUMBO_MODE, 1,
151 FRF_AB_XM_TX_STAT_EN, 1,
152 FRF_AB_XM_RX_STAT_EN, 1);
153 falcon_write(efx, &reg, FR_AB_XM_GLB_CFG);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100154
155 /* Configure TX */
156 EFX_POPULATE_DWORD_6(reg,
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000157 FRF_AB_XM_TXEN, 1,
158 FRF_AB_XM_TX_PRMBL, 1,
159 FRF_AB_XM_AUTO_PAD, 1,
160 FRF_AB_XM_TXCRC, 1,
161 FRF_AB_XM_FCNTL, 1,
162 FRF_AB_XM_IPG, 0x3);
163 falcon_write(efx, &reg, FR_AB_XM_TX_CFG);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100164
165 /* Configure RX */
166 EFX_POPULATE_DWORD_5(reg,
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000167 FRF_AB_XM_RXEN, 1,
168 FRF_AB_XM_AUTO_DEPAD, 0,
169 FRF_AB_XM_ACPT_ALL_MCAST, 1,
170 FRF_AB_XM_ACPT_ALL_UCAST, efx->promiscuous,
171 FRF_AB_XM_PASS_CRC_ERR, 1);
172 falcon_write(efx, &reg, FR_AB_XM_RX_CFG);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100173
174 /* Set frame length */
175 max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000176 EFX_POPULATE_DWORD_1(reg, FRF_AB_XM_MAX_RX_FRM_SIZE, max_frame_len);
177 falcon_write(efx, &reg, FR_AB_XM_RX_PARAM);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100178 EFX_POPULATE_DWORD_2(reg,
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000179 FRF_AB_XM_MAX_TX_FRM_SIZE, max_frame_len,
180 FRF_AB_XM_TX_JUMBO_MODE, 1);
181 falcon_write(efx, &reg, FR_AB_XM_TX_PARAM);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100182
183 EFX_POPULATE_DWORD_2(reg,
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000184 FRF_AB_XM_PAUSE_TIME, 0xfffe, /* MAX PAUSE TIME */
185 FRF_AB_XM_DIS_FCNTL, !rx_fc);
186 falcon_write(efx, &reg, FR_AB_XM_FC);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100187
188 /* Set MAC address */
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000189 memcpy(&reg, &efx->net_dev->dev_addr[0], 4);
190 falcon_write(efx, &reg, FR_AB_XM_ADR_LO);
191 memcpy(&reg, &efx->net_dev->dev_addr[4], 2);
192 falcon_write(efx, &reg, FR_AB_XM_ADR_HI);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100193}
194
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100195static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
196{
Ben Hutchingsc1e5fcc2008-09-01 12:48:41 +0100197 efx_oword_t reg;
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +0100198 bool xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS);
199 bool xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI);
200 bool xgmii_loopback = (efx->loopback_mode == LOOPBACK_XGMII);
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100201
202 /* XGXS block is flaky and will need to be reset if moving
203 * into our out of XGMII, XGXS or XAUI loopbacks. */
204 if (EFX_WORKAROUND_5147(efx)) {
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +0100205 bool old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
206 bool reset_xgxs;
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100207
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000208 falcon_read(efx, &reg, FR_AB_XX_CORE_STAT);
209 old_xgxs_loopback = EFX_OWORD_FIELD(reg, FRF_AB_XX_XGXS_LB_EN);
210 old_xgmii_loopback =
211 EFX_OWORD_FIELD(reg, FRF_AB_XX_XGMII_LB_EN);
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100212
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000213 falcon_read(efx, &reg, FR_AB_XX_SD_CTL);
214 old_xaui_loopback = EFX_OWORD_FIELD(reg, FRF_AB_XX_LPBKA);
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100215
216 /* The PHY driver may have turned XAUI off */
217 reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) ||
218 (xaui_loopback != old_xaui_loopback) ||
219 (xgmii_loopback != old_xgmii_loopback));
Ben Hutchings8c8661e2008-09-01 12:49:02 +0100220
221 if (reset_xgxs)
222 falcon_reset_xaui(efx);
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100223 }
224
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000225 falcon_read(efx, &reg, FR_AB_XX_CORE_STAT);
226 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_FORCE_SIG,
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100227 (xgxs_loopback || xaui_loopback) ?
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000228 FFE_AB_XX_FORCE_SIG_ALL_LANES : 0);
229 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_XGXS_LB_EN, xgxs_loopback);
230 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_XGMII_LB_EN, xgmii_loopback);
231 falcon_write(efx, &reg, FR_AB_XX_CORE_STAT);
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100232
Ben Hutchings3e6c4532009-10-23 08:30:36 +0000233 falcon_read(efx, &reg, FR_AB_XX_SD_CTL);
234 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKD, xaui_loopback);
235 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKC, xaui_loopback);
236 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKB, xaui_loopback);
237 EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKA, xaui_loopback);
238 falcon_write(efx, &reg, FR_AB_XX_SD_CTL);
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100239}
240
241
Ben Hutchings8ceee662008-04-27 12:55:59 +0100242/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
243 * to come back up. Bash it until it comes back up */
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800244static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
Ben Hutchings8ceee662008-04-27 12:55:59 +0100245{
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800246 efx->mac_up = falcon_xaui_link_ok(efx);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100247
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100248 if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
Ben Hutchingsf8b87c12008-09-01 12:48:17 +0100249 efx_phy_mode_disabled(efx->phy_mode))
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800250 /* XAUI link is expected to be down */
251 return;
Ben Hutchings8ceee662008-04-27 12:55:59 +0100252
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800253 while (!efx->mac_up && tries) {
254 EFX_LOG(efx, "bashing xaui\n");
Ben Hutchings91ad7572008-05-16 21:14:27 +0100255 falcon_reset_xaui(efx);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100256 udelay(200);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100257
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800258 efx->mac_up = falcon_xaui_link_ok(efx);
259 --tries;
260 }
Ben Hutchings8ceee662008-04-27 12:55:59 +0100261}
262
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800263static void falcon_reconfigure_xmac(struct efx_nic *efx)
Ben Hutchings8ceee662008-04-27 12:55:59 +0100264{
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +0100265 falcon_mask_status_intr(efx, false);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100266
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100267 falcon_reconfigure_xgxs_core(efx);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100268 falcon_reconfigure_xmac_core(efx);
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100269
Ben Hutchings8ceee662008-04-27 12:55:59 +0100270 falcon_reconfigure_mac_wrapper(efx);
271
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800272 falcon_check_xaui_link_up(efx, 5);
273 falcon_mask_status_intr(efx, true);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100274}
275
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800276static void falcon_update_stats_xmac(struct efx_nic *efx)
Ben Hutchings8ceee662008-04-27 12:55:59 +0100277{
278 struct efx_mac_stats *mac_stats = &efx->mac_stats;
279 int rc;
280
281 rc = falcon_dma_stats(efx, XgDmaDone_offset);
282 if (rc)
283 return;
284
285 /* Update MAC stats from DMAed values */
286 FALCON_STAT(efx, XgRxOctets, rx_bytes);
287 FALCON_STAT(efx, XgRxOctetsOK, rx_good_bytes);
288 FALCON_STAT(efx, XgRxPkts, rx_packets);
289 FALCON_STAT(efx, XgRxPktsOK, rx_good);
290 FALCON_STAT(efx, XgRxBroadcastPkts, rx_broadcast);
291 FALCON_STAT(efx, XgRxMulticastPkts, rx_multicast);
292 FALCON_STAT(efx, XgRxUnicastPkts, rx_unicast);
293 FALCON_STAT(efx, XgRxUndersizePkts, rx_lt64);
294 FALCON_STAT(efx, XgRxOversizePkts, rx_gtjumbo);
295 FALCON_STAT(efx, XgRxJabberPkts, rx_bad_gtjumbo);
296 FALCON_STAT(efx, XgRxUndersizeFCSerrorPkts, rx_bad_lt64);
297 FALCON_STAT(efx, XgRxDropEvents, rx_overflow);
298 FALCON_STAT(efx, XgRxFCSerrorPkts, rx_bad);
299 FALCON_STAT(efx, XgRxAlignError, rx_align_error);
300 FALCON_STAT(efx, XgRxSymbolError, rx_symbol_error);
301 FALCON_STAT(efx, XgRxInternalMACError, rx_internal_error);
302 FALCON_STAT(efx, XgRxControlPkts, rx_control);
303 FALCON_STAT(efx, XgRxPausePkts, rx_pause);
304 FALCON_STAT(efx, XgRxPkts64Octets, rx_64);
305 FALCON_STAT(efx, XgRxPkts65to127Octets, rx_65_to_127);
306 FALCON_STAT(efx, XgRxPkts128to255Octets, rx_128_to_255);
307 FALCON_STAT(efx, XgRxPkts256to511Octets, rx_256_to_511);
308 FALCON_STAT(efx, XgRxPkts512to1023Octets, rx_512_to_1023);
309 FALCON_STAT(efx, XgRxPkts1024to15xxOctets, rx_1024_to_15xx);
310 FALCON_STAT(efx, XgRxPkts15xxtoMaxOctets, rx_15xx_to_jumbo);
311 FALCON_STAT(efx, XgRxLengthError, rx_length_error);
312 FALCON_STAT(efx, XgTxPkts, tx_packets);
313 FALCON_STAT(efx, XgTxOctets, tx_bytes);
314 FALCON_STAT(efx, XgTxMulticastPkts, tx_multicast);
315 FALCON_STAT(efx, XgTxBroadcastPkts, tx_broadcast);
316 FALCON_STAT(efx, XgTxUnicastPkts, tx_unicast);
317 FALCON_STAT(efx, XgTxControlPkts, tx_control);
318 FALCON_STAT(efx, XgTxPausePkts, tx_pause);
319 FALCON_STAT(efx, XgTxPkts64Octets, tx_64);
320 FALCON_STAT(efx, XgTxPkts65to127Octets, tx_65_to_127);
321 FALCON_STAT(efx, XgTxPkts128to255Octets, tx_128_to_255);
322 FALCON_STAT(efx, XgTxPkts256to511Octets, tx_256_to_511);
323 FALCON_STAT(efx, XgTxPkts512to1023Octets, tx_512_to_1023);
324 FALCON_STAT(efx, XgTxPkts1024to15xxOctets, tx_1024_to_15xx);
325 FALCON_STAT(efx, XgTxPkts1519toMaxOctets, tx_15xx_to_jumbo);
326 FALCON_STAT(efx, XgTxUndersizePkts, tx_lt64);
327 FALCON_STAT(efx, XgTxOversizePkts, tx_gtjumbo);
328 FALCON_STAT(efx, XgTxNonTcpUdpPkt, tx_non_tcpudp);
329 FALCON_STAT(efx, XgTxMacSrcErrPkt, tx_mac_src_error);
330 FALCON_STAT(efx, XgTxIpSrcErrPkt, tx_ip_src_error);
331
332 /* Update derived statistics */
333 mac_stats->tx_good_bytes =
Ben Hutchingsc2643612008-09-01 12:46:10 +0100334 (mac_stats->tx_bytes - mac_stats->tx_bad_bytes -
335 mac_stats->tx_control * 64);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100336 mac_stats->rx_bad_bytes =
Ben Hutchingsc2643612008-09-01 12:46:10 +0100337 (mac_stats->rx_bytes - mac_stats->rx_good_bytes -
338 mac_stats->rx_control * 64);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100339}
340
Ben Hutchings766ca0f2008-12-12 21:59:24 -0800341static void falcon_xmac_irq(struct efx_nic *efx)
Ben Hutchings8ceee662008-04-27 12:55:59 +0100342{
Ben Hutchings766ca0f2008-12-12 21:59:24 -0800343 /* The XGMII link has a transient fault, which indicates either:
344 * - there's a transient xgmii fault
345 * - falcon's end of the xaui link may need a kick
346 * - the wire-side link may have gone down, but the lasi/poll()
347 * hasn't noticed yet.
348 *
349 * We only want to even bother polling XAUI if we're confident it's
350 * not (1) or (3). In both cases, the only reliable way to spot this
351 * is to wait a bit. We do this here by forcing the mac link state
352 * to down, and waiting for the mac poll to come round and check
353 */
354 efx->mac_up = false;
355}
Ben Hutchings8ceee662008-04-27 12:55:59 +0100356
Ben Hutchings766ca0f2008-12-12 21:59:24 -0800357static void falcon_poll_xmac(struct efx_nic *efx)
358{
359 if (!EFX_WORKAROUND_5147(efx) || !efx->link_up || efx->mac_up)
360 return;
Ben Hutchings3273c2e2008-05-07 13:36:19 +0100361
Ben Hutchingsdc8cfa52008-09-01 12:46:50 +0100362 falcon_mask_status_intr(efx, false);
Ben Hutchings766ca0f2008-12-12 21:59:24 -0800363 falcon_check_xaui_link_up(efx, 1);
364 falcon_mask_status_intr(efx, true);
Ben Hutchings8ceee662008-04-27 12:55:59 +0100365}
366
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800367struct efx_mac_operations falcon_xmac_operations = {
368 .reconfigure = falcon_reconfigure_xmac,
369 .update_stats = falcon_update_stats_xmac,
Ben Hutchings766ca0f2008-12-12 21:59:24 -0800370 .irq = falcon_xmac_irq,
371 .poll = falcon_poll_xmac,
Ben Hutchings177dfcd2008-12-12 21:50:08 -0800372};