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.32-rc4 435 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}; 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}; 392 393static struct i2c_board_info sfn4111t_r5_hwmon_info = { 394 I2C_BOARD_INFO("max6646", 0x4d), 395}; 396 397int sfn4111t_init(struct efx_nic *efx) 398{ 399 int i = 0; 400 int rc; 401 402 efx->board_info.hwmon_client = 403 i2c_new_device(&efx->i2c_adap, 404 (efx->board_info.minor < 5) ? 405 &sfn4111t_a0_hwmon_info : 406 &sfn4111t_r5_hwmon_info); 407 if (!efx->board_info.hwmon_client) 408 return -EIO; 409 410 efx->board_info.blink = tenxpress_phy_blink; 411 efx->board_info.monitor = sfn4111t_check_hw; 412 efx->board_info.fini = sfn4111t_fini; 413 414 rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); 415 if (rc) 416 goto fail_hwmon; 417 418 do { 419 if (efx->phy_mode & PHY_MODE_SPECIAL) { 420 /* PHY may not generate a 156.25 MHz clock and MAC 421 * stats fetch will fail. */ 422 efx_stats_disable(efx); 423 sfn4111t_reset(efx); 424 } 425 rc = sft9001_wait_boot(efx); 426 if (rc == 0) 427 return 0; 428 efx->phy_mode = PHY_MODE_SPECIAL; 429 } while (rc == -EINVAL && ++i < 2); 430 431 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); 432fail_hwmon: 433 i2c_unregister_device(efx->board_info.hwmon_client); 434 return rc; 435}