ia64/linux-2.6.18-xen.hg

view drivers/net/sfc/falcon_xmac.c @ 847:ad4d307bf9ce

net sfc: Update sfc and sfc_resource driver to latest release

...and update sfc_netfront, sfc_netback, sfc_netutil for any API changes

sfc_netback: Fix asymmetric use of SFC buffer table alloc and free
sfc_netback: Clean up if no SFC accel device found
sfc_netback: Gracefully handle case where page grant fails
sfc_netback: Disable net acceleration if the physical link goes down
sfc_netfront: Less verbose error messages, more verbose counters for
rx discard errors
sfc_netfront: Gracefully handle case where SFC netfront fails during
initialisation

Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 31 11:59:10 2009 +0100 (2009-03-31)
parents fc90e9b2c12b
children
line source
1 /****************************************************************************
2 * Driver for Solarflare network controllers
3 * (including support for SFE4001 10GBT NIC)
4 *
5 * Copyright 2005-2006: Fen Systems Ltd.
6 * Copyright 2006-2008: Solarflare Communications Inc,
7 * 9501 Jeronimo Road, Suite 250,
8 * Irvine, CA 92618, USA
9 *
10 * Initially developed by Michael Brown <mbrown@fensystems.co.uk>
11 * Maintained by Solarflare Communications <linux-net-drivers@solarflare.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License version 2 as published
15 * by the Free Software Foundation, incorporated herein by reference.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 ****************************************************************************
26 */
28 #include <linux/delay.h>
29 #include "net_driver.h"
30 #include "efx.h"
31 #include "falcon.h"
32 #include "falcon_hwdefs.h"
33 #include "falcon_io.h"
34 #include "mac.h"
35 #include "gmii.h"
36 #include "mdio_10g.h"
37 #include "phy.h"
38 #include "boards.h"
39 #include "workarounds.h"
41 /**************************************************************************
42 *
43 * MAC register access
44 *
45 **************************************************************************/
47 /* Offset of an XMAC register within Falcon */
48 #define FALCON_XMAC_REG(mac_reg) \
49 (FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE))
51 static void falcon_xmac_writel(struct efx_nic *efx,
52 efx_dword_t *value, unsigned int mac_reg)
53 {
54 efx_oword_t temp;
56 EFX_POPULATE_OWORD_1(temp, MAC_DATA, EFX_DWORD_FIELD(*value, MAC_DATA));
57 falcon_write(efx, &temp, FALCON_XMAC_REG(mac_reg));
58 }
60 static void falcon_xmac_readl(struct efx_nic *efx,
61 efx_dword_t *value, unsigned int mac_reg)
62 {
63 efx_oword_t temp;
65 falcon_read(efx, &temp, FALCON_XMAC_REG(mac_reg));
66 EFX_POPULATE_DWORD_1(*value, MAC_DATA, EFX_OWORD_FIELD(temp, MAC_DATA));
67 }
69 /**************************************************************************
70 *
71 * MAC operations
72 *
73 *************************************************************************/
74 static int falcon_reset_xmac(struct efx_nic *efx)
75 {
76 efx_dword_t reg;
77 int count;
79 EFX_POPULATE_DWORD_1(reg, XM_CORE_RST, 1);
80 efx->mac_op->mac_writel(efx, &reg, XM_GLB_CFG_REG_MAC);
82 for (count = 0; count < 10000; count++) { /* wait upto 100ms */
83 efx->mac_op->mac_readl(efx, &reg, XM_GLB_CFG_REG_MAC);
84 if (EFX_DWORD_FIELD(reg, XM_CORE_RST) == 0)
85 return 0;
86 udelay(10);
87 }
89 EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
90 return -ETIMEDOUT;
91 }
93 /* Configure the XAUI driver that is an output from Falcon */
94 static void falcon_setup_xaui(struct efx_nic *efx)
95 {
96 efx_dword_t sdctl, txdrv;
98 /* Move the XAUI into low power, unless there is no PHY, in
99 * which case the XAUI will have to drive a cable. */
100 if (efx->phy_type == PHY_TYPE_NONE)
101 return;
103 efx->mac_op->mac_readl(efx, &sdctl, XX_SD_CTL_REG_MAC);
104 EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT);
105 EFX_SET_DWORD_FIELD(sdctl, XX_LODRVD, XX_SD_CTL_DRV_DEFAULT);
106 EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT);
107 EFX_SET_DWORD_FIELD(sdctl, XX_LODRVC, XX_SD_CTL_DRV_DEFAULT);
108 EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT);
109 EFX_SET_DWORD_FIELD(sdctl, XX_LODRVB, XX_SD_CTL_DRV_DEFAULT);
110 EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT);
111 EFX_SET_DWORD_FIELD(sdctl, XX_LODRVA, XX_SD_CTL_DRV_DEFAULT);
112 efx->mac_op->mac_writel(efx, &sdctl, XX_SD_CTL_REG_MAC);
114 EFX_POPULATE_DWORD_8(txdrv,
115 XX_DEQD, XX_TXDRV_DEQ_DEFAULT,
116 XX_DEQC, XX_TXDRV_DEQ_DEFAULT,
117 XX_DEQB, XX_TXDRV_DEQ_DEFAULT,
118 XX_DEQA, XX_TXDRV_DEQ_DEFAULT,
119 XX_DTXD, XX_TXDRV_DTX_DEFAULT,
120 XX_DTXC, XX_TXDRV_DTX_DEFAULT,
121 XX_DTXB, XX_TXDRV_DTX_DEFAULT,
122 XX_DTXA, XX_TXDRV_DTX_DEFAULT);
123 efx->mac_op->mac_writel(efx, &txdrv, XX_TXDRV_CTL_REG_MAC);
124 }
126 static void falcon_hold_xaui_in_rst(struct efx_nic *efx)
127 {
128 efx_dword_t reg;
130 EFX_ZERO_DWORD(reg);
131 EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 1);
132 EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 1);
133 EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 1);
134 EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 1);
135 EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 1);
136 EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 1);
137 EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 1);
138 EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 1);
139 EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 1);
140 EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 1);
141 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
142 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
143 efx->mac_op->mac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
144 udelay(10);
145 }
147 static int _falcon_reset_xaui_a(struct efx_nic *efx)
148 {
149 efx_dword_t reg;
151 if (!efx->is_asic)
152 return 0;
154 falcon_hold_xaui_in_rst(efx);
155 efx->mac_op->mac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
157 /* Follow the RAMBUS XAUI data reset sequencing
158 * Channels A and B first: power down, reset PLL, reset, clear
159 */
160 EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 0);
161 EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 0);
162 efx->mac_op->mac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
163 udelay(10);
165 EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 0);
166 efx->mac_op->mac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
167 udelay(10);
169 EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 0);
170 EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 0);
171 efx->mac_op->mac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
172 udelay(10);
174 /* Channels C and D: power down, reset PLL, reset, clear */
175 EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 0);
176 EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 0);
177 efx->mac_op->mac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
178 udelay(10);
180 EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 0);
181 efx->mac_op->mac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
182 udelay(10);
184 EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 0);
185 EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 0);
186 efx->mac_op->mac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
187 udelay(10);
189 /* Setup XAUI */
190 falcon_setup_xaui(efx);
191 udelay(10);
193 /* Take XGXS out of reset */
194 EFX_ZERO_DWORD(reg);
195 efx->mac_op->mac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
196 udelay(10);
198 return 0;
199 }
201 static int _falcon_reset_xaui_b(struct efx_nic *efx)
202 {
203 efx_dword_t reg;
204 int count;
206 if (!efx->is_asic)
207 return 0;
209 EFX_POPULATE_DWORD_1(reg, XX_RST_XX_EN, 1);
210 efx->mac_op->mac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
212 /* Give some time for the link to establish */
213 for (count = 0; count < 1000; count++) { /* wait upto 10ms */
214 efx->mac_op->mac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
215 if (EFX_DWORD_FIELD(reg, XX_RST_XX_EN) == 0) {
216 falcon_setup_xaui(efx);
217 return 0;
218 }
219 udelay(10);
220 }
221 EFX_ERR(efx, "timed out waiting for XAUI/XGXS reset\n");
222 return -ETIMEDOUT;
223 }
225 int falcon_reset_xaui(struct efx_nic *efx)
226 {
227 int rc;
229 if (EFX_WORKAROUND_9388(efx)) {
230 falcon_hold_xaui_in_rst(efx);
231 efx->phy_op->reset_xaui(efx);
232 rc = _falcon_reset_xaui_a(efx);
233 } else {
234 rc = _falcon_reset_xaui_b(efx);
235 }
236 return rc;
237 }
239 static int falcon_xgmii_status(struct efx_nic *efx)
240 {
241 efx_dword_t reg;
243 if (FALCON_REV(efx) < FALCON_REV_B0)
244 return 1;
246 /* The ISR latches, so clear it and re-read */
247 efx->mac_op->mac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
248 efx->mac_op->mac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
250 if (EFX_DWORD_FIELD(reg, XM_LCLFLT) ||
251 EFX_DWORD_FIELD(reg, XM_RMTFLT)) {
252 EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
253 return 0;
254 }
256 return 1;
257 }
259 static void falcon_mask_status_intr(struct efx_nic *efx, int enable)
260 {
261 efx_dword_t reg;
263 if ((FALCON_REV(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
264 return;
266 /* Flush the ISR */
267 if (enable)
268 efx->mac_op->mac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
270 EFX_POPULATE_DWORD_2(reg,
271 XM_MSK_RMTFLT, !enable,
272 XM_MSK_LCLFLT, !enable);
273 efx->mac_op->mac_writel(efx, &reg, XM_MGT_INT_MSK_REG_MAC_B0);
274 }
276 static int falcon_init_xmac(struct efx_nic *efx)
277 {
278 int rc;
280 /* Initialize the PHY first so the clock is around */
281 rc = efx->phy_op->init(efx);
282 if (rc)
283 goto fail1;
285 rc = falcon_reset_xaui(efx);
286 if (rc)
287 goto fail2;
289 /* Wait again. Give the PHY and MAC time to faff */
290 schedule_timeout_uninterruptible(HZ / 10);
292 /* Reset the MAC */
293 rc = falcon_reset_xmac(efx);
294 if (rc)
295 goto fail2;
297 falcon_mask_status_intr(efx, 1);
298 return 0;
300 fail2:
301 efx->phy_op->fini(efx);
302 fail1:
303 return rc;
304 }
306 /* Get status of XAUI link */
307 int falcon_xaui_link_ok(struct efx_nic *efx)
308 {
309 efx_dword_t reg;
310 int align_done, sync_status, link_ok = 0;
312 /* If we're in internal loopback, then the link is up.
313 * The A1 FPGA/4G has RX and TX XAUI wired together, so the link is up.
314 * The B0 FPGA has XAUI offchip, so it is always up.
315 */
316 if (!efx->is_asic || LOOPBACK_INTERNAL(efx))
317 return 1;
319 /* Read link status */
320 efx->mac_op->mac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
322 align_done = EFX_DWORD_FIELD(reg, XX_ALIGN_DONE);
323 sync_status = EFX_DWORD_FIELD(reg, XX_SYNC_STAT);
324 if (align_done && (sync_status == XX_SYNC_STAT_DECODE_SYNCED))
325 link_ok = 1;
327 /* Clear link status ready for next read */
328 EFX_SET_DWORD_FIELD(reg, XX_COMMA_DET, XX_COMMA_DET_RESET);
329 EFX_SET_DWORD_FIELD(reg, XX_CHARERR, XX_CHARERR_RESET);
330 EFX_SET_DWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET);
331 efx->mac_op->mac_writel(efx, &reg, XX_CORE_STAT_REG_MAC);
333 /* If the link is up, then check the phy side of the xaui link
334 * (error conditions from the wire side propoagate back through
335 * the phy to the xaui side). */
336 if (efx->link_up && link_ok) {
337 int has_phyxs = efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS);
338 if (has_phyxs)
339 link_ok = mdio_clause45_phyxgxs_lane_sync(efx);
340 }
342 /* If the PHY and XAUI links are up, then check the mac's xgmii
343 * fault state */
344 if (efx->link_up && link_ok)
345 link_ok = falcon_xgmii_status(efx);
347 return link_ok;
348 }
350 static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
351 {
352 unsigned int max_frame_len;
353 efx_dword_t reg;
354 efx_oword_t mac_test_reg;
355 int rx_fc = (efx->flow_control & EFX_FC_RX) ? 1 : 0;
357 if (FALCON_REV(efx) <= FALCON_REV_A1 && !efx->is_asic) {
358 /* 10G FPGA's have the XAUI TX and RX wired together. Fake
359 * the link status and configure the link options before
360 * the MAC wrapper is configured */
361 efx->link_options = GM_LPA_10000FULL;
362 efx->link_up = 1;
363 }
365 /* Configure MAC - cut-thru mode is hard wired on */
366 EFX_POPULATE_DWORD_3(reg,
367 XM_RX_JUMBO_MODE, 1,
368 XM_TX_STAT_EN, 1,
369 XM_RX_STAT_EN, 1);
370 efx->mac_op->mac_writel(efx, &reg, XM_GLB_CFG_REG_MAC);
372 /* Configure TX */
373 EFX_POPULATE_DWORD_6(reg,
374 XM_TXEN, 1,
375 XM_TX_PRMBL, 1,
376 XM_AUTO_PAD, 1,
377 XM_TXCRC, 1,
378 XM_FCNTL, 1,
379 XM_IPG, 0x3);
380 efx->mac_op->mac_writel(efx, &reg, XM_TX_CFG_REG_MAC);
382 /* Configure RX */
383 EFX_POPULATE_DWORD_5(reg,
384 XM_RXEN, 1,
385 XM_AUTO_DEPAD, 0,
386 XM_ACPT_ALL_MCAST, 1,
387 XM_ACPT_ALL_UCAST, efx->promiscuous,
388 XM_PASS_CRC_ERR, 1);
389 efx->mac_op->mac_writel(efx, &reg, XM_RX_CFG_REG_MAC);
391 /* Set frame length */
392 max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
393 EFX_POPULATE_DWORD_1(reg, XM_MAX_RX_FRM_SIZE, max_frame_len);
394 efx->mac_op->mac_writel(efx, &reg, XM_RX_PARAM_REG_MAC);
395 EFX_POPULATE_DWORD_2(reg,
396 XM_MAX_TX_FRM_SIZE, max_frame_len,
397 XM_TX_JUMBO_MODE, 1);
398 efx->mac_op->mac_writel(efx, &reg, XM_TX_PARAM_REG_MAC);
400 EFX_POPULATE_DWORD_2(reg,
401 XM_PAUSE_TIME, 0xfffe, /* MAX PAUSE TIME */
402 XM_DIS_FCNTL, rx_fc ? 0 : 1);
403 efx->mac_op->mac_writel(efx, &reg, XM_FC_REG_MAC);
405 /* Set MAC address */
406 EFX_POPULATE_DWORD_4(reg,
407 XM_ADR_0, efx->net_dev->dev_addr[0],
408 XM_ADR_1, efx->net_dev->dev_addr[1],
409 XM_ADR_2, efx->net_dev->dev_addr[2],
410 XM_ADR_3, efx->net_dev->dev_addr[3]);
411 efx->mac_op->mac_writel(efx, &reg, XM_ADR_LO_REG_MAC);
412 EFX_POPULATE_DWORD_2(reg,
413 XM_ADR_4, efx->net_dev->dev_addr[4],
414 XM_ADR_5, efx->net_dev->dev_addr[5]);
415 efx->mac_op->mac_writel(efx, &reg, XM_ADR_HI_REG_MAC);
417 /* Handle B0 FPGA loopback where RAMBUS XGXS block not present */
418 if (FALCON_REV(efx) >= FALCON_REV_B0 && !efx->is_asic) {
419 int xgmii_loopback =
420 (efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0;
422 /* Set the MAC loopback bit. */
423 EFX_POPULATE_OWORD_1(mac_test_reg,
424 MAC_PTLOOP_EN, xgmii_loopback);
425 falcon_write(efx, &mac_test_reg, MAC_TEST_REG_KER);
426 }
427 }
429 static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
430 {
431 efx_dword_t reg;
432 int xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS) ? 1 : 0;
433 int xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI) ? 1 : 0;
434 int xgmii_loopback =
435 (efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0;
437 if (FALCON_REV(efx) >= FALCON_REV_B0 && !efx->is_asic)
438 /* RAMBUS XGXS block is not present */
439 return;
441 /* XGXS block is flaky and will need to be reset if moving
442 * into our out of XGMII, XGXS or XAUI loopbacks. */
443 if (EFX_WORKAROUND_5147(efx)) {
444 int old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
445 int reset_xgxs;
447 efx->mac_op->mac_readl(efx, &reg,
448 XX_CORE_STAT_REG_MAC);
449 old_xgxs_loopback = EFX_DWORD_FIELD(reg, XX_XGXS_LB_EN);
450 old_xgmii_loopback = EFX_DWORD_FIELD(reg, XX_XGMII_LB_EN);
452 efx->mac_op->mac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
453 old_xaui_loopback = EFX_DWORD_FIELD(reg, XX_LPBKA);
455 /* The PHY driver may have turned XAUI off */
456 reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) ||
457 (xaui_loopback != old_xaui_loopback) ||
458 (xgmii_loopback != old_xgmii_loopback));
459 if (reset_xgxs) {
460 efx->mac_op->mac_readl(efx, &reg,
461 XX_PWR_RST_REG_MAC);
462 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
463 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
464 efx->mac_op->mac_writel(efx, &reg,
465 XX_PWR_RST_REG_MAC);
466 udelay(1);
467 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 0);
468 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 0);
469 efx->mac_op->mac_writel(efx, &reg,
470 XX_PWR_RST_REG_MAC);
471 udelay(1);
472 }
473 }
475 efx->mac_op->mac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
476 EFX_SET_DWORD_FIELD(reg, XX_FORCE_SIG,
477 (xgxs_loopback || xaui_loopback) ?
478 XX_FORCE_SIG_DECODE_FORCED : 0);
479 EFX_SET_DWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback);
480 EFX_SET_DWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback);
481 efx->mac_op->mac_writel(efx, &reg, XX_CORE_STAT_REG_MAC);
483 efx->mac_op->mac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
484 EFX_SET_DWORD_FIELD(reg, XX_LPBKD, xaui_loopback);
485 EFX_SET_DWORD_FIELD(reg, XX_LPBKC, xaui_loopback);
486 EFX_SET_DWORD_FIELD(reg, XX_LPBKB, xaui_loopback);
487 EFX_SET_DWORD_FIELD(reg, XX_LPBKA, xaui_loopback);
488 efx->mac_op->mac_writel(efx, &reg, XX_SD_CTL_REG_MAC);
489 }
492 /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
493 * to come back up. Bash it until it comes back up */
494 static int falcon_check_xaui_link_up(struct efx_nic *efx)
495 {
496 int max_tries, tries;
497 tries = EFX_WORKAROUND_5147(efx) ? 5 : 1;
498 max_tries = tries;
500 if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
501 (efx->phy_type == PHY_TYPE_NONE) ||
502 !efx->phy_powered)
503 return 0;
505 while (tries) {
506 if (falcon_xaui_link_ok(efx))
507 return 1;
509 EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n",
510 __func__, tries);
511 (void) falcon_reset_xaui(efx);
512 udelay(200);
513 tries--;
514 }
516 EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n",
517 max_tries);
518 return 0;
519 }
521 static void falcon_reconfigure_xmac(struct efx_nic *efx)
522 {
523 int xaui_link_ok;
525 falcon_mask_status_intr(efx, 0);
527 /* Deconfigure the mac wrapper, draining the tx fifo if necessary */
528 falcon_deconfigure_mac_wrapper(efx);
530 /* Reconfigure the PHY, disabling transmit in mac level loopback. */
531 efx->tx_disabled = LOOPBACK_INTERNAL(efx);
532 efx->phy_op->reconfigure(efx);
534 falcon_reconfigure_xgxs_core(efx);
535 falcon_reconfigure_xmac_core(efx);
537 /* Reconfigure MAC wrapper */
538 falcon_reconfigure_mac_wrapper(efx);
540 /* Ensure XAUI link is up */
541 xaui_link_ok = falcon_check_xaui_link_up(efx);
543 if (xaui_link_ok && efx->link_up)
544 falcon_mask_status_intr(efx, 1);
545 }
547 static void falcon_fini_xmac(struct efx_nic *efx)
548 {
549 /* Isolate the MAC - PHY */
550 falcon_deconfigure_mac_wrapper(efx);
552 /* Potentially power down the PHY */
553 efx->phy_op->fini(efx);
554 }
556 static void falcon_update_stats_xmac(struct efx_nic *efx)
557 {
558 struct efx_mac_stats *mac_stats = &efx->mac_stats;
559 int rc;
561 rc = falcon_dma_stats(efx, XgDmaDone_offset);
562 if (rc)
563 return;
565 /* Update MAC stats from DMAed values */
566 FALCON_STAT(efx, XgRxOctets, rx_bytes);
567 FALCON_STAT(efx, XgRxOctetsOK, rx_good_bytes);
568 FALCON_STAT(efx, XgRxPkts, rx_packets);
569 FALCON_STAT(efx, XgRxPktsOK, rx_good);
570 FALCON_STAT(efx, XgRxBroadcastPkts, rx_broadcast);
571 FALCON_STAT(efx, XgRxMulticastPkts, rx_multicast);
572 FALCON_STAT(efx, XgRxUnicastPkts, rx_unicast);
573 FALCON_STAT(efx, XgRxUndersizePkts, rx_lt64);
574 FALCON_STAT(efx, XgRxOversizePkts, rx_gtjumbo);
575 FALCON_STAT(efx, XgRxJabberPkts, rx_bad_gtjumbo);
576 FALCON_STAT(efx, XgRxUndersizeFCSerrorPkts, rx_bad_lt64);
577 FALCON_STAT(efx, XgRxDropEvents, rx_overflow);
578 FALCON_STAT(efx, XgRxFCSerrorPkts, rx_bad);
579 FALCON_STAT(efx, XgRxAlignError, rx_align_error);
580 FALCON_STAT(efx, XgRxSymbolError, rx_symbol_error);
581 FALCON_STAT(efx, XgRxInternalMACError, rx_internal_error);
582 FALCON_STAT(efx, XgRxControlPkts, rx_control);
583 FALCON_STAT(efx, XgRxPausePkts, rx_pause);
584 FALCON_STAT(efx, XgRxPkts64Octets, rx_64);
585 FALCON_STAT(efx, XgRxPkts65to127Octets, rx_65_to_127);
586 FALCON_STAT(efx, XgRxPkts128to255Octets, rx_128_to_255);
587 FALCON_STAT(efx, XgRxPkts256to511Octets, rx_256_to_511);
588 FALCON_STAT(efx, XgRxPkts512to1023Octets, rx_512_to_1023);
589 FALCON_STAT(efx, XgRxPkts1024to15xxOctets, rx_1024_to_15xx);
590 FALCON_STAT(efx, XgRxPkts15xxtoMaxOctets, rx_15xx_to_jumbo);
591 FALCON_STAT(efx, XgRxLengthError, rx_length_error);
592 FALCON_STAT(efx, XgTxPkts, tx_packets);
593 FALCON_STAT(efx, XgTxOctets, tx_bytes);
594 FALCON_STAT(efx, XgTxMulticastPkts, tx_multicast);
595 FALCON_STAT(efx, XgTxBroadcastPkts, tx_broadcast);
596 FALCON_STAT(efx, XgTxUnicastPkts, tx_unicast);
597 FALCON_STAT(efx, XgTxControlPkts, tx_control);
598 FALCON_STAT(efx, XgTxPausePkts, tx_pause);
599 FALCON_STAT(efx, XgTxPkts64Octets, tx_64);
600 FALCON_STAT(efx, XgTxPkts65to127Octets, tx_65_to_127);
601 FALCON_STAT(efx, XgTxPkts128to255Octets, tx_128_to_255);
602 FALCON_STAT(efx, XgTxPkts256to511Octets, tx_256_to_511);
603 FALCON_STAT(efx, XgTxPkts512to1023Octets, tx_512_to_1023);
604 FALCON_STAT(efx, XgTxPkts1024to15xxOctets, tx_1024_to_15xx);
605 FALCON_STAT(efx, XgTxPkts1519toMaxOctets, tx_15xx_to_jumbo);
606 FALCON_STAT(efx, XgTxUndersizePkts, tx_lt64);
607 FALCON_STAT(efx, XgTxOversizePkts, tx_gtjumbo);
608 FALCON_STAT(efx, XgTxNonTcpUdpPkt, tx_non_tcpudp);
609 FALCON_STAT(efx, XgTxMacSrcErrPkt, tx_mac_src_error);
610 FALCON_STAT(efx, XgTxIpSrcErrPkt, tx_ip_src_error);
612 /* Update derived statistics */
613 mac_stats->tx_good_bytes =
614 (mac_stats->tx_bytes - mac_stats->tx_bad_bytes);
615 mac_stats->rx_bad_bytes =
616 (mac_stats->rx_bytes - mac_stats->rx_good_bytes);
617 }
619 #define EFX_XAUI_RETRAIN_MAX 8
621 static int falcon_check_xmac(struct efx_nic *efx)
622 {
623 unsigned xaui_link_ok;
624 int rc;
626 if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
627 (efx->phy_type == PHY_TYPE_NONE) ||
628 !efx->phy_powered)
629 return 0;
631 falcon_mask_status_intr(efx, 0);
632 xaui_link_ok = falcon_xaui_link_ok(efx);
634 if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok)
635 (void) falcon_reset_xaui(efx);
637 /* Call the PHY check_hw routine */
638 rc = efx->phy_op->check_hw(efx);
640 /* Unmask interrupt if everything was (and still is) ok */
641 if (xaui_link_ok && efx->link_up)
642 falcon_mask_status_intr(efx, 1);
644 return rc;
645 }
647 /* Simulate a PHY event */
648 static void falcon_xmac_sim_phy_event(struct efx_nic *efx)
649 {
650 efx_qword_t phy_event;
652 EFX_POPULATE_QWORD_2(phy_event,
653 EV_CODE, GLOBAL_EV_DECODE,
654 XG_PHY_INTR, 1);
655 falcon_generate_event(&efx->channel[0], &phy_event);
656 }
658 static int falcon_xmac_get_settings(struct efx_nic *efx,
659 struct ethtool_cmd *ecmd)
660 {
661 mdio_clause45_get_settings(efx, ecmd);
662 ecmd->transceiver = XCVR_INTERNAL;
663 ecmd->phy_address = efx->mii.phy_id;
664 ecmd->autoneg = AUTONEG_DISABLE;
665 ecmd->duplex = DUPLEX_FULL;
666 return 0;
667 }
669 static int falcon_xmac_set_settings(struct efx_nic *efx,
670 struct ethtool_cmd *ecmd)
671 {
672 if (ecmd->transceiver != XCVR_INTERNAL)
673 return -EINVAL;
674 if (ecmd->autoneg != AUTONEG_DISABLE)
675 return -EINVAL;
676 if (ecmd->duplex != DUPLEX_FULL)
677 return -EINVAL;
679 return mdio_clause45_set_settings(efx, ecmd);
680 }
683 static int falcon_xmac_set_pause(struct efx_nic *efx,
684 enum efx_fc_type flow_control)
685 {
686 int reset;
688 if (flow_control & EFX_FC_AUTO) {
689 EFX_LOG(efx, "10G does not support flow control "
690 "autonegotiation\n");
691 return -EINVAL;
692 }
694 if ((flow_control & EFX_FC_TX) && !(flow_control & EFX_FC_RX))
695 return -EINVAL;
697 /* TX flow control may automatically turn itself off if the
698 * link partner (intermittently) stops responding to pause
699 * frames. There isn't any indication that this has happened,
700 * so the best we do is leave it up to the user to spot this
701 * and fix it be cycling transmit flow control on this end. */
702 reset = ((flow_control & EFX_FC_TX) &&
703 !(efx->flow_control & EFX_FC_TX));
704 if (EFX_WORKAROUND_11482(efx) && reset) {
705 if (FALCON_REV(efx) >= FALCON_REV_B0) {
706 /* Recover by resetting the EM block */
707 if (efx->link_up)
708 falcon_drain_tx_fifo(efx);
709 } else {
710 /* Schedule a reset to recover */
711 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
712 }
713 }
715 efx->flow_control = flow_control;
717 return 0;
718 }
720 struct efx_mac_operations falcon_xmac_operations = {
721 .mac_writel = falcon_xmac_writel,
722 .mac_readl = falcon_xmac_readl,
723 .init = falcon_init_xmac,
724 .reconfigure = falcon_reconfigure_xmac,
725 .update_stats = falcon_update_stats_xmac,
726 .fini = falcon_fini_xmac,
727 .check_hw = falcon_check_xmac,
728 .fake_phy_event = falcon_xmac_sim_phy_event,
729 .get_settings = falcon_xmac_get_settings,
730 .set_settings = falcon_xmac_set_settings,
731 .set_pause = falcon_xmac_set_pause,
732 };