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.30-rc7 438 lines 12 kB view raw
1/**************************************************************************** 2 * Driver for Solarflare Solarstorm network controllers and boards 3 * Copyright 2007-2008 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/***************************************************************************** 11 * Support for the SFE4001 and SFN4111T NICs. 12 * 13 * The SFE4001 does not power-up fully at reset due to its high power 14 * consumption. We control its power via a PCA9539 I/O expander. 15 * Both boards have a MAX6647 temperature monitor which we expose to 16 * the lm90 driver. 17 * 18 * This also provides minimal support for reflashing the PHY, which is 19 * initiated by resetting it with the FLASH_CFG_1 pin pulled down. 20 * On SFE4001 rev A2 and later this is connected to the 3V3X output of 21 * the IO-expander; on the SFN4111T it is connected to Falcon's GPIO3. 22 * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually 23 * exclusive with the network device being open. 24 */ 25 26#include <linux/delay.h> 27#include <linux/rtnetlink.h> 28#include "net_driver.h" 29#include "efx.h" 30#include "phy.h" 31#include "boards.h" 32#include "falcon.h" 33#include "falcon_hwdefs.h" 34#include "falcon_io.h" 35#include "mac.h" 36#include "workarounds.h" 37 38/************************************************************************** 39 * 40 * I2C IO Expander device 41 * 42 **************************************************************************/ 43#define PCA9539 0x74 44 45#define P0_IN 0x00 46#define P0_OUT 0x02 47#define P0_INVERT 0x04 48#define P0_CONFIG 0x06 49 50#define P0_EN_1V0X_LBN 0 51#define P0_EN_1V0X_WIDTH 1 52#define P0_EN_1V2_LBN 1 53#define P0_EN_1V2_WIDTH 1 54#define P0_EN_2V5_LBN 2 55#define P0_EN_2V5_WIDTH 1 56#define P0_EN_3V3X_LBN 3 57#define P0_EN_3V3X_WIDTH 1 58#define P0_EN_5V_LBN 4 59#define P0_EN_5V_WIDTH 1 60#define P0_SHORTEN_JTAG_LBN 5 61#define P0_SHORTEN_JTAG_WIDTH 1 62#define P0_X_TRST_LBN 6 63#define P0_X_TRST_WIDTH 1 64#define P0_DSP_RESET_LBN 7 65#define P0_DSP_RESET_WIDTH 1 66 67#define P1_IN 0x01 68#define P1_OUT 0x03 69#define P1_INVERT 0x05 70#define P1_CONFIG 0x07 71 72#define P1_AFE_PWD_LBN 0 73#define P1_AFE_PWD_WIDTH 1 74#define P1_DSP_PWD25_LBN 1 75#define P1_DSP_PWD25_WIDTH 1 76#define P1_RESERVED_LBN 2 77#define P1_RESERVED_WIDTH 2 78#define P1_SPARE_LBN 4 79#define P1_SPARE_WIDTH 4 80 81/* Temperature Sensor */ 82#define MAX664X_REG_RSL 0x02 83#define MAX664X_REG_WLHO 0x0B 84 85static void sfe4001_poweroff(struct efx_nic *efx) 86{ 87 struct i2c_client *ioexp_client = efx->board_info.ioexp_client; 88 struct i2c_client *hwmon_client = efx->board_info.hwmon_client; 89 90 /* Turn off all power rails and disable outputs */ 91 i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff); 92 i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff); 93 i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff); 94 95 /* Clear any over-temperature alert */ 96 i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL); 97} 98 99static int sfe4001_poweron(struct efx_nic *efx) 100{ 101 struct i2c_client *hwmon_client = efx->board_info.hwmon_client; 102 struct i2c_client *ioexp_client = efx->board_info.ioexp_client; 103 unsigned int i, j; 104 int rc; 105 u8 out; 106 107 /* Clear any previous over-temperature alert */ 108 rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL); 109 if (rc < 0) 110 return rc; 111 112 /* Enable port 0 and port 1 outputs on IO expander */ 113 rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00); 114 if (rc) 115 return rc; 116 rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 117 0xff & ~(1 << P1_SPARE_LBN)); 118 if (rc) 119 goto fail_on; 120 121 /* If PHY power is on, turn it all off and wait 1 second to 122 * ensure a full reset. 123 */ 124 rc = i2c_smbus_read_byte_data(ioexp_client, P0_OUT); 125 if (rc < 0) 126 goto fail_on; 127 out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) | 128 (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) | 129 (0 << P0_EN_1V0X_LBN)); 130 if (rc != out) { 131 EFX_INFO(efx, "power-cycling PHY\n"); 132 rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); 133 if (rc) 134 goto fail_on; 135 schedule_timeout_uninterruptible(HZ); 136 } 137 138 for (i = 0; i < 20; ++i) { 139 /* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */ 140 out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) | 141 (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) | 142 (1 << P0_X_TRST_LBN)); 143 if (efx->phy_mode & PHY_MODE_SPECIAL) 144 out |= 1 << P0_EN_3V3X_LBN; 145 146 rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); 147 if (rc) 148 goto fail_on; 149 msleep(10); 150 151 /* Turn on 1V power rail */ 152 out &= ~(1 << P0_EN_1V0X_LBN); 153 rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); 154 if (rc) 155 goto fail_on; 156 157 EFX_INFO(efx, "waiting for DSP boot (attempt %d)...\n", i); 158 159 /* In flash config mode, DSP does not turn on AFE, so 160 * just wait 1 second. 161 */ 162 if (efx->phy_mode & PHY_MODE_SPECIAL) { 163 schedule_timeout_uninterruptible(HZ); 164 return 0; 165 } 166 167 for (j = 0; j < 10; ++j) { 168 msleep(100); 169 170 /* Check DSP has asserted AFE power line */ 171 rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN); 172 if (rc < 0) 173 goto fail_on; 174 if (rc & (1 << P1_AFE_PWD_LBN)) 175 return 0; 176 } 177 } 178 179 EFX_INFO(efx, "timed out waiting for DSP boot\n"); 180 rc = -ETIMEDOUT; 181fail_on: 182 sfe4001_poweroff(efx); 183 return rc; 184} 185 186static int sfn4111t_reset(struct efx_nic *efx) 187{ 188 efx_oword_t reg; 189 190 /* GPIO 3 and the GPIO register are shared with I2C, so block that */ 191 mutex_lock(&efx->i2c_adap.bus_lock); 192 193 /* Pull RST_N (GPIO 2) low then let it up again, setting the 194 * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the 195 * output enables; the output levels should always be 0 (low) 196 * and we rely on external pull-ups. */ 197 falcon_read(efx, &reg, GPIO_CTL_REG_KER); 198 EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true); 199 falcon_write(efx, &reg, GPIO_CTL_REG_KER); 200 msleep(1000); 201 EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false); 202 EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, 203 !!(efx->phy_mode & PHY_MODE_SPECIAL)); 204 falcon_write(efx, &reg, GPIO_CTL_REG_KER); 205 msleep(1); 206 207 mutex_unlock(&efx->i2c_adap.bus_lock); 208 209 ssleep(1); 210 return 0; 211} 212 213static ssize_t show_phy_flash_cfg(struct device *dev, 214 struct device_attribute *attr, char *buf) 215{ 216 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); 217 return sprintf(buf, "%d\n", !!(efx->phy_mode & PHY_MODE_SPECIAL)); 218} 219 220static ssize_t set_phy_flash_cfg(struct device *dev, 221 struct device_attribute *attr, 222 const char *buf, size_t count) 223{ 224 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); 225 enum efx_phy_mode old_mode, new_mode; 226 int err; 227 228 rtnl_lock(); 229 old_mode = efx->phy_mode; 230 if (count == 0 || *buf == '0') 231 new_mode = old_mode & ~PHY_MODE_SPECIAL; 232 else 233 new_mode = PHY_MODE_SPECIAL; 234 if (old_mode == new_mode) { 235 err = 0; 236 } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { 237 err = -EBUSY; 238 } else { 239 /* Reset the PHY, reconfigure the MAC and enable/disable 240 * MAC stats accordingly. */ 241 efx->phy_mode = new_mode; 242 if (new_mode & PHY_MODE_SPECIAL) 243 efx_stats_disable(efx); 244 if (efx->board_info.type == EFX_BOARD_SFE4001) 245 err = sfe4001_poweron(efx); 246 else 247 err = sfn4111t_reset(efx); 248 efx_reconfigure_port(efx); 249 if (!(new_mode & PHY_MODE_SPECIAL)) 250 efx_stats_enable(efx); 251 } 252 rtnl_unlock(); 253 254 return err ? err : count; 255} 256 257static DEVICE_ATTR(phy_flash_cfg, 0644, show_phy_flash_cfg, set_phy_flash_cfg); 258 259static void sfe4001_fini(struct efx_nic *efx) 260{ 261 EFX_INFO(efx, "%s\n", __func__); 262 263 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); 264 sfe4001_poweroff(efx); 265 i2c_unregister_device(efx->board_info.ioexp_client); 266 i2c_unregister_device(efx->board_info.hwmon_client); 267} 268 269static int sfe4001_check_hw(struct efx_nic *efx) 270{ 271 s32 status; 272 273 /* If XAUI link is up then do not monitor */ 274 if (EFX_WORKAROUND_7884(efx) && efx->mac_up) 275 return 0; 276 277 /* Check the powered status of the PHY. Lack of power implies that 278 * the MAX6647 has shut down power to it, probably due to a temp. 279 * alarm. Reading the power status rather than the MAX6647 status 280 * directly because the later is read-to-clear and would thus 281 * start to power up the PHY again when polled, causing us to blip 282 * the power undesirably. 283 * We know we can read from the IO expander because we did 284 * it during power-on. Assume failure now is bad news. */ 285 status = i2c_smbus_read_byte_data(efx->board_info.ioexp_client, P1_IN); 286 if (status >= 0 && 287 (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0) 288 return 0; 289 290 /* Use board power control, not PHY power control */ 291 sfe4001_poweroff(efx); 292 efx->phy_mode = PHY_MODE_OFF; 293 294 return (status < 0) ? -EIO : -ERANGE; 295} 296 297static struct i2c_board_info sfe4001_hwmon_info = { 298 I2C_BOARD_INFO("max6647", 0x4e), 299 .irq = -1, 300}; 301 302/* This board uses an I2C expander to provider power to the PHY, which needs to 303 * be turned on before the PHY can be used. 304 * Context: Process context, rtnl lock held 305 */ 306int sfe4001_init(struct efx_nic *efx) 307{ 308 int rc; 309 310#if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE) 311 efx->board_info.hwmon_client = 312 i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info); 313#else 314 efx->board_info.hwmon_client = 315 i2c_new_dummy(&efx->i2c_adap, sfe4001_hwmon_info.addr); 316#endif 317 if (!efx->board_info.hwmon_client) 318 return -EIO; 319 320 /* Raise board/PHY high limit from 85 to 90 degrees Celsius */ 321 rc = i2c_smbus_write_byte_data(efx->board_info.hwmon_client, 322 MAX664X_REG_WLHO, 90); 323 if (rc) 324 goto fail_hwmon; 325 326 efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539); 327 if (!efx->board_info.ioexp_client) { 328 rc = -EIO; 329 goto fail_hwmon; 330 } 331 332 /* 10Xpress has fixed-function LED pins, so there is no board-specific 333 * blink code. */ 334 efx->board_info.blink = tenxpress_phy_blink; 335 336 efx->board_info.monitor = sfe4001_check_hw; 337 efx->board_info.fini = sfe4001_fini; 338 339 if (efx->phy_mode & PHY_MODE_SPECIAL) { 340 /* PHY won't generate a 156.25 MHz clock and MAC stats fetch 341 * will fail. */ 342 efx_stats_disable(efx); 343 } 344 rc = sfe4001_poweron(efx); 345 if (rc) 346 goto fail_ioexp; 347 348 rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); 349 if (rc) 350 goto fail_on; 351 352 EFX_INFO(efx, "PHY is powered on\n"); 353 return 0; 354 355fail_on: 356 sfe4001_poweroff(efx); 357fail_ioexp: 358 i2c_unregister_device(efx->board_info.ioexp_client); 359fail_hwmon: 360 i2c_unregister_device(efx->board_info.hwmon_client); 361 return rc; 362} 363 364static int sfn4111t_check_hw(struct efx_nic *efx) 365{ 366 s32 status; 367 368 /* If XAUI link is up then do not monitor */ 369 if (EFX_WORKAROUND_7884(efx) && efx->mac_up) 370 return 0; 371 372 /* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */ 373 status = i2c_smbus_read_byte_data(efx->board_info.hwmon_client, 374 MAX664X_REG_RSL); 375 if (status < 0) 376 return -EIO; 377 if (status & 0x57) 378 return -ERANGE; 379 return 0; 380} 381 382static void sfn4111t_fini(struct efx_nic *efx) 383{ 384 EFX_INFO(efx, "%s\n", __func__); 385 386 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); 387 i2c_unregister_device(efx->board_info.hwmon_client); 388} 389 390static struct i2c_board_info sfn4111t_a0_hwmon_info = { 391 I2C_BOARD_INFO("max6647", 0x4e), 392 .irq = -1, 393}; 394 395static struct i2c_board_info sfn4111t_r5_hwmon_info = { 396 I2C_BOARD_INFO("max6646", 0x4d), 397 .irq = -1, 398}; 399 400int sfn4111t_init(struct efx_nic *efx) 401{ 402 int i = 0; 403 int rc; 404 405 efx->board_info.hwmon_client = 406 i2c_new_device(&efx->i2c_adap, 407 (efx->board_info.minor < 5) ? 408 &sfn4111t_a0_hwmon_info : 409 &sfn4111t_r5_hwmon_info); 410 if (!efx->board_info.hwmon_client) 411 return -EIO; 412 413 efx->board_info.blink = tenxpress_phy_blink; 414 efx->board_info.monitor = sfn4111t_check_hw; 415 efx->board_info.fini = sfn4111t_fini; 416 417 rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); 418 if (rc) 419 goto fail_hwmon; 420 421 do { 422 if (efx->phy_mode & PHY_MODE_SPECIAL) { 423 /* PHY may not generate a 156.25 MHz clock and MAC 424 * stats fetch will fail. */ 425 efx_stats_disable(efx); 426 sfn4111t_reset(efx); 427 } 428 rc = sft9001_wait_boot(efx); 429 if (rc == 0) 430 return 0; 431 efx->phy_mode = PHY_MODE_SPECIAL; 432 } while (rc == -EINVAL && ++i < 2); 433 434 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); 435fail_hwmon: 436 i2c_unregister_device(efx->board_info.hwmon_client); 437 return rc; 438}