aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/tenxpress.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-06-16 05:27:45 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-16 05:27:45 -0400
commitd939d2851fd12568e2eabb2916769e8a57ba5c89 (patch)
treef3158a5ddd41541a61126f9e48de1ce89c632f64 /drivers/net/sfc/tenxpress.c
parent9f5314fb4d556d3132c784d0df47352b2830ca53 (diff)
parent066519068ad2fbe98c7f45552b1f592903a9c8c8 (diff)
Merge branch 'linus' into x86/irq
Diffstat (limited to 'drivers/net/sfc/tenxpress.c')
-rw-r--r--drivers/net/sfc/tenxpress.c93
1 files changed, 89 insertions, 4 deletions
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index a2e9f79e47b1..c0146061c326 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -24,6 +24,11 @@
24 MDIO_MMDREG_DEVS0_PCS | \ 24 MDIO_MMDREG_DEVS0_PCS | \
25 MDIO_MMDREG_DEVS0_PHYXS) 25 MDIO_MMDREG_DEVS0_PHYXS)
26 26
27#define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \
28 (1 << LOOPBACK_PCS) | \
29 (1 << LOOPBACK_PMAPMD) | \
30 (1 << LOOPBACK_NETWORK))
31
27/* We complain if we fail to see the link partner as 10G capable this many 32/* We complain if we fail to see the link partner as 10G capable this many
28 * times in a row (must be > 1 as sampling the autoneg. registers is racy) 33 * times in a row (must be > 1 as sampling the autoneg. registers is racy)
29 */ 34 */
@@ -72,6 +77,10 @@
72#define PMA_PMD_BIST_RXD_LBN (1) 77#define PMA_PMD_BIST_RXD_LBN (1)
73#define PMA_PMD_BIST_AFE_LBN (0) 78#define PMA_PMD_BIST_AFE_LBN (0)
74 79
80/* Special Software reset register */
81#define PMA_PMD_EXT_CTRL_REG 49152
82#define PMA_PMD_EXT_SSR_LBN 15
83
75#define BIST_MAX_DELAY (1000) 84#define BIST_MAX_DELAY (1000)
76#define BIST_POLL_DELAY (10) 85#define BIST_POLL_DELAY (10)
77 86
@@ -86,6 +95,11 @@
86#define PCS_TEST_SELECT_REG 0xd807 /* PRM 10.5.8 */ 95#define PCS_TEST_SELECT_REG 0xd807 /* PRM 10.5.8 */
87#define CLK312_EN_LBN 3 96#define CLK312_EN_LBN 3
88 97
98/* PHYXS registers */
99#define PHYXS_TEST1 (49162)
100#define LOOPBACK_NEAR_LBN (8)
101#define LOOPBACK_NEAR_WIDTH (1)
102
89/* Boot status register */ 103/* Boot status register */
90#define PCS_BOOT_STATUS_REG (0xd000) 104#define PCS_BOOT_STATUS_REG (0xd000)
91#define PCS_BOOT_FATAL_ERR_LBN (0) 105#define PCS_BOOT_FATAL_ERR_LBN (0)
@@ -106,7 +120,9 @@ MODULE_PARM_DESC(crc_error_reset_threshold,
106 120
107struct tenxpress_phy_data { 121struct tenxpress_phy_data {
108 enum tenxpress_state state; 122 enum tenxpress_state state;
123 enum efx_loopback_mode loopback_mode;
109 atomic_t bad_crc_count; 124 atomic_t bad_crc_count;
125 int tx_disabled;
110 int bad_lp_tries; 126 int bad_lp_tries;
111}; 127};
112 128
@@ -195,14 +211,18 @@ static int tenxpress_phy_init(struct efx_nic *efx)
195 int rc = 0; 211 int rc = 0;
196 212
197 phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); 213 phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
214 if (!phy_data)
215 return -ENOMEM;
198 efx->phy_data = phy_data; 216 efx->phy_data = phy_data;
199 217
200 tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL); 218 tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL);
201 219
202 rc = mdio_clause45_wait_reset_mmds(efx, 220 if (!sfe4001_phy_flash_cfg) {
203 TENXPRESS_REQUIRED_DEVS); 221 rc = mdio_clause45_wait_reset_mmds(efx,
204 if (rc < 0) 222 TENXPRESS_REQUIRED_DEVS);
205 goto fail; 223 if (rc < 0)
224 goto fail;
225 }
206 226
207 rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); 227 rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
208 if (rc < 0) 228 if (rc < 0)
@@ -225,6 +245,35 @@ static int tenxpress_phy_init(struct efx_nic *efx)
225 return rc; 245 return rc;
226} 246}
227 247
248static int tenxpress_special_reset(struct efx_nic *efx)
249{
250 int rc, reg;
251
252 EFX_TRACE(efx, "%s\n", __func__);
253
254 /* Initiate reset */
255 reg = mdio_clause45_read(efx, efx->mii.phy_id,
256 MDIO_MMD_PMAPMD, PMA_PMD_EXT_CTRL_REG);
257 reg |= (1 << PMA_PMD_EXT_SSR_LBN);
258 mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
259 PMA_PMD_EXT_CTRL_REG, reg);
260
261 msleep(200);
262
263 /* Wait for the blocks to come out of reset */
264 rc = mdio_clause45_wait_reset_mmds(efx,
265 TENXPRESS_REQUIRED_DEVS);
266 if (rc < 0)
267 return rc;
268
269 /* Try and reconfigure the device */
270 rc = tenxpress_init(efx);
271 if (rc < 0)
272 return rc;
273
274 return 0;
275}
276
228static void tenxpress_set_bad_lp(struct efx_nic *efx, int bad_lp) 277static void tenxpress_set_bad_lp(struct efx_nic *efx, int bad_lp)
229{ 278{
230 struct tenxpress_phy_data *pd = efx->phy_data; 279 struct tenxpress_phy_data *pd = efx->phy_data;
@@ -299,11 +348,46 @@ static int tenxpress_link_ok(struct efx_nic *efx, int check_lp)
299 return ok; 348 return ok;
300} 349}
301 350
351static void tenxpress_phyxs_loopback(struct efx_nic *efx)
352{
353 int phy_id = efx->mii.phy_id;
354 int ctrl1, ctrl2;
355
356 ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
357 PHYXS_TEST1);
358 if (efx->loopback_mode == LOOPBACK_PHYXS)
359 ctrl2 |= (1 << LOOPBACK_NEAR_LBN);
360 else
361 ctrl2 &= ~(1 << LOOPBACK_NEAR_LBN);
362 if (ctrl1 != ctrl2)
363 mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS,
364 PHYXS_TEST1, ctrl2);
365}
366
302static void tenxpress_phy_reconfigure(struct efx_nic *efx) 367static void tenxpress_phy_reconfigure(struct efx_nic *efx)
303{ 368{
369 struct tenxpress_phy_data *phy_data = efx->phy_data;
370 int loop_change = LOOPBACK_OUT_OF(phy_data, efx,
371 TENXPRESS_LOOPBACKS);
372
304 if (!tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL)) 373 if (!tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL))
305 return; 374 return;
306 375
376 /* When coming out of transmit disable, coming out of low power
377 * mode, or moving out of any PHY internal loopback mode,
378 * perform a special software reset */
379 if ((phy_data->tx_disabled && !efx->tx_disabled) ||
380 loop_change) {
381 tenxpress_special_reset(efx);
382 falcon_reset_xaui(efx);
383 }
384
385 mdio_clause45_transmit_disable(efx);
386 mdio_clause45_phy_reconfigure(efx);
387 tenxpress_phyxs_loopback(efx);
388
389 phy_data->tx_disabled = efx->tx_disabled;
390 phy_data->loopback_mode = efx->loopback_mode;
307 efx->link_up = tenxpress_link_ok(efx, 0); 391 efx->link_up = tenxpress_link_ok(efx, 0);
308 efx->link_options = GM_LPA_10000FULL; 392 efx->link_options = GM_LPA_10000FULL;
309} 393}
@@ -431,4 +515,5 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = {
431 .clear_interrupt = tenxpress_phy_clear_interrupt, 515 .clear_interrupt = tenxpress_phy_clear_interrupt,
432 .reset_xaui = tenxpress_reset_xaui, 516 .reset_xaui = tenxpress_reset_xaui,
433 .mmds = TENXPRESS_REQUIRED_DEVS, 517 .mmds = TENXPRESS_REQUIRED_DEVS,
518 .loopbacks = TENXPRESS_LOOPBACKS,
434}; 519};