aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/mdio_10g.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2009-04-29 04:05:08 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-29 20:32:30 -0400
commit68e7f45e118f98b77cfa007aa2d97b5dac69fe6b (patch)
treed2e05579a0fc1f5a28bce8ff09ac6863d1907186 /drivers/net/sfc/mdio_10g.c
parent1b1c2e95103ce391c2ea39a9460968fcb73deb30 (diff)
sfc: Use generic MDIO functions and definitions
Make use of the newly-added generic MDIO clause 45 support and remove redundant definitions. Add an 'efx_' prefix to the remaining driver-specific MDIO functions and remove arguments which are redundant with efx->mdio.prtad. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/mdio_10g.c')
-rw-r--r--drivers/net/sfc/mdio_10g.c379
1 files changed, 84 insertions, 295 deletions
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 9f5ec3eb3418..11c231a1f875 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -17,7 +17,7 @@
17#include "boards.h" 17#include "boards.h"
18#include "workarounds.h" 18#include "workarounds.h"
19 19
20unsigned mdio_id_oui(u32 id) 20unsigned efx_mdio_id_oui(u32 id)
21{ 21{
22 unsigned oui = 0; 22 unsigned oui = 0;
23 int i; 23 int i;
@@ -32,52 +32,45 @@ unsigned mdio_id_oui(u32 id)
32 return oui; 32 return oui;
33} 33}
34 34
35int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, 35int efx_mdio_reset_mmd(struct efx_nic *port, int mmd,
36 int spins, int spintime) 36 int spins, int spintime)
37{ 37{
38 u32 ctrl; 38 u32 ctrl;
39 int phy_id = port->mii.phy_id;
40 39
41 /* Catch callers passing values in the wrong units (or just silly) */ 40 /* Catch callers passing values in the wrong units (or just silly) */
42 EFX_BUG_ON_PARANOID(spins * spintime >= 5000); 41 EFX_BUG_ON_PARANOID(spins * spintime >= 5000);
43 42
44 mdio_clause45_write(port, phy_id, mmd, MDIO_MMDREG_CTRL1, 43 efx_mdio_write(port, mmd, MDIO_CTRL1, MDIO_CTRL1_RESET);
45 (1 << MDIO_MMDREG_CTRL1_RESET_LBN));
46 /* Wait for the reset bit to clear. */ 44 /* Wait for the reset bit to clear. */
47 do { 45 do {
48 msleep(spintime); 46 msleep(spintime);
49 ctrl = mdio_clause45_read(port, phy_id, mmd, MDIO_MMDREG_CTRL1); 47 ctrl = efx_mdio_read(port, mmd, MDIO_CTRL1);
50 spins--; 48 spins--;
51 49
52 } while (spins && (ctrl & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))); 50 } while (spins && (ctrl & MDIO_CTRL1_RESET));
53 51
54 return spins ? spins : -ETIMEDOUT; 52 return spins ? spins : -ETIMEDOUT;
55} 53}
56 54
57static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd, 55static int efx_mdio_check_mmd(struct efx_nic *efx, int mmd, int fault_fatal)
58 int fault_fatal)
59{ 56{
60 int status; 57 int status;
61 int phy_id = efx->mii.phy_id;
62 58
63 if (LOOPBACK_INTERNAL(efx)) 59 if (LOOPBACK_INTERNAL(efx))
64 return 0; 60 return 0;
65 61
66 if (mmd != MDIO_MMD_AN) { 62 if (mmd != MDIO_MMD_AN) {
67 /* Read MMD STATUS2 to check it is responding. */ 63 /* Read MMD STATUS2 to check it is responding. */
68 status = mdio_clause45_read(efx, phy_id, mmd, 64 status = efx_mdio_read(efx, mmd, MDIO_STAT2);
69 MDIO_MMDREG_STAT2); 65 if ((status & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) {
70 if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
71 ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) !=
72 MDIO_MMDREG_STAT2_PRESENT_VAL) {
73 EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd); 66 EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd);
74 return -EIO; 67 return -EIO;
75 } 68 }
76 } 69 }
77 70
78 /* Read MMD STATUS 1 to check for fault. */ 71 /* Read MMD STATUS 1 to check for fault. */
79 status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT1); 72 status = efx_mdio_read(efx, mmd, MDIO_STAT1);
80 if ((status & (1 << MDIO_MMDREG_STAT1_FAULT_LBN)) != 0) { 73 if (status & MDIO_STAT1_FAULT) {
81 if (fault_fatal) { 74 if (fault_fatal) {
82 EFX_ERR(efx, "PHY MMD %d reporting fatal" 75 EFX_ERR(efx, "PHY MMD %d reporting fatal"
83 " fault: status %x\n", mmd, status); 76 " fault: status %x\n", mmd, status);
@@ -94,8 +87,7 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
94#define MDIO45_RESET_TIME 1000 /* ms */ 87#define MDIO45_RESET_TIME 1000 /* ms */
95#define MDIO45_RESET_ITERS 100 88#define MDIO45_RESET_ITERS 100
96 89
97int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, 90int efx_mdio_wait_reset_mmds(struct efx_nic *efx, unsigned int mmd_mask)
98 unsigned int mmd_mask)
99{ 91{
100 const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS; 92 const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS;
101 int tries = MDIO45_RESET_ITERS; 93 int tries = MDIO45_RESET_ITERS;
@@ -109,16 +101,13 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
109 in_reset = 0; 101 in_reset = 0;
110 while (mask) { 102 while (mask) {
111 if (mask & 1) { 103 if (mask & 1) {
112 stat = mdio_clause45_read(efx, 104 stat = efx_mdio_read(efx, mmd, MDIO_CTRL1);
113 efx->mii.phy_id,
114 mmd,
115 MDIO_MMDREG_CTRL1);
116 if (stat < 0) { 105 if (stat < 0) {
117 EFX_ERR(efx, "failed to read status of" 106 EFX_ERR(efx, "failed to read status of"
118 " MMD %d\n", mmd); 107 " MMD %d\n", mmd);
119 return -EIO; 108 return -EIO;
120 } 109 }
121 if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)) 110 if (stat & MDIO_CTRL1_RESET)
122 in_reset |= (1 << mmd); 111 in_reset |= (1 << mmd);
123 } 112 }
124 mask = mask >> 1; 113 mask = mask >> 1;
@@ -137,28 +126,26 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
137 return rc; 126 return rc;
138} 127}
139 128
140int mdio_clause45_check_mmds(struct efx_nic *efx, 129int efx_mdio_check_mmds(struct efx_nic *efx,
141 unsigned int mmd_mask, unsigned int fatal_mask) 130 unsigned int mmd_mask, unsigned int fatal_mask)
142{ 131{
143 int mmd = 0, probe_mmd, devs0, devs1; 132 int mmd = 0, probe_mmd, devs1, devs2;
144 u32 devices; 133 u32 devices;
145 134
146 /* Historically we have probed the PHYXS to find out what devices are 135 /* Historically we have probed the PHYXS to find out what devices are
147 * present,but that doesn't work so well if the PHYXS isn't expected 136 * present,but that doesn't work so well if the PHYXS isn't expected
148 * to exist, if so just find the first item in the list supplied. */ 137 * to exist, if so just find the first item in the list supplied. */
149 probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS : 138 probe_mmd = (mmd_mask & MDIO_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
150 __ffs(mmd_mask); 139 __ffs(mmd_mask);
151 140
152 /* Check all the expected MMDs are present */ 141 /* Check all the expected MMDs are present */
153 devs0 = mdio_clause45_read(efx, efx->mii.phy_id, 142 devs1 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS1);
154 probe_mmd, MDIO_MMDREG_DEVS0); 143 devs2 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS2);
155 devs1 = mdio_clause45_read(efx, efx->mii.phy_id, 144 if (devs1 < 0 || devs2 < 0) {
156 probe_mmd, MDIO_MMDREG_DEVS1);
157 if (devs0 < 0 || devs1 < 0) {
158 EFX_ERR(efx, "failed to read devices present\n"); 145 EFX_ERR(efx, "failed to read devices present\n");
159 return -EIO; 146 return -EIO;
160 } 147 }
161 devices = devs0 | (devs1 << 16); 148 devices = devs1 | (devs2 << 16);
162 if ((devices & mmd_mask) != mmd_mask) { 149 if ((devices & mmd_mask) != mmd_mask) {
163 EFX_ERR(efx, "required MMDs not present: got %x, " 150 EFX_ERR(efx, "required MMDs not present: got %x, "
164 "wanted %x\n", devices, mmd_mask); 151 "wanted %x\n", devices, mmd_mask);
@@ -170,7 +157,7 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
170 while (mmd_mask) { 157 while (mmd_mask) {
171 if (mmd_mask & 1) { 158 if (mmd_mask & 1) {
172 int fault_fatal = fatal_mask & 1; 159 int fault_fatal = fatal_mask & 1;
173 if (mdio_clause45_check_mmd(efx, mmd, fault_fatal)) 160 if (efx_mdio_check_mmd(efx, mmd, fault_fatal))
174 return -EIO; 161 return -EIO;
175 } 162 }
176 mmd_mask = mmd_mask >> 1; 163 mmd_mask = mmd_mask >> 1;
@@ -181,13 +168,8 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
181 return 0; 168 return 0;
182} 169}
183 170
184bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) 171bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
185{ 172{
186 int phy_id = efx->mii.phy_id;
187 u32 reg;
188 bool ok = true;
189 int mmd = 0;
190
191 /* If the port is in loopback, then we should only consider a subset 173 /* If the port is in loopback, then we should only consider a subset
192 * of mmd's */ 174 * of mmd's */
193 if (LOOPBACK_INTERNAL(efx)) 175 if (LOOPBACK_INTERNAL(efx))
@@ -197,241 +179,75 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
197 else if (efx_phy_mode_disabled(efx->phy_mode)) 179 else if (efx_phy_mode_disabled(efx->phy_mode))
198 return false; 180 return false;
199 else if (efx->loopback_mode == LOOPBACK_PHYXS) 181 else if (efx->loopback_mode == LOOPBACK_PHYXS)
200 mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | 182 mmd_mask &= ~(MDIO_DEVS_PHYXS |
201 MDIO_MMDREG_DEVS_PCS | 183 MDIO_DEVS_PCS |
202 MDIO_MMDREG_DEVS_PMAPMD | 184 MDIO_DEVS_PMAPMD |
203 MDIO_MMDREG_DEVS_AN); 185 MDIO_DEVS_AN);
204 else if (efx->loopback_mode == LOOPBACK_PCS) 186 else if (efx->loopback_mode == LOOPBACK_PCS)
205 mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | 187 mmd_mask &= ~(MDIO_DEVS_PCS |
206 MDIO_MMDREG_DEVS_PMAPMD | 188 MDIO_DEVS_PMAPMD |
207 MDIO_MMDREG_DEVS_AN); 189 MDIO_DEVS_AN);
208 else if (efx->loopback_mode == LOOPBACK_PMAPMD) 190 else if (efx->loopback_mode == LOOPBACK_PMAPMD)
209 mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD | 191 mmd_mask &= ~(MDIO_DEVS_PMAPMD |
210 MDIO_MMDREG_DEVS_AN); 192 MDIO_DEVS_AN);
211
212 if (!mmd_mask) {
213 /* Use presence of XGMII faults in leui of link state */
214 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
215 MDIO_PHYXS_STATUS2);
216 return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
217 }
218 193
219 while (mmd_mask) { 194 return mdio45_links_ok(&efx->mdio, mmd_mask);
220 if (mmd_mask & 1) {
221 /* Double reads because link state is latched, and a
222 * read moves the current state into the register */
223 reg = mdio_clause45_read(efx, phy_id,
224 mmd, MDIO_MMDREG_STAT1);
225 reg = mdio_clause45_read(efx, phy_id,
226 mmd, MDIO_MMDREG_STAT1);
227 ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
228 }
229 mmd_mask = (mmd_mask >> 1);
230 mmd++;
231 }
232 return ok;
233} 195}
234 196
235void mdio_clause45_transmit_disable(struct efx_nic *efx) 197void efx_mdio_transmit_disable(struct efx_nic *efx)
236{ 198{
237 mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 199 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
238 MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN, 200 MDIO_PMA_TXDIS, MDIO_PMD_TXDIS_GLOBAL,
239 efx->phy_mode & PHY_MODE_TX_DISABLED); 201 efx->phy_mode & PHY_MODE_TX_DISABLED);
240} 202}
241 203
242void mdio_clause45_phy_reconfigure(struct efx_nic *efx) 204void efx_mdio_phy_reconfigure(struct efx_nic *efx)
243{ 205{
244 int phy_id = efx->mii.phy_id; 206 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
245 207 MDIO_CTRL1, MDIO_PMA_CTRL1_LOOPBACK,
246 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD, 208 efx->loopback_mode == LOOPBACK_PMAPMD);
247 MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN, 209 efx_mdio_set_flag(efx, MDIO_MMD_PCS,
248 efx->loopback_mode == LOOPBACK_PMAPMD); 210 MDIO_CTRL1, MDIO_PCS_CTRL1_LOOPBACK,
249 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS, 211 efx->loopback_mode == LOOPBACK_PCS);
250 MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN, 212 efx_mdio_set_flag(efx, MDIO_MMD_PHYXS,
251 efx->loopback_mode == LOOPBACK_PCS); 213 MDIO_CTRL1, MDIO_PHYXS_CTRL1_LOOPBACK,
252 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS, 214 efx->loopback_mode == LOOPBACK_NETWORK);
253 MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
254 efx->loopback_mode == LOOPBACK_NETWORK);
255} 215}
256 216
257static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx, 217static void efx_mdio_set_mmd_lpower(struct efx_nic *efx,
258 int lpower, int mmd) 218 int lpower, int mmd)
259{ 219{
260 int phy = efx->mii.phy_id; 220 int stat = efx_mdio_read(efx, mmd, MDIO_STAT1);
261 int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1);
262 221
263 EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n", 222 EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n",
264 mmd, lpower); 223 mmd, lpower);
265 224
266 if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) { 225 if (stat & MDIO_STAT1_LPOWERABLE) {
267 mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1, 226 efx_mdio_set_flag(efx, mmd, MDIO_CTRL1,
268 MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower); 227 MDIO_CTRL1_LPOWER, lpower);
269 } 228 }
270} 229}
271 230
272void mdio_clause45_set_mmds_lpower(struct efx_nic *efx, 231void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
273 int low_power, unsigned int mmd_mask) 232 int low_power, unsigned int mmd_mask)
274{ 233{
275 int mmd = 0; 234 int mmd = 0;
276 mmd_mask &= ~MDIO_MMDREG_DEVS_AN; 235 mmd_mask &= ~MDIO_DEVS_AN;
277 while (mmd_mask) { 236 while (mmd_mask) {
278 if (mmd_mask & 1) 237 if (mmd_mask & 1)
279 mdio_clause45_set_mmd_lpower(efx, low_power, mmd); 238 efx_mdio_set_mmd_lpower(efx, low_power, mmd);
280 mmd_mask = (mmd_mask >> 1); 239 mmd_mask = (mmd_mask >> 1);
281 mmd++; 240 mmd++;
282 } 241 }
283} 242}
284 243
285static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
286{
287 int phy_id = efx->mii.phy_id;
288 u32 result = 0;
289 int reg;
290
291 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr);
292 if (reg & ADVERTISE_10HALF)
293 result |= ADVERTISED_10baseT_Half;
294 if (reg & ADVERTISE_10FULL)
295 result |= ADVERTISED_10baseT_Full;
296 if (reg & ADVERTISE_100HALF)
297 result |= ADVERTISED_100baseT_Half;
298 if (reg & ADVERTISE_100FULL)
299 result |= ADVERTISED_100baseT_Full;
300 return result;
301}
302
303/**
304 * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
305 * @efx: Efx NIC
306 * @ecmd: Buffer for settings
307 *
308 * On return the 'port', 'speed', 'supported' and 'advertising' fields of
309 * ecmd have been filled out.
310 */
311void mdio_clause45_get_settings(struct efx_nic *efx,
312 struct ethtool_cmd *ecmd)
313{
314 mdio_clause45_get_settings_ext(efx, ecmd, 0, 0);
315}
316
317/** 244/**
318 * mdio_clause45_get_settings_ext - Read (some of) the PHY settings over MDIO. 245 * efx_mdio_set_settings - Set (some of) the PHY settings over MDIO.
319 * @efx: Efx NIC
320 * @ecmd: Buffer for settings
321 * @xnp: Advertised Extended Next Page state
322 * @xnp_lpa: Link Partner's advertised XNP state
323 *
324 * On return the 'port', 'speed', 'supported' and 'advertising' fields of
325 * ecmd have been filled out.
326 */
327void mdio_clause45_get_settings_ext(struct efx_nic *efx,
328 struct ethtool_cmd *ecmd,
329 u32 npage_adv, u32 npage_lpa)
330{
331 int phy_id = efx->mii.phy_id;
332 int reg;
333
334 ecmd->transceiver = XCVR_INTERNAL;
335 ecmd->phy_address = phy_id;
336
337 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
338 MDIO_MMDREG_CTRL2);
339 switch (reg & MDIO_PMAPMD_CTRL2_TYPE_MASK) {
340 case MDIO_PMAPMD_CTRL2_10G_BT:
341 case MDIO_PMAPMD_CTRL2_1G_BT:
342 case MDIO_PMAPMD_CTRL2_100_BT:
343 case MDIO_PMAPMD_CTRL2_10_BT:
344 ecmd->port = PORT_TP;
345 ecmd->supported = SUPPORTED_TP;
346 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
347 MDIO_MMDREG_SPEED);
348 if (reg & (1 << MDIO_MMDREG_SPEED_10G_LBN))
349 ecmd->supported |= SUPPORTED_10000baseT_Full;
350 if (reg & (1 << MDIO_MMDREG_SPEED_1000M_LBN))
351 ecmd->supported |= (SUPPORTED_1000baseT_Full |
352 SUPPORTED_1000baseT_Half);
353 if (reg & (1 << MDIO_MMDREG_SPEED_100M_LBN))
354 ecmd->supported |= (SUPPORTED_100baseT_Full |
355 SUPPORTED_100baseT_Half);
356 if (reg & (1 << MDIO_MMDREG_SPEED_10M_LBN))
357 ecmd->supported |= (SUPPORTED_10baseT_Full |
358 SUPPORTED_10baseT_Half);
359 ecmd->advertising = ADVERTISED_TP;
360 break;
361
362 /* We represent CX4 as fibre in the absence of anything better */
363 case MDIO_PMAPMD_CTRL2_10G_CX4:
364 /* All the other defined modes are flavours of optical */
365 default:
366 ecmd->port = PORT_FIBRE;
367 ecmd->supported = SUPPORTED_FIBRE;
368 ecmd->advertising = ADVERTISED_FIBRE;
369 break;
370 }
371
372 if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
373 ecmd->supported |= SUPPORTED_Autoneg;
374 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
375 MDIO_MMDREG_CTRL1);
376 if (reg & BMCR_ANENABLE) {
377 ecmd->autoneg = AUTONEG_ENABLE;
378 ecmd->advertising |=
379 ADVERTISED_Autoneg |
380 mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
381 npage_adv;
382 } else
383 ecmd->autoneg = AUTONEG_DISABLE;
384 } else
385 ecmd->autoneg = AUTONEG_DISABLE;
386
387 if (ecmd->autoneg) {
388 /* If AN is complete, report best common mode,
389 * otherwise report best advertised mode. */
390 u32 modes = 0;
391 if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
392 MDIO_MMDREG_STAT1) &
393 (1 << MDIO_AN_STATUS_AN_DONE_LBN))
394 modes = (ecmd->advertising &
395 (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
396 npage_lpa));
397 if (modes == 0)
398 modes = ecmd->advertising;
399
400 if (modes & ADVERTISED_10000baseT_Full) {
401 ecmd->speed = SPEED_10000;
402 ecmd->duplex = DUPLEX_FULL;
403 } else if (modes & (ADVERTISED_1000baseT_Full |
404 ADVERTISED_1000baseT_Half)) {
405 ecmd->speed = SPEED_1000;
406 ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
407 } else if (modes & (ADVERTISED_100baseT_Full |
408 ADVERTISED_100baseT_Half)) {
409 ecmd->speed = SPEED_100;
410 ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
411 } else {
412 ecmd->speed = SPEED_10;
413 ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
414 }
415 } else {
416 /* Report forced settings */
417 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
418 MDIO_MMDREG_CTRL1);
419 ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) *
420 ((reg & BMCR_SPEED100) ? 100 : 10));
421 ecmd->duplex = (reg & BMCR_FULLDPLX ||
422 ecmd->speed == SPEED_10000);
423 }
424}
425
426/**
427 * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
428 * @efx: Efx NIC 246 * @efx: Efx NIC
429 * @ecmd: New settings 247 * @ecmd: New settings
430 */ 248 */
431int mdio_clause45_set_settings(struct efx_nic *efx, 249int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
432 struct ethtool_cmd *ecmd)
433{ 250{
434 int phy_id = efx->mii.phy_id;
435 struct ethtool_cmd prev; 251 struct ethtool_cmd prev;
436 u32 required; 252 u32 required;
437 int reg; 253 int reg;
@@ -489,94 +305,67 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
489 ADVERTISED_1000baseT_Full)) 305 ADVERTISED_1000baseT_Full))
490 reg |= ADVERTISE_NPAGE; 306 reg |= ADVERTISE_NPAGE;
491 reg |= efx_fc_advertise(efx->wanted_fc); 307 reg |= efx_fc_advertise(efx->wanted_fc);
492 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, 308 efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
493 MDIO_AN_ADVERTISE, reg);
494 309
495 /* Set up the (extended) next page if necessary */ 310 /* Set up the (extended) next page if necessary */
496 if (efx->phy_op->set_npage_adv) 311 if (efx->phy_op->set_npage_adv)
497 efx->phy_op->set_npage_adv(efx, ecmd->advertising); 312 efx->phy_op->set_npage_adv(efx, ecmd->advertising);
498 313
499 /* Enable and restart AN */ 314 /* Enable and restart AN */
500 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, 315 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
501 MDIO_MMDREG_CTRL1); 316 reg |= MDIO_AN_CTRL1_ENABLE;
502 reg |= BMCR_ANENABLE;
503 if (!(EFX_WORKAROUND_15195(efx) && 317 if (!(EFX_WORKAROUND_15195(efx) &&
504 LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)) 318 LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
505 reg |= BMCR_ANRESTART; 319 reg |= MDIO_AN_CTRL1_RESTART;
506 if (xnp) 320 if (xnp)
507 reg |= 1 << MDIO_AN_CTRL_XNP_LBN; 321 reg |= MDIO_AN_CTRL1_XNP;
508 else 322 else
509 reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN); 323 reg &= ~MDIO_AN_CTRL1_XNP;
510 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, 324 efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
511 MDIO_MMDREG_CTRL1, reg);
512 } else { 325 } else {
513 /* Disable AN */ 326 /* Disable AN */
514 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, 327 efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_CTRL1,
515 MDIO_MMDREG_CTRL1, 328 MDIO_AN_CTRL1_ENABLE, false);
516 __ffs(BMCR_ANENABLE), false);
517 329
518 /* Set the basic control bits */ 330 /* Set the basic control bits */
519 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, 331 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1);
520 MDIO_MMDREG_CTRL1); 332 reg &= ~(MDIO_CTRL1_SPEEDSEL | MDIO_CTRL1_FULLDPLX);
521 reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
522 0x003c);
523 if (ecmd->speed == SPEED_100) 333 if (ecmd->speed == SPEED_100)
524 reg |= BMCR_SPEED100; 334 reg |= MDIO_PMA_CTRL1_SPEED100;
525 if (ecmd->duplex) 335 if (ecmd->duplex)
526 reg |= BMCR_FULLDPLX; 336 reg |= MDIO_CTRL1_FULLDPLX;
527 mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, 337 efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, reg);
528 MDIO_MMDREG_CTRL1, reg);
529 } 338 }
530 339
531 return 0; 340 return 0;
532} 341}
533 342
534void mdio_clause45_set_pause(struct efx_nic *efx) 343void efx_mdio_set_pause(struct efx_nic *efx)
535{ 344{
536 int phy_id = efx->mii.phy_id;
537 int reg; 345 int reg;
538 346
539 if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) { 347 if (efx->phy_op->mmds & MDIO_DEVS_AN) {
540 /* Set pause capability advertising */ 348 /* Set pause capability advertising */
541 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, 349 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
542 MDIO_AN_ADVERTISE);
543 reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); 350 reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
544 reg |= efx_fc_advertise(efx->wanted_fc); 351 reg |= efx_fc_advertise(efx->wanted_fc);
545 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, 352 efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
546 MDIO_AN_ADVERTISE, reg);
547 353
548 /* Restart auto-negotiation */ 354 /* Restart auto-negotiation */
549 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, 355 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
550 MDIO_MMDREG_CTRL1); 356 if (reg & MDIO_AN_CTRL1_ENABLE) {
551 if (reg & BMCR_ANENABLE) { 357 reg |= MDIO_AN_CTRL1_RESTART;
552 reg |= BMCR_ANRESTART; 358 efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
553 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
554 MDIO_MMDREG_CTRL1, reg);
555 } 359 }
556 } 360 }
557} 361}
558 362
559enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx) 363enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx)
560{ 364{
561 int phy_id = efx->mii.phy_id;
562 int lpa; 365 int lpa;
563 366
564 if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN))) 367 if (!(efx->phy_op->mmds & MDIO_DEVS_AN))
565 return efx->wanted_fc; 368 return efx->wanted_fc;
566 lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA); 369 lpa = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_LPA);
567 return efx_fc_resolve(efx->wanted_fc, lpa); 370 return efx_fc_resolve(efx->wanted_fc, lpa);
568} 371}
569
570void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
571 u16 addr, int bit, bool sense)
572{
573 int old_val = mdio_clause45_read(efx, prt, dev, addr);
574 int new_val;
575
576 if (sense)
577 new_val = old_val | (1 << bit);
578 else
579 new_val = old_val & ~(1 << bit);
580 if (old_val != new_val)
581 mdio_clause45_write(efx, prt, dev, addr, new_val);
582}