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