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.37-rc1 496 lines 14 kB view raw
1/**************************************************************************** 2 * Driver for Solarflare Solarstorm network controllers and boards 3 * Copyright 2007-2009 Solarflare Communications Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published 7 * by the Free Software Foundation, incorporated herein by reference. 8 */ 9 10#include <linux/delay.h> 11#include <linux/rtnetlink.h> 12#include <linux/seq_file.h> 13#include <linux/slab.h> 14#include "efx.h" 15#include "mdio_10g.h" 16#include "nic.h" 17#include "phy.h" 18#include "regs.h" 19#include "workarounds.h" 20#include "selftest.h" 21 22/* We expect these MMDs to be in the package. */ 23#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \ 24 MDIO_DEVS_PCS | \ 25 MDIO_DEVS_PHYXS | \ 26 MDIO_DEVS_AN) 27 28#define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ 29 (1 << LOOPBACK_PCS) | \ 30 (1 << LOOPBACK_PMAPMD) | \ 31 (1 << LOOPBACK_PHYXS_WS)) 32 33/* We complain if we fail to see the link partner as 10G capable this many 34 * times in a row (must be > 1 as sampling the autoneg. registers is racy) 35 */ 36#define MAX_BAD_LP_TRIES (5) 37 38/* Extended control register */ 39#define PMA_PMD_XCONTROL_REG 49152 40#define PMA_PMD_EXT_GMII_EN_LBN 1 41#define PMA_PMD_EXT_GMII_EN_WIDTH 1 42#define PMA_PMD_EXT_CLK_OUT_LBN 2 43#define PMA_PMD_EXT_CLK_OUT_WIDTH 1 44#define PMA_PMD_LNPGA_POWERDOWN_LBN 8 45#define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1 46#define PMA_PMD_EXT_CLK312_WIDTH 1 47#define PMA_PMD_EXT_LPOWER_LBN 12 48#define PMA_PMD_EXT_LPOWER_WIDTH 1 49#define PMA_PMD_EXT_ROBUST_LBN 14 50#define PMA_PMD_EXT_ROBUST_WIDTH 1 51#define PMA_PMD_EXT_SSR_LBN 15 52#define PMA_PMD_EXT_SSR_WIDTH 1 53 54/* extended status register */ 55#define PMA_PMD_XSTATUS_REG 49153 56#define PMA_PMD_XSTAT_MDIX_LBN 14 57#define PMA_PMD_XSTAT_FLP_LBN (12) 58 59/* LED control register */ 60#define PMA_PMD_LED_CTRL_REG 49159 61#define PMA_PMA_LED_ACTIVITY_LBN (3) 62 63/* LED function override register */ 64#define PMA_PMD_LED_OVERR_REG 49161 65/* Bit positions for different LEDs (there are more but not wired on SFE4001)*/ 66#define PMA_PMD_LED_LINK_LBN (0) 67#define PMA_PMD_LED_SPEED_LBN (2) 68#define PMA_PMD_LED_TX_LBN (4) 69#define PMA_PMD_LED_RX_LBN (6) 70/* Override settings */ 71#define PMA_PMD_LED_AUTO (0) /* H/W control */ 72#define PMA_PMD_LED_ON (1) 73#define PMA_PMD_LED_OFF (2) 74#define PMA_PMD_LED_FLASH (3) 75#define PMA_PMD_LED_MASK 3 76/* All LEDs under hardware control */ 77/* Green and Amber under hardware control, Red off */ 78#define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) 79 80#define PMA_PMD_SPEED_ENABLE_REG 49192 81#define PMA_PMD_100TX_ADV_LBN 1 82#define PMA_PMD_100TX_ADV_WIDTH 1 83#define PMA_PMD_1000T_ADV_LBN 2 84#define PMA_PMD_1000T_ADV_WIDTH 1 85#define PMA_PMD_10000T_ADV_LBN 3 86#define PMA_PMD_10000T_ADV_WIDTH 1 87#define PMA_PMD_SPEED_LBN 4 88#define PMA_PMD_SPEED_WIDTH 4 89 90/* Misc register defines */ 91#define PCS_CLOCK_CTRL_REG 55297 92#define PLL312_RST_N_LBN 2 93 94#define PCS_SOFT_RST2_REG 55302 95#define SERDES_RST_N_LBN 13 96#define XGXS_RST_N_LBN 12 97 98#define PCS_TEST_SELECT_REG 55303 /* PRM 10.5.8 */ 99#define CLK312_EN_LBN 3 100 101/* PHYXS registers */ 102#define PHYXS_XCONTROL_REG 49152 103#define PHYXS_RESET_LBN 15 104#define PHYXS_RESET_WIDTH 1 105 106#define PHYXS_TEST1 (49162) 107#define LOOPBACK_NEAR_LBN (8) 108#define LOOPBACK_NEAR_WIDTH (1) 109 110/* Boot status register */ 111#define PCS_BOOT_STATUS_REG 53248 112#define PCS_BOOT_FATAL_ERROR_LBN 0 113#define PCS_BOOT_PROGRESS_LBN 1 114#define PCS_BOOT_PROGRESS_WIDTH 2 115#define PCS_BOOT_PROGRESS_INIT 0 116#define PCS_BOOT_PROGRESS_WAIT_MDIO 1 117#define PCS_BOOT_PROGRESS_CHECKSUM 2 118#define PCS_BOOT_PROGRESS_JUMP 3 119#define PCS_BOOT_DOWNLOAD_WAIT_LBN 3 120#define PCS_BOOT_CODE_STARTED_LBN 4 121 122/* 100M/1G PHY registers */ 123#define GPHY_XCONTROL_REG 49152 124#define GPHY_ISOLATE_LBN 10 125#define GPHY_ISOLATE_WIDTH 1 126#define GPHY_DUPLEX_LBN 8 127#define GPHY_DUPLEX_WIDTH 1 128#define GPHY_LOOPBACK_NEAR_LBN 14 129#define GPHY_LOOPBACK_NEAR_WIDTH 1 130 131#define C22EXT_STATUS_REG 49153 132#define C22EXT_STATUS_LINK_LBN 2 133#define C22EXT_STATUS_LINK_WIDTH 1 134 135#define C22EXT_MSTSLV_CTRL 49161 136#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8 137#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9 138 139#define C22EXT_MSTSLV_STATUS 49162 140#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10 141#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11 142 143/* Time to wait between powering down the LNPGA and turning off the power 144 * rails */ 145#define LNPGA_PDOWN_WAIT (HZ / 5) 146 147struct tenxpress_phy_data { 148 enum efx_loopback_mode loopback_mode; 149 enum efx_phy_mode phy_mode; 150 int bad_lp_tries; 151}; 152 153static int tenxpress_init(struct efx_nic *efx) 154{ 155 /* Enable 312.5 MHz clock */ 156 efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG, 157 1 << CLK312_EN_LBN); 158 159 /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ 160 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG, 161 1 << PMA_PMA_LED_ACTIVITY_LBN, true); 162 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, 163 SFX7101_PMA_PMD_LED_DEFAULT); 164 165 return 0; 166} 167 168static int tenxpress_phy_probe(struct efx_nic *efx) 169{ 170 struct tenxpress_phy_data *phy_data; 171 172 /* Allocate phy private storage */ 173 phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); 174 if (!phy_data) 175 return -ENOMEM; 176 efx->phy_data = phy_data; 177 phy_data->phy_mode = efx->phy_mode; 178 179 efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; 180 efx->mdio.mode_support = MDIO_SUPPORTS_C45; 181 182 efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; 183 184 efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | 185 ADVERTISED_10000baseT_Full); 186 187 return 0; 188} 189 190static int tenxpress_phy_init(struct efx_nic *efx) 191{ 192 int rc; 193 194 falcon_board(efx)->type->init_phy(efx); 195 196 if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { 197 rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); 198 if (rc < 0) 199 return rc; 200 201 rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); 202 if (rc < 0) 203 return rc; 204 } 205 206 rc = tenxpress_init(efx); 207 if (rc < 0) 208 return rc; 209 210 /* Reinitialise flow control settings */ 211 efx_link_set_wanted_fc(efx, efx->wanted_fc); 212 efx_mdio_an_reconfigure(efx); 213 214 schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ 215 216 /* Let XGXS and SerDes out of reset */ 217 falcon_reset_xaui(efx); 218 219 return 0; 220} 221 222/* Perform a "special software reset" on the PHY. The caller is 223 * responsible for saving and restoring the PHY hardware registers 224 * properly, and masking/unmasking LASI */ 225static int tenxpress_special_reset(struct efx_nic *efx) 226{ 227 int rc, reg; 228 229 /* The XGMAC clock is driven from the SFX7101 312MHz clock, so 230 * a special software reset can glitch the XGMAC sufficiently for stats 231 * requests to fail. */ 232 falcon_stop_nic_stats(efx); 233 234 /* Initiate reset */ 235 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); 236 reg |= (1 << PMA_PMD_EXT_SSR_LBN); 237 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); 238 239 mdelay(200); 240 241 /* Wait for the blocks to come out of reset */ 242 rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); 243 if (rc < 0) 244 goto out; 245 246 /* Try and reconfigure the device */ 247 rc = tenxpress_init(efx); 248 if (rc < 0) 249 goto out; 250 251 /* Wait for the XGXS state machine to churn */ 252 mdelay(10); 253out: 254 falcon_start_nic_stats(efx); 255 return rc; 256} 257 258static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok) 259{ 260 struct tenxpress_phy_data *pd = efx->phy_data; 261 bool bad_lp; 262 int reg; 263 264 if (link_ok) { 265 bad_lp = false; 266 } else { 267 /* Check that AN has started but not completed. */ 268 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_STAT1); 269 if (!(reg & MDIO_AN_STAT1_LPABLE)) 270 return; /* LP status is unknown */ 271 bad_lp = !(reg & MDIO_AN_STAT1_COMPLETE); 272 if (bad_lp) 273 pd->bad_lp_tries++; 274 } 275 276 /* Nothing to do if all is well and was previously so. */ 277 if (!pd->bad_lp_tries) 278 return; 279 280 /* Use the RX (red) LED as an error indicator once we've seen AN 281 * failure several times in a row, and also log a message. */ 282 if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) { 283 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, 284 PMA_PMD_LED_OVERR_REG); 285 reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN); 286 if (!bad_lp) { 287 reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN; 288 } else { 289 reg |= PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN; 290 netif_err(efx, link, efx->net_dev, 291 "appears to be plugged into a port" 292 " that is not 10GBASE-T capable. The PHY" 293 " supports 10GBASE-T ONLY, so no link can" 294 " be established\n"); 295 } 296 efx_mdio_write(efx, MDIO_MMD_PMAPMD, 297 PMA_PMD_LED_OVERR_REG, reg); 298 pd->bad_lp_tries = bad_lp; 299 } 300} 301 302static bool sfx7101_link_ok(struct efx_nic *efx) 303{ 304 return efx_mdio_links_ok(efx, 305 MDIO_DEVS_PMAPMD | 306 MDIO_DEVS_PCS | 307 MDIO_DEVS_PHYXS); 308} 309 310static void tenxpress_ext_loopback(struct efx_nic *efx) 311{ 312 efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1, 313 1 << LOOPBACK_NEAR_LBN, 314 efx->loopback_mode == LOOPBACK_PHYXS); 315} 316 317static void tenxpress_low_power(struct efx_nic *efx) 318{ 319 efx_mdio_set_mmds_lpower( 320 efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER), 321 TENXPRESS_REQUIRED_DEVS); 322} 323 324static int tenxpress_phy_reconfigure(struct efx_nic *efx) 325{ 326 struct tenxpress_phy_data *phy_data = efx->phy_data; 327 bool phy_mode_change, loop_reset; 328 329 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { 330 phy_data->phy_mode = efx->phy_mode; 331 return 0; 332 } 333 334 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && 335 phy_data->phy_mode != PHY_MODE_NORMAL); 336 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, LOOPBACKS_EXTERNAL(efx)) || 337 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); 338 339 if (loop_reset || phy_mode_change) { 340 tenxpress_special_reset(efx); 341 falcon_reset_xaui(efx); 342 } 343 344 tenxpress_low_power(efx); 345 efx_mdio_transmit_disable(efx); 346 efx_mdio_phy_reconfigure(efx); 347 tenxpress_ext_loopback(efx); 348 efx_mdio_an_reconfigure(efx); 349 350 phy_data->loopback_mode = efx->loopback_mode; 351 phy_data->phy_mode = efx->phy_mode; 352 353 return 0; 354} 355 356static void 357tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd); 358 359/* Poll for link state changes */ 360static bool tenxpress_phy_poll(struct efx_nic *efx) 361{ 362 struct efx_link_state old_state = efx->link_state; 363 364 efx->link_state.up = sfx7101_link_ok(efx); 365 efx->link_state.speed = 10000; 366 efx->link_state.fd = true; 367 efx->link_state.fc = efx_mdio_get_pause(efx); 368 369 sfx7101_check_bad_lp(efx, efx->link_state.up); 370 371 return !efx_link_state_equal(&efx->link_state, &old_state); 372} 373 374static void sfx7101_phy_fini(struct efx_nic *efx) 375{ 376 int reg; 377 378 /* Power down the LNPGA */ 379 reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); 380 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); 381 382 /* Waiting here ensures that the board fini, which can turn 383 * off the power to the PHY, won't get run until the LNPGA 384 * powerdown has been given long enough to complete. */ 385 schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ 386} 387 388static void tenxpress_phy_remove(struct efx_nic *efx) 389{ 390 kfree(efx->phy_data); 391 efx->phy_data = NULL; 392} 393 394 395/* Override the RX, TX and link LEDs */ 396void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) 397{ 398 int reg; 399 400 switch (mode) { 401 case EFX_LED_OFF: 402 reg = (PMA_PMD_LED_OFF << PMA_PMD_LED_TX_LBN) | 403 (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) | 404 (PMA_PMD_LED_OFF << PMA_PMD_LED_LINK_LBN); 405 break; 406 case EFX_LED_ON: 407 reg = (PMA_PMD_LED_ON << PMA_PMD_LED_TX_LBN) | 408 (PMA_PMD_LED_ON << PMA_PMD_LED_RX_LBN) | 409 (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN); 410 break; 411 default: 412 reg = SFX7101_PMA_PMD_LED_DEFAULT; 413 break; 414 } 415 416 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg); 417} 418 419static const char *const sfx7101_test_names[] = { 420 "bist" 421}; 422 423static const char *sfx7101_test_name(struct efx_nic *efx, unsigned int index) 424{ 425 if (index < ARRAY_SIZE(sfx7101_test_names)) 426 return sfx7101_test_names[index]; 427 return NULL; 428} 429 430static int 431sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags) 432{ 433 int rc; 434 435 if (!(flags & ETH_TEST_FL_OFFLINE)) 436 return 0; 437 438 /* BIST is automatically run after a special software reset */ 439 rc = tenxpress_special_reset(efx); 440 results[0] = rc ? -1 : 1; 441 442 efx_mdio_an_reconfigure(efx); 443 444 return rc; 445} 446 447static void 448tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 449{ 450 u32 adv = 0, lpa = 0; 451 int reg; 452 453 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL); 454 if (reg & MDIO_AN_10GBT_CTRL_ADV10G) 455 adv |= ADVERTISED_10000baseT_Full; 456 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); 457 if (reg & MDIO_AN_10GBT_STAT_LP10G) 458 lpa |= ADVERTISED_10000baseT_Full; 459 460 mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); 461 462 /* In loopback, the PHY automatically brings up the correct interface, 463 * but doesn't advertise the correct speed. So override it */ 464 if (LOOPBACK_EXTERNAL(efx)) 465 ecmd->speed = SPEED_10000; 466} 467 468static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 469{ 470 if (!ecmd->autoneg) 471 return -EINVAL; 472 473 return efx_mdio_set_settings(efx, ecmd); 474} 475 476static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) 477{ 478 efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, 479 MDIO_AN_10GBT_CTRL_ADV10G, 480 advertising & ADVERTISED_10000baseT_Full); 481} 482 483struct efx_phy_operations falcon_sfx7101_phy_ops = { 484 .probe = tenxpress_phy_probe, 485 .init = tenxpress_phy_init, 486 .reconfigure = tenxpress_phy_reconfigure, 487 .poll = tenxpress_phy_poll, 488 .fini = sfx7101_phy_fini, 489 .remove = tenxpress_phy_remove, 490 .get_settings = tenxpress_get_settings, 491 .set_settings = tenxpress_set_settings, 492 .set_npage_adv = sfx7101_set_npage_adv, 493 .test_alive = efx_mdio_test_alive, 494 .test_name = sfx7101_test_name, 495 .run_tests = sfx7101_run_tests, 496};