aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/net/sfc/boards.c2
-rw-r--r--drivers/net/sfc/boards.h7
-rw-r--r--drivers/net/sfc/falcon.c7
-rw-r--r--drivers/net/sfc/falcon_hwdefs.h2
-rw-r--r--drivers/net/sfc/selftest.c11
-rw-r--r--drivers/net/sfc/sfe4001.c153
-rw-r--r--drivers/net/sfc/workarounds.h3
7 files changed, 150 insertions, 35 deletions
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index 08fa4e35742b..64903496aa9a 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -241,6 +241,8 @@ struct efx_board_data {
241static struct efx_board_data board_data[] = { 241static struct efx_board_data board_data[] = {
242 { EFX_BOARD_SFE4001, "SFE4001", "10GBASE-T adapter", sfe4001_init }, 242 { EFX_BOARD_SFE4001, "SFE4001", "10GBASE-T adapter", sfe4001_init },
243 { EFX_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init }, 243 { EFX_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init },
244 { EFX_BOARD_SFN4111T, "SFN4111T", "100/1000/10GBASE-T adapter",
245 sfn4111t_init },
244}; 246};
245 247
246void efx_set_board_info(struct efx_nic *efx, u16 revision_info) 248void efx_set_board_info(struct efx_nic *efx, u16 revision_info)
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h
index 5e0dde59c44c..d93c6c6a7548 100644
--- a/drivers/net/sfc/boards.h
+++ b/drivers/net/sfc/boards.h
@@ -12,11 +12,16 @@
12 12
13/* Board IDs (must fit in 8 bits) */ 13/* Board IDs (must fit in 8 bits) */
14enum efx_board_type { 14enum efx_board_type {
15 EFX_BOARD_SFE4001 = 1, /* SFE4001 (10GBASE-T) */ 15 EFX_BOARD_SFE4001 = 1,
16 EFX_BOARD_SFE4002 = 2, 16 EFX_BOARD_SFE4002 = 2,
17 EFX_BOARD_SFN4111T = 0x51,
17}; 18};
18 19
19extern void efx_set_board_info(struct efx_nic *efx, u16 revision_info); 20extern void efx_set_board_info(struct efx_nic *efx, u16 revision_info);
21
22/* SFE4001 (10GBASE-T) */
20extern int sfe4001_init(struct efx_nic *efx); 23extern int sfe4001_init(struct efx_nic *efx);
24/* SFN4111T (100/1000/10GBASE-T) */
25extern int sfn4111t_init(struct efx_nic *efx);
21 26
22#endif 27#endif
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index db8e147f00b2..84771a792099 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2971,6 +2971,13 @@ int falcon_init_nic(struct efx_nic *efx)
2971 EFX_SET_OWORD_FIELD(temp, ONCHIP_SRAM, 1); 2971 EFX_SET_OWORD_FIELD(temp, ONCHIP_SRAM, 1);
2972 falcon_write(efx, &temp, NIC_STAT_REG); 2972 falcon_write(efx, &temp, NIC_STAT_REG);
2973 2973
2974 /* Set the source of the GMAC clock */
2975 if (falcon_rev(efx) == FALCON_REV_B0) {
2976 falcon_read(efx, &temp, GPIO_CTL_REG_KER);
2977 EFX_SET_OWORD_FIELD(temp, GPIO_USE_NIC_CLK, true);
2978 falcon_write(efx, &temp, GPIO_CTL_REG_KER);
2979 }
2980
2974 /* Set buffer table mode */ 2981 /* Set buffer table mode */
2975 EFX_POPULATE_OWORD_1(temp, BUF_TBL_MODE, BUF_TBL_MODE_FULL); 2982 EFX_POPULATE_OWORD_1(temp, BUF_TBL_MODE, BUF_TBL_MODE_FULL);
2976 falcon_write(efx, &temp, BUF_TBL_CFG_REG_KER); 2983 falcon_write(efx, &temp, BUF_TBL_CFG_REG_KER);
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index a58c627f51aa..bda8d5bb72e4 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -136,6 +136,8 @@
136 136
137/* GPIO control register */ 137/* GPIO control register */
138#define GPIO_CTL_REG_KER 0x0210 138#define GPIO_CTL_REG_KER 0x0210
139#define GPIO_USE_NIC_CLK_LBN (30)
140#define GPIO_USE_NIC_CLK_WIDTH (1)
139#define GPIO_OUTPUTS_LBN (16) 141#define GPIO_OUTPUTS_LBN (16)
140#define GPIO_OUTPUTS_WIDTH (4) 142#define GPIO_OUTPUTS_WIDTH (4)
141#define GPIO_INPUTS_LBN (8) 143#define GPIO_INPUTS_LBN (8)
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 578b7f410ed4..6bb09f263b33 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -702,8 +702,15 @@ int efx_offline_test(struct efx_nic *efx,
702 */ 702 */
703 mutex_lock(&efx->mac_lock); 703 mutex_lock(&efx->mac_lock);
704 efx->port_inhibited = true; 704 efx->port_inhibited = true;
705 if (efx->loopback_modes) 705 if (efx->loopback_modes) {
706 efx->loopback_mode = __ffs(efx->loopback_modes); 706 /* We need the 312 clock from the PHY to test the XMAC
707 * registers, so move into XGMII loopback if available */
708 if (efx->loopback_modes & (1 << LOOPBACK_XGMII))
709 efx->loopback_mode = LOOPBACK_XGMII;
710 else
711 efx->loopback_mode = __ffs(efx->loopback_modes);
712 }
713
707 __efx_reconfigure_port(efx); 714 __efx_reconfigure_port(efx);
708 mutex_unlock(&efx->mac_lock); 715 mutex_unlock(&efx->mac_lock);
709 716
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}
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index ecebff211a74..82e03e1d7371 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -17,6 +17,7 @@
17 17
18#define EFX_WORKAROUND_ALWAYS(efx) 1 18#define EFX_WORKAROUND_ALWAYS(efx) 1
19#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) 19#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
20#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
20#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101) 21#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101)
21#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A) 22#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
22 23
@@ -25,7 +26,7 @@
25/* RX PCIe double split performance issue */ 26/* RX PCIe double split performance issue */
26#define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS 27#define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS
27/* Bit-bashed I2C reads cause performance drop */ 28/* Bit-bashed I2C reads cause performance drop */
28#define EFX_WORKAROUND_7884 EFX_WORKAROUND_ALWAYS 29#define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G
29/* TX pkt parser problem with <= 16 byte TXes */ 30/* TX pkt parser problem with <= 16 byte TXes */
30#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS 31#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
31/* Low rate CRC errors require XAUI reset */ 32/* Low rate CRC errors require XAUI reset */