Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.26-rc6 655 lines 19 kB view raw
1/**************************************************************************** 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" 15#include "falcon_hwdefs.h" 16#include "falcon_io.h" 17#include "mac.h" 18#include "gmii.h" 19#include "mdio_10g.h" 20#include "phy.h" 21#include "boards.h" 22#include "workarounds.h" 23 24/************************************************************************** 25 * 26 * MAC register access 27 * 28 **************************************************************************/ 29 30/* Offset of an XMAC register within Falcon */ 31#define FALCON_XMAC_REG(mac_reg) \ 32 (FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE)) 33 34void falcon_xmac_writel(struct efx_nic *efx, 35 efx_dword_t *value, unsigned int mac_reg) 36{ 37 efx_oword_t temp; 38 39 EFX_POPULATE_OWORD_1(temp, MAC_DATA, EFX_DWORD_FIELD(*value, MAC_DATA)); 40 falcon_write(efx, &temp, FALCON_XMAC_REG(mac_reg)); 41} 42 43void falcon_xmac_readl(struct efx_nic *efx, 44 efx_dword_t *value, unsigned int mac_reg) 45{ 46 efx_oword_t temp; 47 48 falcon_read(efx, &temp, FALCON_XMAC_REG(mac_reg)); 49 EFX_POPULATE_DWORD_1(*value, MAC_DATA, EFX_OWORD_FIELD(temp, MAC_DATA)); 50} 51 52/************************************************************************** 53 * 54 * MAC operations 55 * 56 *************************************************************************/ 57static int falcon_reset_xmac(struct efx_nic *efx) 58{ 59 efx_dword_t reg; 60 int count; 61 62 EFX_POPULATE_DWORD_1(reg, XM_CORE_RST, 1); 63 falcon_xmac_writel(efx, &reg, XM_GLB_CFG_REG_MAC); 64 65 for (count = 0; count < 10000; count++) { /* wait upto 100ms */ 66 falcon_xmac_readl(efx, &reg, XM_GLB_CFG_REG_MAC); 67 if (EFX_DWORD_FIELD(reg, XM_CORE_RST) == 0) 68 return 0; 69 udelay(10); 70 } 71 72 /* This often fails when DSP is disabled, ignore it */ 73 if (sfe4001_phy_flash_cfg != 0) 74 return 0; 75 76 EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); 77 return -ETIMEDOUT; 78} 79 80/* Configure the XAUI driver that is an output from Falcon */ 81static void falcon_setup_xaui(struct efx_nic *efx) 82{ 83 efx_dword_t sdctl, txdrv; 84 85 /* Move the XAUI into low power, unless there is no PHY, in 86 * which case the XAUI will have to drive a cable. */ 87 if (efx->phy_type == PHY_TYPE_NONE) 88 return; 89 90 falcon_xmac_readl(efx, &sdctl, XX_SD_CTL_REG_MAC); 91 EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT); 92 EFX_SET_DWORD_FIELD(sdctl, XX_LODRVD, XX_SD_CTL_DRV_DEFAULT); 93 EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT); 94 EFX_SET_DWORD_FIELD(sdctl, XX_LODRVC, XX_SD_CTL_DRV_DEFAULT); 95 EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT); 96 EFX_SET_DWORD_FIELD(sdctl, XX_LODRVB, XX_SD_CTL_DRV_DEFAULT); 97 EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT); 98 EFX_SET_DWORD_FIELD(sdctl, XX_LODRVA, XX_SD_CTL_DRV_DEFAULT); 99 falcon_xmac_writel(efx, &sdctl, XX_SD_CTL_REG_MAC); 100 101 EFX_POPULATE_DWORD_8(txdrv, 102 XX_DEQD, XX_TXDRV_DEQ_DEFAULT, 103 XX_DEQC, XX_TXDRV_DEQ_DEFAULT, 104 XX_DEQB, XX_TXDRV_DEQ_DEFAULT, 105 XX_DEQA, XX_TXDRV_DEQ_DEFAULT, 106 XX_DTXD, XX_TXDRV_DTX_DEFAULT, 107 XX_DTXC, XX_TXDRV_DTX_DEFAULT, 108 XX_DTXB, XX_TXDRV_DTX_DEFAULT, 109 XX_DTXA, XX_TXDRV_DTX_DEFAULT); 110 falcon_xmac_writel(efx, &txdrv, XX_TXDRV_CTL_REG_MAC); 111} 112 113static void falcon_hold_xaui_in_rst(struct efx_nic *efx) 114{ 115 efx_dword_t reg; 116 117 EFX_ZERO_DWORD(reg); 118 EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 1); 119 EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 1); 120 EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 1); 121 EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 1); 122 EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 1); 123 EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 1); 124 EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 1); 125 EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 1); 126 EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 1); 127 EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 1); 128 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1); 129 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1); 130 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 131 udelay(10); 132} 133 134static int _falcon_reset_xaui_a(struct efx_nic *efx) 135{ 136 efx_dword_t reg; 137 138 falcon_hold_xaui_in_rst(efx); 139 falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC); 140 141 /* Follow the RAMBUS XAUI data reset sequencing 142 * Channels A and B first: power down, reset PLL, reset, clear 143 */ 144 EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 0); 145 EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 0); 146 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 147 udelay(10); 148 149 EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 0); 150 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 151 udelay(10); 152 153 EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 0); 154 EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 0); 155 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 156 udelay(10); 157 158 /* Channels C and D: power down, reset PLL, reset, clear */ 159 EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 0); 160 EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 0); 161 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 162 udelay(10); 163 164 EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 0); 165 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 166 udelay(10); 167 168 EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 0); 169 EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 0); 170 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 171 udelay(10); 172 173 /* Setup XAUI */ 174 falcon_setup_xaui(efx); 175 udelay(10); 176 177 /* Take XGXS out of reset */ 178 EFX_ZERO_DWORD(reg); 179 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 180 udelay(10); 181 182 return 0; 183} 184 185static int _falcon_reset_xaui_b(struct efx_nic *efx) 186{ 187 efx_dword_t reg; 188 int count; 189 190 EFX_POPULATE_DWORD_1(reg, XX_RST_XX_EN, 1); 191 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 192 193 /* Give some time for the link to establish */ 194 for (count = 0; count < 1000; count++) { /* wait upto 10ms */ 195 falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC); 196 if (EFX_DWORD_FIELD(reg, XX_RST_XX_EN) == 0) { 197 falcon_setup_xaui(efx); 198 return 0; 199 } 200 udelay(10); 201 } 202 EFX_ERR(efx, "timed out waiting for XAUI/XGXS reset\n"); 203 return -ETIMEDOUT; 204} 205 206int falcon_reset_xaui(struct efx_nic *efx) 207{ 208 int rc; 209 210 if (EFX_WORKAROUND_9388(efx)) { 211 falcon_hold_xaui_in_rst(efx); 212 efx->phy_op->reset_xaui(efx); 213 rc = _falcon_reset_xaui_a(efx); 214 } else { 215 rc = _falcon_reset_xaui_b(efx); 216 } 217 return rc; 218} 219 220static int falcon_xgmii_status(struct efx_nic *efx) 221{ 222 efx_dword_t reg; 223 224 if (falcon_rev(efx) < FALCON_REV_B0) 225 return 1; 226 227 /* The ISR latches, so clear it and re-read */ 228 falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0); 229 falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0); 230 231 if (EFX_DWORD_FIELD(reg, XM_LCLFLT) || 232 EFX_DWORD_FIELD(reg, XM_RMTFLT)) { 233 EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg)); 234 return 0; 235 } 236 237 return 1; 238} 239 240static void falcon_mask_status_intr(struct efx_nic *efx, int enable) 241{ 242 efx_dword_t reg; 243 244 if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) 245 return; 246 247 /* Flush the ISR */ 248 if (enable) 249 falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0); 250 251 EFX_POPULATE_DWORD_2(reg, 252 XM_MSK_RMTFLT, !enable, 253 XM_MSK_LCLFLT, !enable); 254 falcon_xmac_writel(efx, &reg, XM_MGT_INT_MSK_REG_MAC_B0); 255} 256 257int falcon_init_xmac(struct efx_nic *efx) 258{ 259 int rc; 260 261 /* Initialize the PHY first so the clock is around */ 262 rc = efx->phy_op->init(efx); 263 if (rc) 264 goto fail1; 265 266 rc = falcon_reset_xaui(efx); 267 if (rc) 268 goto fail2; 269 270 /* Wait again. Give the PHY and MAC time to come back */ 271 schedule_timeout_uninterruptible(HZ / 10); 272 273 rc = falcon_reset_xmac(efx); 274 if (rc) 275 goto fail2; 276 277 falcon_mask_status_intr(efx, 1); 278 return 0; 279 280 fail2: 281 efx->phy_op->fini(efx); 282 fail1: 283 return rc; 284} 285 286int falcon_xaui_link_ok(struct efx_nic *efx) 287{ 288 efx_dword_t reg; 289 int align_done, sync_status, link_ok = 0; 290 291 if (LOOPBACK_INTERNAL(efx)) 292 return 1; 293 294 /* Read link status */ 295 falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC); 296 297 align_done = EFX_DWORD_FIELD(reg, XX_ALIGN_DONE); 298 sync_status = EFX_DWORD_FIELD(reg, XX_SYNC_STAT); 299 if (align_done && (sync_status == XX_SYNC_STAT_DECODE_SYNCED)) 300 link_ok = 1; 301 302 /* Clear link status ready for next read */ 303 EFX_SET_DWORD_FIELD(reg, XX_COMMA_DET, XX_COMMA_DET_RESET); 304 EFX_SET_DWORD_FIELD(reg, XX_CHARERR, XX_CHARERR_RESET); 305 EFX_SET_DWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET); 306 falcon_xmac_writel(efx, &reg, XX_CORE_STAT_REG_MAC); 307 308 /* If the link is up, then check the phy side of the xaui link 309 * (error conditions from the wire side propoagate back through 310 * the phy to the xaui side). */ 311 if (efx->link_up && link_ok) { 312 int has_phyxs = efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS); 313 if (has_phyxs) 314 link_ok = mdio_clause45_phyxgxs_lane_sync(efx); 315 } 316 317 /* If the PHY and XAUI links are up, then check the mac's xgmii 318 * fault state */ 319 if (efx->link_up && link_ok) 320 link_ok = falcon_xgmii_status(efx); 321 322 return link_ok; 323} 324 325static void falcon_reconfigure_xmac_core(struct efx_nic *efx) 326{ 327 unsigned int max_frame_len; 328 efx_dword_t reg; 329 int rx_fc = (efx->flow_control & EFX_FC_RX) ? 1 : 0; 330 331 /* Configure MAC - cut-thru mode is hard wired on */ 332 EFX_POPULATE_DWORD_3(reg, 333 XM_RX_JUMBO_MODE, 1, 334 XM_TX_STAT_EN, 1, 335 XM_RX_STAT_EN, 1); 336 falcon_xmac_writel(efx, &reg, XM_GLB_CFG_REG_MAC); 337 338 /* Configure TX */ 339 EFX_POPULATE_DWORD_6(reg, 340 XM_TXEN, 1, 341 XM_TX_PRMBL, 1, 342 XM_AUTO_PAD, 1, 343 XM_TXCRC, 1, 344 XM_FCNTL, 1, 345 XM_IPG, 0x3); 346 falcon_xmac_writel(efx, &reg, XM_TX_CFG_REG_MAC); 347 348 /* Configure RX */ 349 EFX_POPULATE_DWORD_5(reg, 350 XM_RXEN, 1, 351 XM_AUTO_DEPAD, 0, 352 XM_ACPT_ALL_MCAST, 1, 353 XM_ACPT_ALL_UCAST, efx->promiscuous, 354 XM_PASS_CRC_ERR, 1); 355 falcon_xmac_writel(efx, &reg, XM_RX_CFG_REG_MAC); 356 357 /* Set frame length */ 358 max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu); 359 EFX_POPULATE_DWORD_1(reg, XM_MAX_RX_FRM_SIZE, max_frame_len); 360 falcon_xmac_writel(efx, &reg, XM_RX_PARAM_REG_MAC); 361 EFX_POPULATE_DWORD_2(reg, 362 XM_MAX_TX_FRM_SIZE, max_frame_len, 363 XM_TX_JUMBO_MODE, 1); 364 falcon_xmac_writel(efx, &reg, XM_TX_PARAM_REG_MAC); 365 366 EFX_POPULATE_DWORD_2(reg, 367 XM_PAUSE_TIME, 0xfffe, /* MAX PAUSE TIME */ 368 XM_DIS_FCNTL, rx_fc ? 0 : 1); 369 falcon_xmac_writel(efx, &reg, XM_FC_REG_MAC); 370 371 /* Set MAC address */ 372 EFX_POPULATE_DWORD_4(reg, 373 XM_ADR_0, efx->net_dev->dev_addr[0], 374 XM_ADR_1, efx->net_dev->dev_addr[1], 375 XM_ADR_2, efx->net_dev->dev_addr[2], 376 XM_ADR_3, efx->net_dev->dev_addr[3]); 377 falcon_xmac_writel(efx, &reg, XM_ADR_LO_REG_MAC); 378 EFX_POPULATE_DWORD_2(reg, 379 XM_ADR_4, efx->net_dev->dev_addr[4], 380 XM_ADR_5, efx->net_dev->dev_addr[5]); 381 falcon_xmac_writel(efx, &reg, XM_ADR_HI_REG_MAC); 382} 383 384static void falcon_reconfigure_xgxs_core(struct efx_nic *efx) 385{ 386 efx_dword_t reg; 387 int xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS) ? 1 : 0; 388 int xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI) ? 1 : 0; 389 int xgmii_loopback = 390 (efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0; 391 392 /* XGXS block is flaky and will need to be reset if moving 393 * into our out of XGMII, XGXS or XAUI loopbacks. */ 394 if (EFX_WORKAROUND_5147(efx)) { 395 int old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback; 396 int reset_xgxs; 397 398 falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC); 399 old_xgxs_loopback = EFX_DWORD_FIELD(reg, XX_XGXS_LB_EN); 400 old_xgmii_loopback = EFX_DWORD_FIELD(reg, XX_XGMII_LB_EN); 401 402 falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC); 403 old_xaui_loopback = EFX_DWORD_FIELD(reg, XX_LPBKA); 404 405 /* The PHY driver may have turned XAUI off */ 406 reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) || 407 (xaui_loopback != old_xaui_loopback) || 408 (xgmii_loopback != old_xgmii_loopback)); 409 if (reset_xgxs) { 410 falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC); 411 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1); 412 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1); 413 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 414 udelay(1); 415 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 0); 416 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 0); 417 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 418 udelay(1); 419 } 420 } 421 422 falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC); 423 EFX_SET_DWORD_FIELD(reg, XX_FORCE_SIG, 424 (xgxs_loopback || xaui_loopback) ? 425 XX_FORCE_SIG_DECODE_FORCED : 0); 426 EFX_SET_DWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback); 427 EFX_SET_DWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback); 428 falcon_xmac_writel(efx, &reg, XX_CORE_STAT_REG_MAC); 429 430 falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC); 431 EFX_SET_DWORD_FIELD(reg, XX_LPBKD, xaui_loopback); 432 EFX_SET_DWORD_FIELD(reg, XX_LPBKC, xaui_loopback); 433 EFX_SET_DWORD_FIELD(reg, XX_LPBKB, xaui_loopback); 434 EFX_SET_DWORD_FIELD(reg, XX_LPBKA, xaui_loopback); 435 falcon_xmac_writel(efx, &reg, XX_SD_CTL_REG_MAC); 436} 437 438 439/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails 440 * to come back up. Bash it until it comes back up */ 441static int falcon_check_xaui_link_up(struct efx_nic *efx) 442{ 443 int max_tries, tries; 444 tries = EFX_WORKAROUND_5147(efx) ? 5 : 1; 445 max_tries = tries; 446 447 if ((efx->loopback_mode == LOOPBACK_NETWORK) || 448 (efx->phy_type == PHY_TYPE_NONE)) 449 return 0; 450 451 while (tries) { 452 if (falcon_xaui_link_ok(efx)) 453 return 1; 454 455 EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n", 456 __func__, tries); 457 falcon_reset_xaui(efx); 458 udelay(200); 459 tries--; 460 } 461 462 EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n", 463 max_tries); 464 return 0; 465} 466 467void falcon_reconfigure_xmac(struct efx_nic *efx) 468{ 469 int xaui_link_ok; 470 471 falcon_mask_status_intr(efx, 0); 472 473 falcon_deconfigure_mac_wrapper(efx); 474 475 efx->tx_disabled = LOOPBACK_INTERNAL(efx); 476 efx->phy_op->reconfigure(efx); 477 478 falcon_reconfigure_xgxs_core(efx); 479 falcon_reconfigure_xmac_core(efx); 480 481 falcon_reconfigure_mac_wrapper(efx); 482 483 /* Ensure XAUI link is up */ 484 xaui_link_ok = falcon_check_xaui_link_up(efx); 485 486 if (xaui_link_ok && efx->link_up) 487 falcon_mask_status_intr(efx, 1); 488} 489 490void falcon_fini_xmac(struct efx_nic *efx) 491{ 492 /* Isolate the MAC - PHY */ 493 falcon_deconfigure_mac_wrapper(efx); 494 495 /* Potentially power down the PHY */ 496 efx->phy_op->fini(efx); 497} 498 499void falcon_update_stats_xmac(struct efx_nic *efx) 500{ 501 struct efx_mac_stats *mac_stats = &efx->mac_stats; 502 int rc; 503 504 rc = falcon_dma_stats(efx, XgDmaDone_offset); 505 if (rc) 506 return; 507 508 /* Update MAC stats from DMAed values */ 509 FALCON_STAT(efx, XgRxOctets, rx_bytes); 510 FALCON_STAT(efx, XgRxOctetsOK, rx_good_bytes); 511 FALCON_STAT(efx, XgRxPkts, rx_packets); 512 FALCON_STAT(efx, XgRxPktsOK, rx_good); 513 FALCON_STAT(efx, XgRxBroadcastPkts, rx_broadcast); 514 FALCON_STAT(efx, XgRxMulticastPkts, rx_multicast); 515 FALCON_STAT(efx, XgRxUnicastPkts, rx_unicast); 516 FALCON_STAT(efx, XgRxUndersizePkts, rx_lt64); 517 FALCON_STAT(efx, XgRxOversizePkts, rx_gtjumbo); 518 FALCON_STAT(efx, XgRxJabberPkts, rx_bad_gtjumbo); 519 FALCON_STAT(efx, XgRxUndersizeFCSerrorPkts, rx_bad_lt64); 520 FALCON_STAT(efx, XgRxDropEvents, rx_overflow); 521 FALCON_STAT(efx, XgRxFCSerrorPkts, rx_bad); 522 FALCON_STAT(efx, XgRxAlignError, rx_align_error); 523 FALCON_STAT(efx, XgRxSymbolError, rx_symbol_error); 524 FALCON_STAT(efx, XgRxInternalMACError, rx_internal_error); 525 FALCON_STAT(efx, XgRxControlPkts, rx_control); 526 FALCON_STAT(efx, XgRxPausePkts, rx_pause); 527 FALCON_STAT(efx, XgRxPkts64Octets, rx_64); 528 FALCON_STAT(efx, XgRxPkts65to127Octets, rx_65_to_127); 529 FALCON_STAT(efx, XgRxPkts128to255Octets, rx_128_to_255); 530 FALCON_STAT(efx, XgRxPkts256to511Octets, rx_256_to_511); 531 FALCON_STAT(efx, XgRxPkts512to1023Octets, rx_512_to_1023); 532 FALCON_STAT(efx, XgRxPkts1024to15xxOctets, rx_1024_to_15xx); 533 FALCON_STAT(efx, XgRxPkts15xxtoMaxOctets, rx_15xx_to_jumbo); 534 FALCON_STAT(efx, XgRxLengthError, rx_length_error); 535 FALCON_STAT(efx, XgTxPkts, tx_packets); 536 FALCON_STAT(efx, XgTxOctets, tx_bytes); 537 FALCON_STAT(efx, XgTxMulticastPkts, tx_multicast); 538 FALCON_STAT(efx, XgTxBroadcastPkts, tx_broadcast); 539 FALCON_STAT(efx, XgTxUnicastPkts, tx_unicast); 540 FALCON_STAT(efx, XgTxControlPkts, tx_control); 541 FALCON_STAT(efx, XgTxPausePkts, tx_pause); 542 FALCON_STAT(efx, XgTxPkts64Octets, tx_64); 543 FALCON_STAT(efx, XgTxPkts65to127Octets, tx_65_to_127); 544 FALCON_STAT(efx, XgTxPkts128to255Octets, tx_128_to_255); 545 FALCON_STAT(efx, XgTxPkts256to511Octets, tx_256_to_511); 546 FALCON_STAT(efx, XgTxPkts512to1023Octets, tx_512_to_1023); 547 FALCON_STAT(efx, XgTxPkts1024to15xxOctets, tx_1024_to_15xx); 548 FALCON_STAT(efx, XgTxPkts1519toMaxOctets, tx_15xx_to_jumbo); 549 FALCON_STAT(efx, XgTxUndersizePkts, tx_lt64); 550 FALCON_STAT(efx, XgTxOversizePkts, tx_gtjumbo); 551 FALCON_STAT(efx, XgTxNonTcpUdpPkt, tx_non_tcpudp); 552 FALCON_STAT(efx, XgTxMacSrcErrPkt, tx_mac_src_error); 553 FALCON_STAT(efx, XgTxIpSrcErrPkt, tx_ip_src_error); 554 555 /* Update derived statistics */ 556 mac_stats->tx_good_bytes = 557 (mac_stats->tx_bytes - mac_stats->tx_bad_bytes); 558 mac_stats->rx_bad_bytes = 559 (mac_stats->rx_bytes - mac_stats->rx_good_bytes); 560} 561 562int falcon_check_xmac(struct efx_nic *efx) 563{ 564 unsigned xaui_link_ok; 565 int rc; 566 567 if ((efx->loopback_mode == LOOPBACK_NETWORK) || 568 (efx->phy_type == PHY_TYPE_NONE)) 569 return 0; 570 571 falcon_mask_status_intr(efx, 0); 572 xaui_link_ok = falcon_xaui_link_ok(efx); 573 574 if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok) 575 falcon_reset_xaui(efx); 576 577 /* Call the PHY check_hw routine */ 578 rc = efx->phy_op->check_hw(efx); 579 580 /* Unmask interrupt if everything was (and still is) ok */ 581 if (xaui_link_ok && efx->link_up) 582 falcon_mask_status_intr(efx, 1); 583 584 return rc; 585} 586 587/* Simulate a PHY event */ 588void falcon_xmac_sim_phy_event(struct efx_nic *efx) 589{ 590 efx_qword_t phy_event; 591 592 EFX_POPULATE_QWORD_2(phy_event, 593 EV_CODE, GLOBAL_EV_DECODE, 594 XG_PHY_INTR, 1); 595 falcon_generate_event(&efx->channel[0], &phy_event); 596} 597 598int falcon_xmac_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 599{ 600 mdio_clause45_get_settings(efx, ecmd); 601 ecmd->transceiver = XCVR_INTERNAL; 602 ecmd->phy_address = efx->mii.phy_id; 603 ecmd->autoneg = AUTONEG_DISABLE; 604 ecmd->duplex = DUPLEX_FULL; 605 return 0; 606} 607 608int falcon_xmac_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 609{ 610 if (ecmd->transceiver != XCVR_INTERNAL) 611 return -EINVAL; 612 if (ecmd->autoneg != AUTONEG_DISABLE) 613 return -EINVAL; 614 if (ecmd->duplex != DUPLEX_FULL) 615 return -EINVAL; 616 617 return mdio_clause45_set_settings(efx, ecmd); 618} 619 620 621int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control) 622{ 623 int reset; 624 625 if (flow_control & EFX_FC_AUTO) { 626 EFX_LOG(efx, "10G does not support flow control " 627 "autonegotiation\n"); 628 return -EINVAL; 629 } 630 631 if ((flow_control & EFX_FC_TX) && !(flow_control & EFX_FC_RX)) 632 return -EINVAL; 633 634 /* TX flow control may automatically turn itself off if the 635 * link partner (intermittently) stops responding to pause 636 * frames. There isn't any indication that this has happened, 637 * so the best we do is leave it up to the user to spot this 638 * and fix it be cycling transmit flow control on this end. */ 639 reset = ((flow_control & EFX_FC_TX) && 640 !(efx->flow_control & EFX_FC_TX)); 641 if (EFX_WORKAROUND_11482(efx) && reset) { 642 if (falcon_rev(efx) >= FALCON_REV_B0) { 643 /* Recover by resetting the EM block */ 644 if (efx->link_up) 645 falcon_drain_tx_fifo(efx); 646 } else { 647 /* Schedule a reset to recover */ 648 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); 649 } 650 } 651 652 efx->flow_control = flow_control; 653 654 return 0; 655}