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/delay.h>
11 #include <linux/rtnetlink.h>
12 #include <linux/seq_file.h>
13 #include <linux/slab.h>
18 #include "workarounds.h"
20 /* We expect these MMDs to be in the package. */
21 #define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \
26 #define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \
27 (1 << LOOPBACK_PCS) | \
28 (1 << LOOPBACK_PMAPMD) | \
29 (1 << LOOPBACK_PHYXS_WS))
31 /* We complain if we fail to see the link partner as 10G capable this many
32 * times in a row (must be > 1 as sampling the autoneg. registers is racy)
34 #define MAX_BAD_LP_TRIES (5)
36 /* Extended control register */
37 #define PMA_PMD_XCONTROL_REG 49152
38 #define PMA_PMD_EXT_GMII_EN_LBN 1
39 #define PMA_PMD_EXT_GMII_EN_WIDTH 1
40 #define PMA_PMD_EXT_CLK_OUT_LBN 2
41 #define PMA_PMD_EXT_CLK_OUT_WIDTH 1
42 #define PMA_PMD_LNPGA_POWERDOWN_LBN 8
43 #define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1
44 #define PMA_PMD_EXT_CLK312_WIDTH 1
45 #define PMA_PMD_EXT_LPOWER_LBN 12
46 #define PMA_PMD_EXT_LPOWER_WIDTH 1
47 #define PMA_PMD_EXT_ROBUST_LBN 14
48 #define PMA_PMD_EXT_ROBUST_WIDTH 1
49 #define PMA_PMD_EXT_SSR_LBN 15
50 #define PMA_PMD_EXT_SSR_WIDTH 1
52 /* extended status register */
53 #define PMA_PMD_XSTATUS_REG 49153
54 #define PMA_PMD_XSTAT_MDIX_LBN 14
55 #define PMA_PMD_XSTAT_FLP_LBN (12)
57 /* LED control register */
58 #define PMA_PMD_LED_CTRL_REG 49159
59 #define PMA_PMA_LED_ACTIVITY_LBN (3)
61 /* LED function override register */
62 #define PMA_PMD_LED_OVERR_REG 49161
63 /* Bit positions for different LEDs (there are more but not wired on SFE4001)*/
64 #define PMA_PMD_LED_LINK_LBN (0)
65 #define PMA_PMD_LED_SPEED_LBN (2)
66 #define PMA_PMD_LED_TX_LBN (4)
67 #define PMA_PMD_LED_RX_LBN (6)
68 /* Override settings */
69 #define PMA_PMD_LED_AUTO (0) /* H/W control */
70 #define PMA_PMD_LED_ON (1)
71 #define PMA_PMD_LED_OFF (2)
72 #define PMA_PMD_LED_FLASH (3)
73 #define PMA_PMD_LED_MASK 3
74 /* All LEDs under hardware control */
75 /* Green and Amber under hardware control, Red off */
76 #define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
78 #define PMA_PMD_SPEED_ENABLE_REG 49192
79 #define PMA_PMD_100TX_ADV_LBN 1
80 #define PMA_PMD_100TX_ADV_WIDTH 1
81 #define PMA_PMD_1000T_ADV_LBN 2
82 #define PMA_PMD_1000T_ADV_WIDTH 1
83 #define PMA_PMD_10000T_ADV_LBN 3
84 #define PMA_PMD_10000T_ADV_WIDTH 1
85 #define PMA_PMD_SPEED_LBN 4
86 #define PMA_PMD_SPEED_WIDTH 4
88 /* Misc register defines */
89 #define PCS_CLOCK_CTRL_REG 55297
90 #define PLL312_RST_N_LBN 2
92 #define PCS_SOFT_RST2_REG 55302
93 #define SERDES_RST_N_LBN 13
94 #define XGXS_RST_N_LBN 12
96 #define PCS_TEST_SELECT_REG 55303 /* PRM 10.5.8 */
97 #define CLK312_EN_LBN 3
100 #define PHYXS_XCONTROL_REG 49152
101 #define PHYXS_RESET_LBN 15
102 #define PHYXS_RESET_WIDTH 1
104 #define PHYXS_TEST1 (49162)
105 #define LOOPBACK_NEAR_LBN (8)
106 #define LOOPBACK_NEAR_WIDTH (1)
108 /* Boot status register */
109 #define PCS_BOOT_STATUS_REG 53248
110 #define PCS_BOOT_FATAL_ERROR_LBN 0
111 #define PCS_BOOT_PROGRESS_LBN 1
112 #define PCS_BOOT_PROGRESS_WIDTH 2
113 #define PCS_BOOT_PROGRESS_INIT 0
114 #define PCS_BOOT_PROGRESS_WAIT_MDIO 1
115 #define PCS_BOOT_PROGRESS_CHECKSUM 2
116 #define PCS_BOOT_PROGRESS_JUMP 3
117 #define PCS_BOOT_DOWNLOAD_WAIT_LBN 3
118 #define PCS_BOOT_CODE_STARTED_LBN 4
120 /* 100M/1G PHY registers */
121 #define GPHY_XCONTROL_REG 49152
122 #define GPHY_ISOLATE_LBN 10
123 #define GPHY_ISOLATE_WIDTH 1
124 #define GPHY_DUPLEX_LBN 8
125 #define GPHY_DUPLEX_WIDTH 1
126 #define GPHY_LOOPBACK_NEAR_LBN 14
127 #define GPHY_LOOPBACK_NEAR_WIDTH 1
129 #define C22EXT_STATUS_REG 49153
130 #define C22EXT_STATUS_LINK_LBN 2
131 #define C22EXT_STATUS_LINK_WIDTH 1
133 #define C22EXT_MSTSLV_CTRL 49161
134 #define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8
135 #define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9
137 #define C22EXT_MSTSLV_STATUS 49162
138 #define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10
139 #define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11
141 /* Time to wait between powering down the LNPGA and turning off the power
143 #define LNPGA_PDOWN_WAIT (HZ / 5)
145 struct tenxpress_phy_data
{
146 enum efx_loopback_mode loopback_mode
;
147 enum efx_phy_mode phy_mode
;
151 static int tenxpress_init(struct efx_nic
*efx
)
153 /* Enable 312.5 MHz clock */
154 efx_mdio_write(efx
, MDIO_MMD_PCS
, PCS_TEST_SELECT_REG
,
157 /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
158 efx_mdio_set_flag(efx
, MDIO_MMD_PMAPMD
, PMA_PMD_LED_CTRL_REG
,
159 1 << PMA_PMA_LED_ACTIVITY_LBN
, true);
160 efx_mdio_write(efx
, MDIO_MMD_PMAPMD
, PMA_PMD_LED_OVERR_REG
,
161 SFX7101_PMA_PMD_LED_DEFAULT
);
166 static int tenxpress_phy_probe(struct efx_nic
*efx
)
168 struct tenxpress_phy_data
*phy_data
;
170 /* Allocate phy private storage */
171 phy_data
= kzalloc(sizeof(*phy_data
), GFP_KERNEL
);
174 efx
->phy_data
= phy_data
;
175 phy_data
->phy_mode
= efx
->phy_mode
;
177 efx
->mdio
.mmds
= TENXPRESS_REQUIRED_DEVS
;
178 efx
->mdio
.mode_support
= MDIO_SUPPORTS_C45
;
180 efx
->loopback_modes
= SFX7101_LOOPBACKS
| FALCON_XMAC_LOOPBACKS
;
182 efx
->link_advertising
= (ADVERTISED_TP
| ADVERTISED_Autoneg
|
183 ADVERTISED_10000baseT_Full
);
188 static int tenxpress_phy_init(struct efx_nic
*efx
)
192 falcon_board(efx
)->type
->init_phy(efx
);
194 if (!(efx
->phy_mode
& PHY_MODE_SPECIAL
)) {
195 rc
= efx_mdio_wait_reset_mmds(efx
, TENXPRESS_REQUIRED_DEVS
);
199 rc
= efx_mdio_check_mmds(efx
, TENXPRESS_REQUIRED_DEVS
, 0);
204 rc
= tenxpress_init(efx
);
208 /* Reinitialise flow control settings */
209 efx_link_set_wanted_fc(efx
, efx
->wanted_fc
);
210 efx_mdio_an_reconfigure(efx
);
212 schedule_timeout_uninterruptible(HZ
/ 5); /* 200ms */
214 /* Let XGXS and SerDes out of reset */
215 falcon_reset_xaui(efx
);
220 /* Perform a "special software reset" on the PHY. The caller is
221 * responsible for saving and restoring the PHY hardware registers
222 * properly, and masking/unmasking LASI */
223 static int tenxpress_special_reset(struct efx_nic
*efx
)
227 /* The XGMAC clock is driven from the SFX7101 312MHz clock, so
228 * a special software reset can glitch the XGMAC sufficiently for stats
229 * requests to fail. */
230 falcon_stop_nic_stats(efx
);
233 reg
= efx_mdio_read(efx
, MDIO_MMD_PMAPMD
, PMA_PMD_XCONTROL_REG
);
234 reg
|= (1 << PMA_PMD_EXT_SSR_LBN
);
235 efx_mdio_write(efx
, MDIO_MMD_PMAPMD
, PMA_PMD_XCONTROL_REG
, reg
);
239 /* Wait for the blocks to come out of reset */
240 rc
= efx_mdio_wait_reset_mmds(efx
, TENXPRESS_REQUIRED_DEVS
);
244 /* Try and reconfigure the device */
245 rc
= tenxpress_init(efx
);
249 /* Wait for the XGXS state machine to churn */
252 falcon_start_nic_stats(efx
);
256 static void sfx7101_check_bad_lp(struct efx_nic
*efx
, bool link_ok
)
258 struct tenxpress_phy_data
*pd
= efx
->phy_data
;
265 /* Check that AN has started but not completed. */
266 reg
= efx_mdio_read(efx
, MDIO_MMD_AN
, MDIO_STAT1
);
267 if (!(reg
& MDIO_AN_STAT1_LPABLE
))
268 return; /* LP status is unknown */
269 bad_lp
= !(reg
& MDIO_AN_STAT1_COMPLETE
);
274 /* Nothing to do if all is well and was previously so. */
275 if (!pd
->bad_lp_tries
)
278 /* Use the RX (red) LED as an error indicator once we've seen AN
279 * failure several times in a row, and also log a message. */
280 if (!bad_lp
|| pd
->bad_lp_tries
== MAX_BAD_LP_TRIES
) {
281 reg
= efx_mdio_read(efx
, MDIO_MMD_PMAPMD
,
282 PMA_PMD_LED_OVERR_REG
);
283 reg
&= ~(PMA_PMD_LED_MASK
<< PMA_PMD_LED_RX_LBN
);
285 reg
|= PMA_PMD_LED_OFF
<< PMA_PMD_LED_RX_LBN
;
287 reg
|= PMA_PMD_LED_FLASH
<< PMA_PMD_LED_RX_LBN
;
288 netif_err(efx
, link
, efx
->net_dev
,
289 "appears to be plugged into a port"
290 " that is not 10GBASE-T capable. The PHY"
291 " supports 10GBASE-T ONLY, so no link can"
292 " be established\n");
294 efx_mdio_write(efx
, MDIO_MMD_PMAPMD
,
295 PMA_PMD_LED_OVERR_REG
, reg
);
296 pd
->bad_lp_tries
= bad_lp
;
300 static bool sfx7101_link_ok(struct efx_nic
*efx
)
302 return efx_mdio_links_ok(efx
,
308 static void tenxpress_ext_loopback(struct efx_nic
*efx
)
310 efx_mdio_set_flag(efx
, MDIO_MMD_PHYXS
, PHYXS_TEST1
,
311 1 << LOOPBACK_NEAR_LBN
,
312 efx
->loopback_mode
== LOOPBACK_PHYXS
);
315 static void tenxpress_low_power(struct efx_nic
*efx
)
317 efx_mdio_set_mmds_lpower(
318 efx
, !!(efx
->phy_mode
& PHY_MODE_LOW_POWER
),
319 TENXPRESS_REQUIRED_DEVS
);
322 static int tenxpress_phy_reconfigure(struct efx_nic
*efx
)
324 struct tenxpress_phy_data
*phy_data
= efx
->phy_data
;
325 bool phy_mode_change
, loop_reset
;
327 if (efx
->phy_mode
& (PHY_MODE_OFF
| PHY_MODE_SPECIAL
)) {
328 phy_data
->phy_mode
= efx
->phy_mode
;
332 phy_mode_change
= (efx
->phy_mode
== PHY_MODE_NORMAL
&&
333 phy_data
->phy_mode
!= PHY_MODE_NORMAL
);
334 loop_reset
= (LOOPBACK_OUT_OF(phy_data
, efx
, LOOPBACKS_EXTERNAL(efx
)) ||
335 LOOPBACK_CHANGED(phy_data
, efx
, 1 << LOOPBACK_GPHY
));
337 if (loop_reset
|| phy_mode_change
) {
338 tenxpress_special_reset(efx
);
339 falcon_reset_xaui(efx
);
342 tenxpress_low_power(efx
);
343 efx_mdio_transmit_disable(efx
);
344 efx_mdio_phy_reconfigure(efx
);
345 tenxpress_ext_loopback(efx
);
346 efx_mdio_an_reconfigure(efx
);
348 phy_data
->loopback_mode
= efx
->loopback_mode
;
349 phy_data
->phy_mode
= efx
->phy_mode
;
355 tenxpress_get_settings(struct efx_nic
*efx
, struct ethtool_cmd
*ecmd
);
357 /* Poll for link state changes */
358 static bool tenxpress_phy_poll(struct efx_nic
*efx
)
360 struct efx_link_state old_state
= efx
->link_state
;
362 efx
->link_state
.up
= sfx7101_link_ok(efx
);
363 efx
->link_state
.speed
= 10000;
364 efx
->link_state
.fd
= true;
365 efx
->link_state
.fc
= efx_mdio_get_pause(efx
);
367 sfx7101_check_bad_lp(efx
, efx
->link_state
.up
);
369 return !efx_link_state_equal(&efx
->link_state
, &old_state
);
372 static void sfx7101_phy_fini(struct efx_nic
*efx
)
376 /* Power down the LNPGA */
377 reg
= (1 << PMA_PMD_LNPGA_POWERDOWN_LBN
);
378 efx_mdio_write(efx
, MDIO_MMD_PMAPMD
, PMA_PMD_XCONTROL_REG
, reg
);
380 /* Waiting here ensures that the board fini, which can turn
381 * off the power to the PHY, won't get run until the LNPGA
382 * powerdown has been given long enough to complete. */
383 schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT
); /* 200 ms */
386 static void tenxpress_phy_remove(struct efx_nic
*efx
)
388 kfree(efx
->phy_data
);
389 efx
->phy_data
= NULL
;
393 /* Override the RX, TX and link LEDs */
394 void tenxpress_set_id_led(struct efx_nic
*efx
, enum efx_led_mode mode
)
400 reg
= (PMA_PMD_LED_OFF
<< PMA_PMD_LED_TX_LBN
) |
401 (PMA_PMD_LED_OFF
<< PMA_PMD_LED_RX_LBN
) |
402 (PMA_PMD_LED_OFF
<< PMA_PMD_LED_LINK_LBN
);
405 reg
= (PMA_PMD_LED_ON
<< PMA_PMD_LED_TX_LBN
) |
406 (PMA_PMD_LED_ON
<< PMA_PMD_LED_RX_LBN
) |
407 (PMA_PMD_LED_ON
<< PMA_PMD_LED_LINK_LBN
);
410 reg
= SFX7101_PMA_PMD_LED_DEFAULT
;
414 efx_mdio_write(efx
, MDIO_MMD_PMAPMD
, PMA_PMD_LED_OVERR_REG
, reg
);
417 static const char *const sfx7101_test_names
[] = {
421 static const char *sfx7101_test_name(struct efx_nic
*efx
, unsigned int index
)
423 if (index
< ARRAY_SIZE(sfx7101_test_names
))
424 return sfx7101_test_names
[index
];
429 sfx7101_run_tests(struct efx_nic
*efx
, int *results
, unsigned flags
)
433 if (!(flags
& ETH_TEST_FL_OFFLINE
))
436 /* BIST is automatically run after a special software reset */
437 rc
= tenxpress_special_reset(efx
);
438 results
[0] = rc
? -1 : 1;
440 efx_mdio_an_reconfigure(efx
);
446 tenxpress_get_settings(struct efx_nic
*efx
, struct ethtool_cmd
*ecmd
)
448 u32 adv
= 0, lpa
= 0;
451 reg
= efx_mdio_read(efx
, MDIO_MMD_AN
, MDIO_AN_10GBT_CTRL
);
452 if (reg
& MDIO_AN_10GBT_CTRL_ADV10G
)
453 adv
|= ADVERTISED_10000baseT_Full
;
454 reg
= efx_mdio_read(efx
, MDIO_MMD_AN
, MDIO_AN_10GBT_STAT
);
455 if (reg
& MDIO_AN_10GBT_STAT_LP10G
)
456 lpa
|= ADVERTISED_10000baseT_Full
;
458 mdio45_ethtool_gset_npage(&efx
->mdio
, ecmd
, adv
, lpa
);
460 /* In loopback, the PHY automatically brings up the correct interface,
461 * but doesn't advertise the correct speed. So override it */
462 if (LOOPBACK_EXTERNAL(efx
))
463 ecmd
->speed
= SPEED_10000
;
466 static int tenxpress_set_settings(struct efx_nic
*efx
, struct ethtool_cmd
*ecmd
)
471 return efx_mdio_set_settings(efx
, ecmd
);
474 static void sfx7101_set_npage_adv(struct efx_nic
*efx
, u32 advertising
)
476 efx_mdio_set_flag(efx
, MDIO_MMD_AN
, MDIO_AN_10GBT_CTRL
,
477 MDIO_AN_10GBT_CTRL_ADV10G
,
478 advertising
& ADVERTISED_10000baseT_Full
);
481 struct efx_phy_operations falcon_sfx7101_phy_ops
= {
482 .probe
= tenxpress_phy_probe
,
483 .init
= tenxpress_phy_init
,
484 .reconfigure
= tenxpress_phy_reconfigure
,
485 .poll
= tenxpress_phy_poll
,
486 .fini
= sfx7101_phy_fini
,
487 .remove
= tenxpress_phy_remove
,
488 .get_settings
= tenxpress_get_settings
,
489 .set_settings
= tenxpress_set_settings
,
490 .set_npage_adv
= sfx7101_set_npage_adv
,
491 .test_alive
= efx_mdio_test_alive
,
492 .test_name
= sfx7101_test_name
,
493 .run_tests
= sfx7101_run_tests
,