aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/sfe4001.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-12-13 01:00:49 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-13 01:00:49 -0500
commit6f158d5f29b420438e907d72cb111ddb9973f00a (patch)
tree38d7696c47a706447c6bf8e66f52a5854d781464 /drivers/net/sfc/sfe4001.c
parente6fa2eb789f49dc51a20d3db0d410bc8158abb43 (diff)
sfc: Add support for SFN4111T
Add support code for the SFN4111T 100/1000/10GBASE-T reference design, based in part on the existing code for the SFE4001. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/sfe4001.c')
-rw-r--r--drivers/net/sfc/sfe4001.c153
1 files changed, 122 insertions, 31 deletions
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index af652844baee..16b80acb9992 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -1,6 +1,6 @@
1/**************************************************************************** 1/****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards 2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2007 Solarflare Communications Inc. 3 * Copyright 2007-2008 Solarflare Communications Inc.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 as published
@@ -8,10 +8,21 @@
8 */ 8 */
9 9
10/***************************************************************************** 10/*****************************************************************************
11 * Support for the SFE4001 NIC: driver code for the PCA9539 I/O expander that 11 * Support for the SFE4001 and SFN4111T NICs.
12 * controls the PHY power rails, and for the MAX6647 temp. sensor used to check 12 *
13 * the PHY 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.
14 */ 24 */
25
15#include <linux/delay.h> 26#include <linux/delay.h>
16#include "net_driver.h" 27#include "net_driver.h"
17#include "efx.h" 28#include "efx.h"
@@ -171,39 +182,30 @@ fail_on:
171 return rc; 182 return rc;
172} 183}
173 184
174static int sfe4001_check_hw(struct efx_nic *efx) 185static int sfn4111t_reset(struct efx_nic *efx)
175{ 186{
176 s32 status; 187 efx_oword_t reg;
177 188
178 /* If XAUI link is up then do not monitor */ 189 /* GPIO pins are also used for I2C, so block that temporarily */
179 if (EFX_WORKAROUND_7884(efx) && efx->mac_up) 190 mutex_lock(&efx->i2c_adap.bus_lock);
180 return 0;
181 191
182 /* Check the powered status of the PHY. Lack of power implies that 192 falcon_read(efx, &reg, GPIO_CTL_REG_KER);
183 * the MAX6647 has shut down power to it, probably due to a temp. 193 EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true);
184 * alarm. Reading the power status rather than the MAX6647 status 194 EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false);
185 * directly because the later is read-to-clear and would thus 195 falcon_write(efx, &reg, GPIO_CTL_REG_KER);
186 * start to power up the PHY again when polled, causing us to blip 196 msleep(1000);
187 * the power undesirably. 197 EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, true);
188 * We know we can read from the IO expander because we did 198 EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, true);
189 * it during power-on. Assume failure now is bad news. */ 199 EFX_SET_OWORD_FIELD(reg, GPIO3_OUT,
190 status = i2c_smbus_read_byte_data(efx->board_info.ioexp_client, P1_IN); 200 !(efx->phy_mode & PHY_MODE_SPECIAL));
191 if (status >= 0 && 201 falcon_write(efx, &reg, GPIO_CTL_REG_KER);
192 (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0)
193 return 0;
194 202
195 /* Use board power control, not PHY power control */ 203 mutex_unlock(&efx->i2c_adap.bus_lock);
196 sfe4001_poweroff(efx);
197 efx->phy_mode = PHY_MODE_OFF;
198 204
199 return (status < 0) ? -EIO : -ERANGE; 205 ssleep(1);
206 return 0;
200} 207}
201 208
202/* On SFE4001 rev A2 and later, we can control the FLASH_CFG_1 pin
203 * using the 3V3X output of the IO-expander. Allow the user to set
204 * this when the device is stopped, and keep it stopped then.
205 */
206
207static ssize_t show_phy_flash_cfg(struct device *dev, 209static ssize_t show_phy_flash_cfg(struct device *dev,
208 struct device_attribute *attr, char *buf) 210 struct device_attribute *attr, char *buf)
209{ 211{
@@ -231,7 +233,10 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
231 err = -EBUSY; 233 err = -EBUSY;
232 } else { 234 } else {
233 efx->phy_mode = new_mode; 235 efx->phy_mode = new_mode;
234 err = sfe4001_poweron(efx); 236 if (efx->board_info.type == EFX_BOARD_SFE4001)
237 err = sfe4001_poweron(efx);
238 else
239 err = sfn4111t_reset(efx);
235 efx_reconfigure_port(efx); 240 efx_reconfigure_port(efx);
236 } 241 }
237 rtnl_unlock(); 242 rtnl_unlock();
@@ -251,6 +256,34 @@ static void sfe4001_fini(struct efx_nic *efx)
251 i2c_unregister_device(efx->board_info.hwmon_client); 256 i2c_unregister_device(efx->board_info.hwmon_client);
252} 257}
253 258
259static int sfe4001_check_hw(struct efx_nic *efx)
260{
261 s32 status;
262
263 /* If XAUI link is up then do not monitor */
264 if (EFX_WORKAROUND_7884(efx) && efx->mac_up)
265 return 0;
266
267 /* Check the powered status of the PHY. Lack of power implies that
268 * the MAX6647 has shut down power to it, probably due to a temp.
269 * alarm. Reading the power status rather than the MAX6647 status
270 * directly because the later is read-to-clear and would thus
271 * start to power up the PHY again when polled, causing us to blip
272 * the power undesirably.
273 * We know we can read from the IO expander because we did
274 * it during power-on. Assume failure now is bad news. */
275 status = i2c_smbus_read_byte_data(efx->board_info.ioexp_client, P1_IN);
276 if (status >= 0 &&
277 (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0)
278 return 0;
279
280 /* Use board power control, not PHY power control */
281 sfe4001_poweroff(efx);
282 efx->phy_mode = PHY_MODE_OFF;
283
284 return (status < 0) ? -EIO : -ERANGE;
285}
286
254static struct i2c_board_info sfe4001_hwmon_info = { 287static struct i2c_board_info sfe4001_hwmon_info = {
255 I2C_BOARD_INFO("max6647", 0x4e), 288 I2C_BOARD_INFO("max6647", 0x4e),
256 .irq = -1, 289 .irq = -1,
@@ -312,3 +345,61 @@ fail_hwmon:
312 i2c_unregister_device(efx->board_info.hwmon_client); 345 i2c_unregister_device(efx->board_info.hwmon_client);
313 return rc; 346 return rc;
314} 347}
348
349static int sfn4111t_check_hw(struct efx_nic *efx)
350{
351 s32 status;
352
353 /* If XAUI link is up then do not monitor */
354 if (EFX_WORKAROUND_7884(efx) && efx->mac_up)
355 return 0;
356
357 /* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */
358 status = i2c_smbus_read_byte_data(efx->board_info.hwmon_client,
359 MAX664X_REG_RSL);
360 if (status < 0)
361 return -EIO;
362 if (status & 0x57)
363 return -ERANGE;
364 return 0;
365}
366
367static void sfn4111t_fini(struct efx_nic *efx)
368{
369 EFX_INFO(efx, "%s\n", __func__);
370
371 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
372 i2c_unregister_device(efx->board_info.hwmon_client);
373}
374
375static struct i2c_board_info sfn4111t_hwmon_info = {
376 I2C_BOARD_INFO("max6647", 0x4e),
377 .irq = -1,
378};
379
380int sfn4111t_init(struct efx_nic *efx)
381{
382 int rc;
383
384 efx->board_info.hwmon_client =
385 i2c_new_device(&efx->i2c_adap, &sfn4111t_hwmon_info);
386 if (!efx->board_info.hwmon_client)
387 return -EIO;
388
389 efx->board_info.blink = tenxpress_phy_blink;
390 efx->board_info.monitor = sfn4111t_check_hw;
391 efx->board_info.fini = sfn4111t_fini;
392
393 rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
394 if (rc)
395 goto fail_hwmon;
396
397 if (efx->phy_mode & PHY_MODE_SPECIAL)
398 sfn4111t_reset(efx);
399
400 return 0;
401
402fail_hwmon:
403 i2c_unregister_device(efx->board_info.hwmon_client);
404 return rc;
405}