1 /****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2007-2009 Solarflare Communications Inc.
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.
10 #include <linux/rtnetlink.h>
12 #include "net_driver.h"
18 #include "workarounds.h"
20 /* Macros for unpacking the board revision */
21 /* The revision info is in host byte order. */
22 #define FALCON_BOARD_TYPE(_rev) (_rev >> 8)
23 #define FALCON_BOARD_MAJOR(_rev) ((_rev >> 4) & 0xf)
24 #define FALCON_BOARD_MINOR(_rev) (_rev & 0xf)
27 #define FALCON_BOARD_SFE4001 0x01
28 #define FALCON_BOARD_SFE4002 0x02
29 #define FALCON_BOARD_SFE4003 0x03
30 #define FALCON_BOARD_SFN4112F 0x52
32 /* Board temperature is about 15°C above ambient when air flow is
34 #define FALCON_BOARD_TEMP_BIAS 15
36 /* SFC4000 datasheet says: 'The maximum permitted junction temperature
37 * is 125°C; the thermal design of the environment for the SFC4000
38 * should aim to keep this well below 100°C.' */
39 #define FALCON_JUNC_TEMP_MAX 90
41 /*****************************************************************************
42 * Support for LM87 sensor chip used on several boards
44 #define LM87_REG_ALARMS1 0x41
45 #define LM87_REG_ALARMS2 0x42
46 #define LM87_IN_LIMITS(nr, _min, _max) \
47 0x2B + (nr) * 2, _max, 0x2C + (nr) * 2, _min
48 #define LM87_AIN_LIMITS(nr, _min, _max) \
49 0x3B + (nr), _max, 0x1A + (nr), _min
50 #define LM87_TEMP_INT_LIMITS(_min, _max) \
51 0x39, _max, 0x3A, _min
52 #define LM87_TEMP_EXT1_LIMITS(_min, _max) \
53 0x37, _max, 0x38, _min
55 #define LM87_ALARM_TEMP_INT 0x10
56 #define LM87_ALARM_TEMP_EXT1 0x20
58 #if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE)
60 static int efx_init_lm87(struct efx_nic
*efx
, struct i2c_board_info
*info
,
63 struct falcon_board
*board
= falcon_board(efx
);
64 struct i2c_client
*client
= i2c_new_device(&board
->i2c_adap
, info
);
71 u8 reg
= *reg_values
++;
72 u8 value
= *reg_values
++;
73 rc
= i2c_smbus_write_byte_data(client
, reg
, value
);
78 board
->hwmon_client
= client
;
82 i2c_unregister_device(client
);
86 static void efx_fini_lm87(struct efx_nic
*efx
)
88 i2c_unregister_device(falcon_board(efx
)->hwmon_client
);
91 static int efx_check_lm87(struct efx_nic
*efx
, unsigned mask
)
93 struct i2c_client
*client
= falcon_board(efx
)->hwmon_client
;
96 /* If link is up then do not monitor temperature */
97 if (EFX_WORKAROUND_7884(efx
) && efx
->link_state
.up
)
100 alarms1
= i2c_smbus_read_byte_data(client
, LM87_REG_ALARMS1
);
101 alarms2
= i2c_smbus_read_byte_data(client
, LM87_REG_ALARMS2
);
107 alarms2
&= mask
>> 8;
108 if (alarms1
|| alarms2
) {
109 netif_err(efx
, hw
, efx
->net_dev
,
110 "LM87 detected a hardware failure (status %02x:%02x)"
113 (alarms1
& LM87_ALARM_TEMP_INT
) ?
114 "; board is overheating" : "",
115 (alarms1
& LM87_ALARM_TEMP_EXT1
) ?
116 "; controller is overheating" : "",
117 (alarms1
& ~(LM87_ALARM_TEMP_INT
| LM87_ALARM_TEMP_EXT1
)
119 "; electrical fault" : "");
126 #else /* !CONFIG_SENSORS_LM87 */
129 efx_init_lm87(struct efx_nic
*efx
, struct i2c_board_info
*info
,
130 const u8
*reg_values
)
134 static inline void efx_fini_lm87(struct efx_nic
*efx
)
137 static inline int efx_check_lm87(struct efx_nic
*efx
, unsigned mask
)
142 #endif /* CONFIG_SENSORS_LM87 */
144 /*****************************************************************************
145 * Support for the SFE4001 NIC.
147 * The SFE4001 does not power-up fully at reset due to its high power
148 * consumption. We control its power via a PCA9539 I/O expander.
149 * It also has a MAX6647 temperature monitor which we expose to
152 * This also provides minimal support for reflashing the PHY, which is
153 * initiated by resetting it with the FLASH_CFG_1 pin pulled down.
154 * On SFE4001 rev A2 and later this is connected to the 3V3X output of
156 * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually
157 * exclusive with the network device being open.
160 /**************************************************************************
161 * Support for I2C IO Expander device on SFE4001
167 #define P0_INVERT 0x04
168 #define P0_CONFIG 0x06
170 #define P0_EN_1V0X_LBN 0
171 #define P0_EN_1V0X_WIDTH 1
172 #define P0_EN_1V2_LBN 1
173 #define P0_EN_1V2_WIDTH 1
174 #define P0_EN_2V5_LBN 2
175 #define P0_EN_2V5_WIDTH 1
176 #define P0_EN_3V3X_LBN 3
177 #define P0_EN_3V3X_WIDTH 1
178 #define P0_EN_5V_LBN 4
179 #define P0_EN_5V_WIDTH 1
180 #define P0_SHORTEN_JTAG_LBN 5
181 #define P0_SHORTEN_JTAG_WIDTH 1
182 #define P0_X_TRST_LBN 6
183 #define P0_X_TRST_WIDTH 1
184 #define P0_DSP_RESET_LBN 7
185 #define P0_DSP_RESET_WIDTH 1
189 #define P1_INVERT 0x05
190 #define P1_CONFIG 0x07
192 #define P1_AFE_PWD_LBN 0
193 #define P1_AFE_PWD_WIDTH 1
194 #define P1_DSP_PWD25_LBN 1
195 #define P1_DSP_PWD25_WIDTH 1
196 #define P1_RESERVED_LBN 2
197 #define P1_RESERVED_WIDTH 2
198 #define P1_SPARE_LBN 4
199 #define P1_SPARE_WIDTH 4
201 /* Temperature Sensor */
202 #define MAX664X_REG_RSL 0x02
203 #define MAX664X_REG_WLHO 0x0B
205 static void sfe4001_poweroff(struct efx_nic
*efx
)
207 struct i2c_client
*ioexp_client
= falcon_board(efx
)->ioexp_client
;
208 struct i2c_client
*hwmon_client
= falcon_board(efx
)->hwmon_client
;
210 /* Turn off all power rails and disable outputs */
211 i2c_smbus_write_byte_data(ioexp_client
, P0_OUT
, 0xff);
212 i2c_smbus_write_byte_data(ioexp_client
, P1_CONFIG
, 0xff);
213 i2c_smbus_write_byte_data(ioexp_client
, P0_CONFIG
, 0xff);
215 /* Clear any over-temperature alert */
216 i2c_smbus_read_byte_data(hwmon_client
, MAX664X_REG_RSL
);
219 static int sfe4001_poweron(struct efx_nic
*efx
)
221 struct i2c_client
*ioexp_client
= falcon_board(efx
)->ioexp_client
;
222 struct i2c_client
*hwmon_client
= falcon_board(efx
)->hwmon_client
;
227 /* Clear any previous over-temperature alert */
228 rc
= i2c_smbus_read_byte_data(hwmon_client
, MAX664X_REG_RSL
);
232 /* Enable port 0 and port 1 outputs on IO expander */
233 rc
= i2c_smbus_write_byte_data(ioexp_client
, P0_CONFIG
, 0x00);
236 rc
= i2c_smbus_write_byte_data(ioexp_client
, P1_CONFIG
,
237 0xff & ~(1 << P1_SPARE_LBN
));
241 /* If PHY power is on, turn it all off and wait 1 second to
242 * ensure a full reset.
244 rc
= i2c_smbus_read_byte_data(ioexp_client
, P0_OUT
);
247 out
= 0xff & ~((0 << P0_EN_1V2_LBN
) | (0 << P0_EN_2V5_LBN
) |
248 (0 << P0_EN_3V3X_LBN
) | (0 << P0_EN_5V_LBN
) |
249 (0 << P0_EN_1V0X_LBN
));
251 netif_info(efx
, hw
, efx
->net_dev
, "power-cycling PHY\n");
252 rc
= i2c_smbus_write_byte_data(ioexp_client
, P0_OUT
, out
);
255 schedule_timeout_uninterruptible(HZ
);
258 for (i
= 0; i
< 20; ++i
) {
259 /* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */
260 out
= 0xff & ~((1 << P0_EN_1V2_LBN
) | (1 << P0_EN_2V5_LBN
) |
261 (1 << P0_EN_3V3X_LBN
) | (1 << P0_EN_5V_LBN
) |
262 (1 << P0_X_TRST_LBN
));
263 if (efx
->phy_mode
& PHY_MODE_SPECIAL
)
264 out
|= 1 << P0_EN_3V3X_LBN
;
266 rc
= i2c_smbus_write_byte_data(ioexp_client
, P0_OUT
, out
);
271 /* Turn on 1V power rail */
272 out
&= ~(1 << P0_EN_1V0X_LBN
);
273 rc
= i2c_smbus_write_byte_data(ioexp_client
, P0_OUT
, out
);
277 netif_info(efx
, hw
, efx
->net_dev
,
278 "waiting for DSP boot (attempt %d)...\n", i
);
280 /* In flash config mode, DSP does not turn on AFE, so
281 * just wait 1 second.
283 if (efx
->phy_mode
& PHY_MODE_SPECIAL
) {
284 schedule_timeout_uninterruptible(HZ
);
288 for (j
= 0; j
< 10; ++j
) {
291 /* Check DSP has asserted AFE power line */
292 rc
= i2c_smbus_read_byte_data(ioexp_client
, P1_IN
);
295 if (rc
& (1 << P1_AFE_PWD_LBN
))
300 netif_info(efx
, hw
, efx
->net_dev
, "timed out waiting for DSP boot\n");
303 sfe4001_poweroff(efx
);
307 static ssize_t
show_phy_flash_cfg(struct device
*dev
,
308 struct device_attribute
*attr
, char *buf
)
310 struct efx_nic
*efx
= pci_get_drvdata(to_pci_dev(dev
));
311 return sprintf(buf
, "%d\n", !!(efx
->phy_mode
& PHY_MODE_SPECIAL
));
314 static ssize_t
set_phy_flash_cfg(struct device
*dev
,
315 struct device_attribute
*attr
,
316 const char *buf
, size_t count
)
318 struct efx_nic
*efx
= pci_get_drvdata(to_pci_dev(dev
));
319 enum efx_phy_mode old_mode
, new_mode
;
323 old_mode
= efx
->phy_mode
;
324 if (count
== 0 || *buf
== '0')
325 new_mode
= old_mode
& ~PHY_MODE_SPECIAL
;
327 new_mode
= PHY_MODE_SPECIAL
;
328 if (old_mode
== new_mode
) {
330 } else if (efx
->state
!= STATE_RUNNING
|| netif_running(efx
->net_dev
)) {
333 /* Reset the PHY, reconfigure the MAC and enable/disable
334 * MAC stats accordingly. */
335 efx
->phy_mode
= new_mode
;
336 if (new_mode
& PHY_MODE_SPECIAL
)
337 falcon_stop_nic_stats(efx
);
338 err
= sfe4001_poweron(efx
);
340 err
= efx_reconfigure_port(efx
);
341 if (!(new_mode
& PHY_MODE_SPECIAL
))
342 falcon_start_nic_stats(efx
);
346 return err
? err
: count
;
349 static DEVICE_ATTR(phy_flash_cfg
, 0644, show_phy_flash_cfg
, set_phy_flash_cfg
);
351 static void sfe4001_fini(struct efx_nic
*efx
)
353 struct falcon_board
*board
= falcon_board(efx
);
355 netif_info(efx
, drv
, efx
->net_dev
, "%s\n", __func__
);
357 device_remove_file(&efx
->pci_dev
->dev
, &dev_attr_phy_flash_cfg
);
358 sfe4001_poweroff(efx
);
359 i2c_unregister_device(board
->ioexp_client
);
360 i2c_unregister_device(board
->hwmon_client
);
363 static int sfe4001_check_hw(struct efx_nic
*efx
)
367 /* If XAUI link is up then do not monitor */
368 if (EFX_WORKAROUND_7884(efx
) && !efx
->xmac_poll_required
)
371 /* Check the powered status of the PHY. Lack of power implies that
372 * the MAX6647 has shut down power to it, probably due to a temp.
373 * alarm. Reading the power status rather than the MAX6647 status
374 * directly because the later is read-to-clear and would thus
375 * start to power up the PHY again when polled, causing us to blip
376 * the power undesirably.
377 * We know we can read from the IO expander because we did
378 * it during power-on. Assume failure now is bad news. */
379 status
= i2c_smbus_read_byte_data(falcon_board(efx
)->ioexp_client
, P1_IN
);
381 (status
& ((1 << P1_AFE_PWD_LBN
) | (1 << P1_DSP_PWD25_LBN
))) != 0)
384 /* Use board power control, not PHY power control */
385 sfe4001_poweroff(efx
);
386 efx
->phy_mode
= PHY_MODE_OFF
;
388 return (status
< 0) ? -EIO
: -ERANGE
;
391 static struct i2c_board_info sfe4001_hwmon_info
= {
392 I2C_BOARD_INFO("max6647", 0x4e),
395 /* This board uses an I2C expander to provider power to the PHY, which needs to
396 * be turned on before the PHY can be used.
397 * Context: Process context, rtnl lock held
399 static int sfe4001_init(struct efx_nic
*efx
)
401 struct falcon_board
*board
= falcon_board(efx
);
404 #if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE)
405 board
->hwmon_client
=
406 i2c_new_device(&board
->i2c_adap
, &sfe4001_hwmon_info
);
408 board
->hwmon_client
=
409 i2c_new_dummy(&board
->i2c_adap
, sfe4001_hwmon_info
.addr
);
411 if (!board
->hwmon_client
)
414 /* Raise board/PHY high limit from 85 to 90 degrees Celsius */
415 rc
= i2c_smbus_write_byte_data(board
->hwmon_client
,
416 MAX664X_REG_WLHO
, 90);
420 board
->ioexp_client
= i2c_new_dummy(&board
->i2c_adap
, PCA9539
);
421 if (!board
->ioexp_client
) {
426 if (efx
->phy_mode
& PHY_MODE_SPECIAL
) {
427 /* PHY won't generate a 156.25 MHz clock and MAC stats fetch
429 falcon_stop_nic_stats(efx
);
431 rc
= sfe4001_poweron(efx
);
435 rc
= device_create_file(&efx
->pci_dev
->dev
, &dev_attr_phy_flash_cfg
);
439 netif_info(efx
, hw
, efx
->net_dev
, "PHY is powered on\n");
443 sfe4001_poweroff(efx
);
445 i2c_unregister_device(board
->ioexp_client
);
447 i2c_unregister_device(board
->hwmon_client
);
451 /*****************************************************************************
452 * Support for the SFE4002
455 static u8 sfe4002_lm87_channel
= 0x03; /* use AIN not FAN inputs */
457 static const u8 sfe4002_lm87_regs
[] = {
458 LM87_IN_LIMITS(0, 0x7c, 0x99), /* 2.5V: 1.8V +/- 10% */
459 LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */
460 LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */
461 LM87_IN_LIMITS(3, 0xac, 0xd4), /* 5V: 5.0V +/- 10% */
462 LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */
463 LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */
464 LM87_AIN_LIMITS(0, 0x98, 0xbb), /* AIN1: 1.66V +/- 10% */
465 LM87_AIN_LIMITS(1, 0x8a, 0xa9), /* AIN2: 1.5V +/- 10% */
466 LM87_TEMP_INT_LIMITS(0, 80 + FALCON_BOARD_TEMP_BIAS
),
467 LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX
),
471 static struct i2c_board_info sfe4002_hwmon_info
= {
472 I2C_BOARD_INFO("lm87", 0x2e),
473 .platform_data
= &sfe4002_lm87_channel
,
476 /****************************************************************************/
477 /* LED allocations. Note that on rev A0 boards the schematic and the reality
478 * differ: red and green are swapped. Below is the fixed (A1) layout (there
479 * are only 3 A0 boards in existence, so no real reason to make this
482 #define SFE4002_FAULT_LED (2) /* Red */
483 #define SFE4002_RX_LED (0) /* Green */
484 #define SFE4002_TX_LED (1) /* Amber */
486 static void sfe4002_init_phy(struct efx_nic
*efx
)
488 /* Set the TX and RX LEDs to reflect status and activity, and the
490 falcon_qt202x_set_led(efx
, SFE4002_TX_LED
,
491 QUAKE_LED_TXLINK
| QUAKE_LED_LINK_ACTSTAT
);
492 falcon_qt202x_set_led(efx
, SFE4002_RX_LED
,
493 QUAKE_LED_RXLINK
| QUAKE_LED_LINK_ACTSTAT
);
494 falcon_qt202x_set_led(efx
, SFE4002_FAULT_LED
, QUAKE_LED_OFF
);
497 static void sfe4002_set_id_led(struct efx_nic
*efx
, enum efx_led_mode mode
)
499 falcon_qt202x_set_led(
500 efx
, SFE4002_FAULT_LED
,
501 (mode
== EFX_LED_ON
) ? QUAKE_LED_ON
: QUAKE_LED_OFF
);
504 static int sfe4002_check_hw(struct efx_nic
*efx
)
506 struct falcon_board
*board
= falcon_board(efx
);
508 /* A0 board rev. 4002s report a temperature fault the whole time
509 * (bad sensor) so we mask it out. */
510 unsigned alarm_mask
=
511 (board
->major
== 0 && board
->minor
== 0) ?
512 ~LM87_ALARM_TEMP_EXT1
: ~0;
514 return efx_check_lm87(efx
, alarm_mask
);
517 static int sfe4002_init(struct efx_nic
*efx
)
519 return efx_init_lm87(efx
, &sfe4002_hwmon_info
, sfe4002_lm87_regs
);
522 /*****************************************************************************
523 * Support for the SFN4112F
526 static u8 sfn4112f_lm87_channel
= 0x03; /* use AIN not FAN inputs */
528 static const u8 sfn4112f_lm87_regs
[] = {
529 LM87_IN_LIMITS(0, 0x7c, 0x99), /* 2.5V: 1.8V +/- 10% */
530 LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */
531 LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */
532 LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */
533 LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */
534 LM87_AIN_LIMITS(1, 0x8a, 0xa9), /* AIN2: 1.5V +/- 10% */
535 LM87_TEMP_INT_LIMITS(0, 60 + FALCON_BOARD_TEMP_BIAS
),
536 LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX
),
540 static struct i2c_board_info sfn4112f_hwmon_info
= {
541 I2C_BOARD_INFO("lm87", 0x2e),
542 .platform_data
= &sfn4112f_lm87_channel
,
545 #define SFN4112F_ACT_LED 0
546 #define SFN4112F_LINK_LED 1
548 static void sfn4112f_init_phy(struct efx_nic
*efx
)
550 falcon_qt202x_set_led(efx
, SFN4112F_ACT_LED
,
551 QUAKE_LED_RXLINK
| QUAKE_LED_LINK_ACT
);
552 falcon_qt202x_set_led(efx
, SFN4112F_LINK_LED
,
553 QUAKE_LED_RXLINK
| QUAKE_LED_LINK_STAT
);
556 static void sfn4112f_set_id_led(struct efx_nic
*efx
, enum efx_led_mode mode
)
568 reg
= QUAKE_LED_RXLINK
| QUAKE_LED_LINK_STAT
;
572 falcon_qt202x_set_led(efx
, SFN4112F_LINK_LED
, reg
);
575 static int sfn4112f_check_hw(struct efx_nic
*efx
)
577 /* Mask out unused sensors */
578 return efx_check_lm87(efx
, ~0x48);
581 static int sfn4112f_init(struct efx_nic
*efx
)
583 return efx_init_lm87(efx
, &sfn4112f_hwmon_info
, sfn4112f_lm87_regs
);
586 /*****************************************************************************
587 * Support for the SFE4003
590 static u8 sfe4003_lm87_channel
= 0x03; /* use AIN not FAN inputs */
592 static const u8 sfe4003_lm87_regs
[] = {
593 LM87_IN_LIMITS(0, 0x67, 0x7f), /* 2.5V: 1.5V +/- 10% */
594 LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */
595 LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */
596 LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */
597 LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */
598 LM87_TEMP_INT_LIMITS(0, 70 + FALCON_BOARD_TEMP_BIAS
),
602 static struct i2c_board_info sfe4003_hwmon_info
= {
603 I2C_BOARD_INFO("lm87", 0x2e),
604 .platform_data
= &sfe4003_lm87_channel
,
607 /* Board-specific LED info. */
608 #define SFE4003_RED_LED_GPIO 11
609 #define SFE4003_LED_ON 1
610 #define SFE4003_LED_OFF 0
612 static void sfe4003_set_id_led(struct efx_nic
*efx
, enum efx_led_mode mode
)
614 struct falcon_board
*board
= falcon_board(efx
);
616 /* The LEDs were not wired to GPIOs before A3 */
617 if (board
->minor
< 3 && board
->major
== 0)
620 falcon_txc_set_gpio_val(
621 efx
, SFE4003_RED_LED_GPIO
,
622 (mode
== EFX_LED_ON
) ? SFE4003_LED_ON
: SFE4003_LED_OFF
);
625 static void sfe4003_init_phy(struct efx_nic
*efx
)
627 struct falcon_board
*board
= falcon_board(efx
);
629 /* The LEDs were not wired to GPIOs before A3 */
630 if (board
->minor
< 3 && board
->major
== 0)
633 falcon_txc_set_gpio_dir(efx
, SFE4003_RED_LED_GPIO
, TXC_GPIO_DIR_OUTPUT
);
634 falcon_txc_set_gpio_val(efx
, SFE4003_RED_LED_GPIO
, SFE4003_LED_OFF
);
637 static int sfe4003_check_hw(struct efx_nic
*efx
)
639 struct falcon_board
*board
= falcon_board(efx
);
641 /* A0/A1/A2 board rev. 4003s report a temperature fault the whole time
642 * (bad sensor) so we mask it out. */
643 unsigned alarm_mask
=
644 (board
->major
== 0 && board
->minor
<= 2) ?
645 ~LM87_ALARM_TEMP_EXT1
: ~0;
647 return efx_check_lm87(efx
, alarm_mask
);
650 static int sfe4003_init(struct efx_nic
*efx
)
652 return efx_init_lm87(efx
, &sfe4003_hwmon_info
, sfe4003_lm87_regs
);
655 static const struct falcon_board_type board_types
[] = {
657 .id
= FALCON_BOARD_SFE4001
,
658 .ref_model
= "SFE4001",
659 .gen_type
= "10GBASE-T adapter",
660 .init
= sfe4001_init
,
661 .init_phy
= efx_port_dummy_op_void
,
662 .fini
= sfe4001_fini
,
663 .set_id_led
= tenxpress_set_id_led
,
664 .monitor
= sfe4001_check_hw
,
667 .id
= FALCON_BOARD_SFE4002
,
668 .ref_model
= "SFE4002",
669 .gen_type
= "XFP adapter",
670 .init
= sfe4002_init
,
671 .init_phy
= sfe4002_init_phy
,
672 .fini
= efx_fini_lm87
,
673 .set_id_led
= sfe4002_set_id_led
,
674 .monitor
= sfe4002_check_hw
,
677 .id
= FALCON_BOARD_SFE4003
,
678 .ref_model
= "SFE4003",
679 .gen_type
= "10GBASE-CX4 adapter",
680 .init
= sfe4003_init
,
681 .init_phy
= sfe4003_init_phy
,
682 .fini
= efx_fini_lm87
,
683 .set_id_led
= sfe4003_set_id_led
,
684 .monitor
= sfe4003_check_hw
,
687 .id
= FALCON_BOARD_SFN4112F
,
688 .ref_model
= "SFN4112F",
689 .gen_type
= "SFP+ adapter",
690 .init
= sfn4112f_init
,
691 .init_phy
= sfn4112f_init_phy
,
692 .fini
= efx_fini_lm87
,
693 .set_id_led
= sfn4112f_set_id_led
,
694 .monitor
= sfn4112f_check_hw
,
698 int falcon_probe_board(struct efx_nic
*efx
, u16 revision_info
)
700 struct falcon_board
*board
= falcon_board(efx
);
701 u8 type_id
= FALCON_BOARD_TYPE(revision_info
);
704 board
->major
= FALCON_BOARD_MAJOR(revision_info
);
705 board
->minor
= FALCON_BOARD_MINOR(revision_info
);
707 for (i
= 0; i
< ARRAY_SIZE(board_types
); i
++)
708 if (board_types
[i
].id
== type_id
)
709 board
->type
= &board_types
[i
];
712 netif_info(efx
, probe
, efx
->net_dev
, "board is %s rev %c%d\n",
713 (efx
->pci_dev
->subsystem_vendor
== EFX_VENDID_SFC
)
714 ? board
->type
->ref_model
: board
->type
->gen_type
,
715 'A' + board
->major
, board
->minor
);
718 netif_err(efx
, probe
, efx
->net_dev
, "unknown board type %d\n",