1 /****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2006-2008 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 * Useful functions for working with MDIO clause 45 PHYs
12 #include <linux/types.h>
13 #include <linux/ethtool.h>
14 #include <linux/delay.h>
15 #include "net_driver.h"
19 int mdio_clause45_reset_mmd(struct efx_nic
*port
, int mmd
,
20 int spins
, int spintime
)
23 int phy_id
= port
->mii
.phy_id
;
25 /* Catch callers passing values in the wrong units (or just silly) */
26 EFX_BUG_ON_PARANOID(spins
* spintime
>= 5000);
28 mdio_clause45_write(port
, phy_id
, mmd
, MDIO_MMDREG_CTRL1
,
29 (1 << MDIO_MMDREG_CTRL1_RESET_LBN
));
30 /* Wait for the reset bit to clear. */
33 ctrl
= mdio_clause45_read(port
, phy_id
, mmd
, MDIO_MMDREG_CTRL1
);
36 } while (spins
&& (ctrl
& (1 << MDIO_MMDREG_CTRL1_RESET_LBN
)));
38 return spins
? spins
: -ETIMEDOUT
;
41 static int mdio_clause45_check_mmd(struct efx_nic
*efx
, int mmd
,
45 int phy_id
= efx
->mii
.phy_id
;
47 if (LOOPBACK_INTERNAL(efx
))
50 /* Read MMD STATUS2 to check it is responding. */
51 status
= mdio_clause45_read(efx
, phy_id
, mmd
, MDIO_MMDREG_STAT2
);
52 if (((status
>> MDIO_MMDREG_STAT2_PRESENT_LBN
) &
53 ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH
) - 1)) !=
54 MDIO_MMDREG_STAT2_PRESENT_VAL
) {
55 EFX_ERR(efx
, "PHY MMD %d not responding.\n", mmd
);
59 /* Read MMD STATUS 1 to check for fault. */
60 status
= mdio_clause45_read(efx
, phy_id
, mmd
, MDIO_MMDREG_STAT1
);
61 if ((status
& (1 << MDIO_MMDREG_STAT1_FAULT_LBN
)) != 0) {
63 EFX_ERR(efx
, "PHY MMD %d reporting fatal"
64 " fault: status %x\n", mmd
, status
);
67 EFX_LOG(efx
, "PHY MMD %d reporting status"
68 " %x (expected)\n", mmd
, status
);
74 /* This ought to be ridiculous overkill. We expect it to fail rarely */
75 #define MDIO45_RESET_TIME 1000 /* ms */
76 #define MDIO45_RESET_ITERS 100
78 int mdio_clause45_wait_reset_mmds(struct efx_nic
*efx
,
79 unsigned int mmd_mask
)
81 const int spintime
= MDIO45_RESET_TIME
/ MDIO45_RESET_ITERS
;
82 int tries
= MDIO45_RESET_ITERS
;
93 stat
= mdio_clause45_read(efx
,
98 EFX_ERR(efx
, "failed to read status of"
102 if (stat
& (1 << MDIO_MMDREG_CTRL1_RESET_LBN
))
103 in_reset
|= (1 << mmd
);
114 EFX_ERR(efx
, "not all MMDs came out of reset in time."
115 " MMDs still in reset: %x\n", in_reset
);
121 int mdio_clause45_check_mmds(struct efx_nic
*efx
,
122 unsigned int mmd_mask
, unsigned int fatal_mask
)
124 int devices
, mmd
= 0;
127 /* Historically we have probed the PHYXS to find out what devices are
128 * present,but that doesn't work so well if the PHYXS isn't expected
129 * to exist, if so just find the first item in the list supplied. */
130 probe_mmd
= (mmd_mask
& MDIO_MMDREG_DEVS0_PHYXS
) ? MDIO_MMD_PHYXS
:
132 devices
= mdio_clause45_read(efx
, efx
->mii
.phy_id
,
133 probe_mmd
, MDIO_MMDREG_DEVS0
);
135 /* Check all the expected MMDs are present */
137 EFX_ERR(efx
, "failed to read devices present\n");
140 if ((devices
& mmd_mask
) != mmd_mask
) {
141 EFX_ERR(efx
, "required MMDs not present: got %x, "
142 "wanted %x\n", devices
, mmd_mask
);
145 EFX_TRACE(efx
, "Devices present: %x\n", devices
);
147 /* Check all required MMDs are responding and happy. */
150 int fault_fatal
= fatal_mask
& 1;
151 if (mdio_clause45_check_mmd(efx
, mmd
, fault_fatal
))
154 mmd_mask
= mmd_mask
>> 1;
155 fatal_mask
= fatal_mask
>> 1;
162 int mdio_clause45_links_ok(struct efx_nic
*efx
, unsigned int mmd_mask
)
164 int phy_id
= efx
->mii
.phy_id
;
170 /* If the port is in loopback, then we should only consider a subset
172 if (LOOPBACK_INTERNAL(efx
))
174 else if (efx
->loopback_mode
== LOOPBACK_NETWORK
)
176 else if (efx
->loopback_mode
== LOOPBACK_PHYXS
)
177 mmd_mask
&= ~(MDIO_MMDREG_DEVS0_PHYXS
|
178 MDIO_MMDREG_DEVS0_PCS
|
179 MDIO_MMDREG_DEVS0_PMAPMD
);
180 else if (efx
->loopback_mode
== LOOPBACK_PCS
)
181 mmd_mask
&= ~(MDIO_MMDREG_DEVS0_PCS
|
182 MDIO_MMDREG_DEVS0_PMAPMD
);
183 else if (efx
->loopback_mode
== LOOPBACK_PMAPMD
)
184 mmd_mask
&= ~MDIO_MMDREG_DEVS0_PMAPMD
;
188 /* Double reads because link state is latched, and a
189 * read moves the current state into the register */
190 status
= mdio_clause45_read(efx
, phy_id
,
191 mmd
, MDIO_MMDREG_STAT1
);
192 status
= mdio_clause45_read(efx
, phy_id
,
193 mmd
, MDIO_MMDREG_STAT1
);
195 good
= status
& (1 << MDIO_MMDREG_STAT1_LINK_LBN
);
198 mmd_mask
= (mmd_mask
>> 1);
204 void mdio_clause45_transmit_disable(struct efx_nic
*efx
)
206 int phy_id
= efx
->mii
.phy_id
;
209 ctrl1
= ctrl2
= mdio_clause45_read(efx
, phy_id
, MDIO_MMD_PMAPMD
,
211 if (efx
->tx_disabled
)
212 ctrl2
|= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN
);
214 ctrl1
&= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN
);
216 mdio_clause45_write(efx
, phy_id
, MDIO_MMD_PMAPMD
,
217 MDIO_MMDREG_TXDIS
, ctrl2
);
220 void mdio_clause45_phy_reconfigure(struct efx_nic
*efx
)
222 int phy_id
= efx
->mii
.phy_id
;
225 /* Handle (with debouncing) PMA/PMD loopback */
226 ctrl1
= ctrl2
= mdio_clause45_read(efx
, phy_id
, MDIO_MMD_PMAPMD
,
229 if (efx
->loopback_mode
== LOOPBACK_PMAPMD
)
230 ctrl2
|= (1 << MDIO_PMAPMD_CTRL1_LBACK_LBN
);
232 ctrl2
&= ~(1 << MDIO_PMAPMD_CTRL1_LBACK_LBN
);
235 mdio_clause45_write(efx
, phy_id
, MDIO_MMD_PMAPMD
,
236 MDIO_MMDREG_CTRL1
, ctrl2
);
238 /* Handle (with debouncing) PCS loopback */
239 ctrl1
= ctrl2
= mdio_clause45_read(efx
, phy_id
, MDIO_MMD_PCS
,
241 if (efx
->loopback_mode
== LOOPBACK_PCS
)
242 ctrl2
|= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN
);
244 ctrl2
&= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN
);
247 mdio_clause45_write(efx
, phy_id
, MDIO_MMD_PCS
,
248 MDIO_MMDREG_CTRL1
, ctrl2
);
250 /* Handle (with debouncing) PHYXS network loopback */
251 ctrl1
= ctrl2
= mdio_clause45_read(efx
, phy_id
, MDIO_MMD_PHYXS
,
253 if (efx
->loopback_mode
== LOOPBACK_NETWORK
)
254 ctrl2
|= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN
);
256 ctrl2
&= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN
);
259 mdio_clause45_write(efx
, phy_id
, MDIO_MMD_PHYXS
,
260 MDIO_MMDREG_CTRL1
, ctrl2
);
264 * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
266 * @ecmd: Buffer for settings
268 * On return the 'port', 'speed', 'supported' and 'advertising' fields of
269 * ecmd have been filled out based on the PMA type.
271 void mdio_clause45_get_settings(struct efx_nic
*efx
,
272 struct ethtool_cmd
*ecmd
)
276 /* If no PMA is present we are presumably talking something XAUI-ish
277 * like CX4. Which we report as FIBRE (see below) */
278 if ((efx
->phy_op
->mmds
& DEV_PRESENT_BIT(MDIO_MMD_PMAPMD
)) == 0) {
279 ecmd
->speed
= SPEED_10000
;
280 ecmd
->port
= PORT_FIBRE
;
281 ecmd
->supported
= SUPPORTED_FIBRE
;
282 ecmd
->advertising
= ADVERTISED_FIBRE
;
286 pma_type
= mdio_clause45_read(efx
, efx
->mii
.phy_id
,
287 MDIO_MMD_PMAPMD
, MDIO_MMDREG_CTRL2
);
288 pma_type
&= MDIO_PMAPMD_CTRL2_TYPE_MASK
;
291 /* We represent CX4 as fibre in the absence of anything
293 case MDIO_PMAPMD_CTRL2_10G_CX4
:
294 ecmd
->speed
= SPEED_10000
;
295 ecmd
->port
= PORT_FIBRE
;
296 ecmd
->supported
= SUPPORTED_FIBRE
;
297 ecmd
->advertising
= ADVERTISED_FIBRE
;
300 case MDIO_PMAPMD_CTRL2_10G_BT
:
301 ecmd
->speed
= SPEED_10000
;
302 ecmd
->port
= PORT_TP
;
303 ecmd
->supported
= SUPPORTED_TP
| SUPPORTED_10000baseT_Full
;
304 ecmd
->advertising
= (ADVERTISED_FIBRE
305 | ADVERTISED_10000baseT_Full
);
307 case MDIO_PMAPMD_CTRL2_1G_BT
:
308 ecmd
->speed
= SPEED_1000
;
309 ecmd
->port
= PORT_TP
;
310 ecmd
->supported
= SUPPORTED_TP
| SUPPORTED_1000baseT_Full
;
311 ecmd
->advertising
= (ADVERTISED_FIBRE
312 | ADVERTISED_1000baseT_Full
);
314 case MDIO_PMAPMD_CTRL2_100_BT
:
315 ecmd
->speed
= SPEED_100
;
316 ecmd
->port
= PORT_TP
;
317 ecmd
->supported
= SUPPORTED_TP
| SUPPORTED_100baseT_Full
;
318 ecmd
->advertising
= (ADVERTISED_FIBRE
319 | ADVERTISED_100baseT_Full
);
321 case MDIO_PMAPMD_CTRL2_10_BT
:
322 ecmd
->speed
= SPEED_10
;
323 ecmd
->port
= PORT_TP
;
324 ecmd
->supported
= SUPPORTED_TP
| SUPPORTED_10baseT_Full
;
325 ecmd
->advertising
= ADVERTISED_FIBRE
| ADVERTISED_10baseT_Full
;
327 /* All the other defined modes are flavours of
330 ecmd
->speed
= SPEED_10000
;
331 ecmd
->port
= PORT_FIBRE
;
332 ecmd
->supported
= SUPPORTED_FIBRE
;
333 ecmd
->advertising
= ADVERTISED_FIBRE
;
339 * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
341 * @ecmd: New settings
343 * Currently this just enforces that we are _not_ changing the
344 * 'port', 'speed', 'supported' or 'advertising' settings as these
345 * cannot be changed on any currently supported PHY.
347 int mdio_clause45_set_settings(struct efx_nic
*efx
,
348 struct ethtool_cmd
*ecmd
)
350 struct ethtool_cmd tmpcmd
;
351 mdio_clause45_get_settings(efx
, &tmpcmd
);
352 /* None of the current PHYs support more than one mode
353 * of operation (and only 10GBT ever will), so keep things
355 if ((ecmd
->speed
== tmpcmd
.speed
) && (ecmd
->port
== tmpcmd
.port
) &&
356 (ecmd
->supported
== tmpcmd
.supported
) &&
357 (ecmd
->advertising
== tmpcmd
.advertising
))