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