• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * Driver for Solarflare Solarstorm network controllers and boards
3  * Copyright 2006-2008 Solarflare Communications Inc.
4  *
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.
8  */
9 /*
10  * Useful functions for working with MDIO clause 45 PHYs
11  */
12 #include <linux/types.h>
13 #include <linux/ethtool.h>
14 #include <linux/delay.h>
15 #include "net_driver.h"
16 #include "mdio_10g.h"
17 #include "boards.h"
18 #include "workarounds.h"
19 
mdio_clause45_reset_mmd(struct efx_nic * port,int mmd,int spins,int spintime)20 int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
21 			    int spins, int spintime)
22 {
23 	u32 ctrl;
24 	int phy_id = port->mii.phy_id;
25 
26 	/* Catch callers passing values in the wrong units (or just silly) */
27 	EFX_BUG_ON_PARANOID(spins * spintime >= 5000);
28 
29 	mdio_clause45_write(port, phy_id, mmd, MDIO_MMDREG_CTRL1,
30 			    (1 << MDIO_MMDREG_CTRL1_RESET_LBN));
31 	/* Wait for the reset bit to clear. */
32 	do {
33 		msleep(spintime);
34 		ctrl = mdio_clause45_read(port, phy_id, mmd, MDIO_MMDREG_CTRL1);
35 		spins--;
36 
37 	} while (spins && (ctrl & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)));
38 
39 	return spins ? spins : -ETIMEDOUT;
40 }
41 
mdio_clause45_check_mmd(struct efx_nic * efx,int mmd,int fault_fatal)42 static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
43 				   int fault_fatal)
44 {
45 	int status;
46 	int phy_id = efx->mii.phy_id;
47 
48 	if (LOOPBACK_INTERNAL(efx))
49 		return 0;
50 
51 	if (mmd != MDIO_MMD_AN) {
52 		/* Read MMD STATUS2 to check it is responding. */
53 		status = mdio_clause45_read(efx, phy_id, mmd,
54 					    MDIO_MMDREG_STAT2);
55 		if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
56 		     ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) !=
57 		    MDIO_MMDREG_STAT2_PRESENT_VAL) {
58 			EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd);
59 			return -EIO;
60 		}
61 	}
62 
63 	/* Read MMD STATUS 1 to check for fault. */
64 	status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT1);
65 	if ((status & (1 << MDIO_MMDREG_STAT1_FAULT_LBN)) != 0) {
66 		if (fault_fatal) {
67 			EFX_ERR(efx, "PHY MMD %d reporting fatal"
68 				" fault: status %x\n", mmd, status);
69 			return -EIO;
70 		} else {
71 			EFX_LOG(efx, "PHY MMD %d reporting status"
72 				" %x (expected)\n", mmd, status);
73 		}
74 	}
75 	return 0;
76 }
77 
78 /* This ought to be ridiculous overkill. We expect it to fail rarely */
79 #define MDIO45_RESET_TIME	1000 /* ms */
80 #define MDIO45_RESET_ITERS	100
81 
mdio_clause45_wait_reset_mmds(struct efx_nic * efx,unsigned int mmd_mask)82 int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
83 				  unsigned int mmd_mask)
84 {
85 	const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS;
86 	int tries = MDIO45_RESET_ITERS;
87 	int rc = 0;
88 	int in_reset;
89 
90 	while (tries) {
91 		int mask = mmd_mask;
92 		int mmd = 0;
93 		int stat;
94 		in_reset = 0;
95 		while (mask) {
96 			if (mask & 1) {
97 				stat = mdio_clause45_read(efx,
98 							  efx->mii.phy_id,
99 							  mmd,
100 							  MDIO_MMDREG_CTRL1);
101 				if (stat < 0) {
102 					EFX_ERR(efx, "failed to read status of"
103 						" MMD %d\n", mmd);
104 					return -EIO;
105 				}
106 				if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))
107 					in_reset |= (1 << mmd);
108 			}
109 			mask = mask >> 1;
110 			mmd++;
111 		}
112 		if (!in_reset)
113 			break;
114 		tries--;
115 		msleep(spintime);
116 	}
117 	if (in_reset != 0) {
118 		EFX_ERR(efx, "not all MMDs came out of reset in time."
119 			" MMDs still in reset: %x\n", in_reset);
120 		rc = -ETIMEDOUT;
121 	}
122 	return rc;
123 }
124 
mdio_clause45_check_mmds(struct efx_nic * efx,unsigned int mmd_mask,unsigned int fatal_mask)125 int mdio_clause45_check_mmds(struct efx_nic *efx,
126 			     unsigned int mmd_mask, unsigned int fatal_mask)
127 {
128 	u32 devices;
129 	int mmd = 0, probe_mmd;
130 
131 	/* Historically we have probed the PHYXS to find out what devices are
132 	 * present,but that doesn't work so well if the PHYXS isn't expected
133 	 * to exist, if so just find the first item in the list supplied. */
134 	probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
135 	    __ffs(mmd_mask);
136 	devices = (mdio_clause45_read(efx, efx->mii.phy_id,
137 				      probe_mmd, MDIO_MMDREG_DEVS0) |
138 		   mdio_clause45_read(efx, efx->mii.phy_id,
139 				      probe_mmd, MDIO_MMDREG_DEVS1) << 16);
140 
141 	/* Check all the expected MMDs are present */
142 	if (devices < 0) {
143 		EFX_ERR(efx, "failed to read devices present\n");
144 		return -EIO;
145 	}
146 	if ((devices & mmd_mask) != mmd_mask) {
147 		EFX_ERR(efx, "required MMDs not present: got %x, "
148 			"wanted %x\n", devices, mmd_mask);
149 		return -ENODEV;
150 	}
151 	EFX_TRACE(efx, "Devices present: %x\n", devices);
152 
153 	/* Check all required MMDs are responding and happy. */
154 	while (mmd_mask) {
155 		if (mmd_mask & 1) {
156 			int fault_fatal = fatal_mask & 1;
157 			if (mdio_clause45_check_mmd(efx, mmd, fault_fatal))
158 				return -EIO;
159 		}
160 		mmd_mask = mmd_mask >> 1;
161 		fatal_mask = fatal_mask >> 1;
162 		mmd++;
163 	}
164 
165 	return 0;
166 }
167 
mdio_clause45_links_ok(struct efx_nic * efx,unsigned int mmd_mask)168 bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
169 {
170 	int phy_id = efx->mii.phy_id;
171 	u32 reg;
172 	bool ok = true;
173 	int mmd = 0;
174 
175 	/* If the port is in loopback, then we should only consider a subset
176 	 * of mmd's */
177 	if (LOOPBACK_INTERNAL(efx))
178 		return true;
179 	else if (efx->loopback_mode == LOOPBACK_NETWORK)
180 		return false;
181 	else if (efx_phy_mode_disabled(efx->phy_mode))
182 		return false;
183 	else if (efx->loopback_mode == LOOPBACK_PHYXS)
184 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
185 			      MDIO_MMDREG_DEVS_PCS |
186 			      MDIO_MMDREG_DEVS_PMAPMD |
187 			      MDIO_MMDREG_DEVS_AN);
188 	else if (efx->loopback_mode == LOOPBACK_PCS)
189 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
190 			      MDIO_MMDREG_DEVS_PMAPMD |
191 			      MDIO_MMDREG_DEVS_AN);
192 	else if (efx->loopback_mode == LOOPBACK_PMAPMD)
193 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
194 			      MDIO_MMDREG_DEVS_AN);
195 
196 	if (!mmd_mask) {
197 		/* Use presence of XGMII faults in leui of link state */
198 		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
199 					 MDIO_PHYXS_STATUS2);
200 		return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
201 	}
202 
203 	while (mmd_mask) {
204 		if (mmd_mask & 1) {
205 			/* Double reads because link state is latched, and a
206 			 * read moves the current state into the register */
207 			reg = mdio_clause45_read(efx, phy_id,
208 						 mmd, MDIO_MMDREG_STAT1);
209 			reg = mdio_clause45_read(efx, phy_id,
210 						 mmd, MDIO_MMDREG_STAT1);
211 			ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
212 		}
213 		mmd_mask = (mmd_mask >> 1);
214 		mmd++;
215 	}
216 	return ok;
217 }
218 
mdio_clause45_transmit_disable(struct efx_nic * efx)219 void mdio_clause45_transmit_disable(struct efx_nic *efx)
220 {
221 	mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
222 			       MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN,
223 			       efx->phy_mode & PHY_MODE_TX_DISABLED);
224 }
225 
mdio_clause45_phy_reconfigure(struct efx_nic * efx)226 void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
227 {
228 	int phy_id = efx->mii.phy_id;
229 
230 	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
231 			       MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN,
232 			       efx->loopback_mode == LOOPBACK_PMAPMD);
233 	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS,
234 			       MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
235 			       efx->loopback_mode == LOOPBACK_PCS);
236 	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
237 			       MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
238 			       efx->loopback_mode == LOOPBACK_NETWORK);
239 }
240 
mdio_clause45_set_mmd_lpower(struct efx_nic * efx,int lpower,int mmd)241 static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
242 					 int lpower, int mmd)
243 {
244 	int phy = efx->mii.phy_id;
245 	int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1);
246 
247 	EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n",
248 		  mmd, lpower);
249 
250 	if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) {
251 		mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1,
252 				       MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower);
253 	}
254 }
255 
mdio_clause45_set_mmds_lpower(struct efx_nic * efx,int low_power,unsigned int mmd_mask)256 void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
257 				   int low_power, unsigned int mmd_mask)
258 {
259 	int mmd = 0;
260 	mmd_mask &= ~MDIO_MMDREG_DEVS_AN;
261 	while (mmd_mask) {
262 		if (mmd_mask & 1)
263 			mdio_clause45_set_mmd_lpower(efx, low_power, mmd);
264 		mmd_mask = (mmd_mask >> 1);
265 		mmd++;
266 	}
267 }
268 
mdio_clause45_get_an(struct efx_nic * efx,u16 addr)269 static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
270 {
271 	int phy_id = efx->mii.phy_id;
272 	u32 result = 0;
273 	int reg;
274 
275 	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr);
276 	if (reg & ADVERTISE_10HALF)
277 		result |= ADVERTISED_10baseT_Half;
278 	if (reg & ADVERTISE_10FULL)
279 		result |= ADVERTISED_10baseT_Full;
280 	if (reg & ADVERTISE_100HALF)
281 		result |= ADVERTISED_100baseT_Half;
282 	if (reg & ADVERTISE_100FULL)
283 		result |= ADVERTISED_100baseT_Full;
284 	return result;
285 }
286 
287 /**
288  * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
289  * @efx:		Efx NIC
290  * @ecmd: 		Buffer for settings
291  *
292  * On return the 'port', 'speed', 'supported' and 'advertising' fields of
293  * ecmd have been filled out.
294  */
mdio_clause45_get_settings(struct efx_nic * efx,struct ethtool_cmd * ecmd)295 void mdio_clause45_get_settings(struct efx_nic *efx,
296 				struct ethtool_cmd *ecmd)
297 {
298 	mdio_clause45_get_settings_ext(efx, ecmd, 0, 0);
299 }
300 
301 /**
302  * mdio_clause45_get_settings_ext - Read (some of) the PHY settings over MDIO.
303  * @efx:		Efx NIC
304  * @ecmd: 		Buffer for settings
305  * @xnp:		Advertised Extended Next Page state
306  * @xnp_lpa:		Link Partner's advertised XNP state
307  *
308  * On return the 'port', 'speed', 'supported' and 'advertising' fields of
309  * ecmd have been filled out.
310  */
mdio_clause45_get_settings_ext(struct efx_nic * efx,struct ethtool_cmd * ecmd,u32 npage_adv,u32 npage_lpa)311 void mdio_clause45_get_settings_ext(struct efx_nic *efx,
312 				    struct ethtool_cmd *ecmd,
313 				    u32 npage_adv, u32 npage_lpa)
314 {
315 	int phy_id = efx->mii.phy_id;
316 	int reg;
317 
318 	ecmd->transceiver = XCVR_INTERNAL;
319 	ecmd->phy_address = phy_id;
320 
321 	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
322 				 MDIO_MMDREG_CTRL2);
323 	switch (reg & MDIO_PMAPMD_CTRL2_TYPE_MASK) {
324 	case MDIO_PMAPMD_CTRL2_10G_BT:
325 	case MDIO_PMAPMD_CTRL2_1G_BT:
326 	case MDIO_PMAPMD_CTRL2_100_BT:
327 	case MDIO_PMAPMD_CTRL2_10_BT:
328 		ecmd->port = PORT_TP;
329 		ecmd->supported = SUPPORTED_TP;
330 		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
331 					 MDIO_MMDREG_SPEED);
332 		if (reg & (1 << MDIO_MMDREG_SPEED_10G_LBN))
333 			ecmd->supported |= SUPPORTED_10000baseT_Full;
334 		if (reg & (1 << MDIO_MMDREG_SPEED_1000M_LBN))
335 			ecmd->supported |= (SUPPORTED_1000baseT_Full |
336 					    SUPPORTED_1000baseT_Half);
337 		if (reg & (1 << MDIO_MMDREG_SPEED_100M_LBN))
338 			ecmd->supported |= (SUPPORTED_100baseT_Full |
339 					    SUPPORTED_100baseT_Half);
340 		if (reg & (1 << MDIO_MMDREG_SPEED_10M_LBN))
341 			ecmd->supported |= (SUPPORTED_10baseT_Full |
342 					    SUPPORTED_10baseT_Half);
343 		ecmd->advertising = ADVERTISED_TP;
344 		break;
345 
346 	/* We represent CX4 as fibre in the absence of anything better */
347 	case MDIO_PMAPMD_CTRL2_10G_CX4:
348 	/* All the other defined modes are flavours of optical */
349 	default:
350 		ecmd->port = PORT_FIBRE;
351 		ecmd->supported = SUPPORTED_FIBRE;
352 		ecmd->advertising = ADVERTISED_FIBRE;
353 		break;
354 	}
355 
356 	if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
357 		ecmd->supported |= SUPPORTED_Autoneg;
358 		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
359 					 MDIO_MMDREG_CTRL1);
360 		if (reg & BMCR_ANENABLE) {
361 			ecmd->autoneg = AUTONEG_ENABLE;
362 			ecmd->advertising |=
363 				ADVERTISED_Autoneg |
364 				mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
365 				npage_adv;
366 		} else
367 			ecmd->autoneg = AUTONEG_DISABLE;
368 	} else
369 		ecmd->autoneg = AUTONEG_DISABLE;
370 
371 	if (ecmd->autoneg) {
372 		/* If AN is complete, report best common mode,
373 		 * otherwise report best advertised mode. */
374 		u32 modes = 0;
375 		if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
376 				       MDIO_MMDREG_STAT1) &
377 		    (1 << MDIO_AN_STATUS_AN_DONE_LBN))
378 			modes = (ecmd->advertising &
379 				 (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
380 				  npage_lpa));
381 		if (modes == 0)
382 			modes = ecmd->advertising;
383 
384 		if (modes & ADVERTISED_10000baseT_Full) {
385 			ecmd->speed = SPEED_10000;
386 			ecmd->duplex = DUPLEX_FULL;
387 		} else if (modes & (ADVERTISED_1000baseT_Full |
388 				    ADVERTISED_1000baseT_Half)) {
389 			ecmd->speed = SPEED_1000;
390 			ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
391 		} else if (modes & (ADVERTISED_100baseT_Full |
392 				    ADVERTISED_100baseT_Half)) {
393 			ecmd->speed = SPEED_100;
394 			ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
395 		} else {
396 			ecmd->speed = SPEED_10;
397 			ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
398 		}
399 	} else {
400 		/* Report forced settings */
401 		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
402 					 MDIO_MMDREG_CTRL1);
403 		ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) *
404 			       ((reg & BMCR_SPEED100) ? 100 : 10));
405 		ecmd->duplex = (reg & BMCR_FULLDPLX ||
406 				ecmd->speed == SPEED_10000);
407 	}
408 }
409 
410 /**
411  * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
412  * @efx:		Efx NIC
413  * @ecmd: 		New settings
414  */
mdio_clause45_set_settings(struct efx_nic * efx,struct ethtool_cmd * ecmd)415 int mdio_clause45_set_settings(struct efx_nic *efx,
416 			       struct ethtool_cmd *ecmd)
417 {
418 	int phy_id = efx->mii.phy_id;
419 	struct ethtool_cmd prev;
420 	u32 required;
421 	int reg;
422 
423 	efx->phy_op->get_settings(efx, &prev);
424 
425 	if (ecmd->advertising == prev.advertising &&
426 	    ecmd->speed == prev.speed &&
427 	    ecmd->duplex == prev.duplex &&
428 	    ecmd->port == prev.port &&
429 	    ecmd->autoneg == prev.autoneg)
430 		return 0;
431 
432 	/* We can only change these settings for -T PHYs */
433 	if (prev.port != PORT_TP || ecmd->port != PORT_TP)
434 		return -EINVAL;
435 
436 	/* Check that PHY supports these settings */
437 	if (ecmd->autoneg) {
438 		required = SUPPORTED_Autoneg;
439 	} else if (ecmd->duplex) {
440 		switch (ecmd->speed) {
441 		case SPEED_10:  required = SUPPORTED_10baseT_Full;  break;
442 		case SPEED_100: required = SUPPORTED_100baseT_Full; break;
443 		default:        return -EINVAL;
444 		}
445 	} else {
446 		switch (ecmd->speed) {
447 		case SPEED_10:  required = SUPPORTED_10baseT_Half;  break;
448 		case SPEED_100: required = SUPPORTED_100baseT_Half; break;
449 		default:        return -EINVAL;
450 		}
451 	}
452 	required |= ecmd->advertising;
453 	if (required & ~prev.supported)
454 		return -EINVAL;
455 
456 	if (ecmd->autoneg) {
457 		bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full
458 			    || EFX_WORKAROUND_13204(efx));
459 
460 		/* Set up the base page */
461 		reg = ADVERTISE_CSMA;
462 		if (ecmd->advertising & ADVERTISED_10baseT_Half)
463 			reg |= ADVERTISE_10HALF;
464 		if (ecmd->advertising & ADVERTISED_10baseT_Full)
465 			reg |= ADVERTISE_10FULL;
466 		if (ecmd->advertising & ADVERTISED_100baseT_Half)
467 			reg |= ADVERTISE_100HALF;
468 		if (ecmd->advertising & ADVERTISED_100baseT_Full)
469 			reg |= ADVERTISE_100FULL;
470 		if (xnp)
471 			reg |= ADVERTISE_RESV;
472 		else if (ecmd->advertising & (ADVERTISED_1000baseT_Half |
473 					      ADVERTISED_1000baseT_Full))
474 			reg |= ADVERTISE_NPAGE;
475 		reg |= efx_fc_advertise(efx->wanted_fc);
476 		mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
477 				    MDIO_AN_ADVERTISE, reg);
478 
479 		/* Set up the (extended) next page if necessary */
480 		if (efx->phy_op->set_npage_adv)
481 			efx->phy_op->set_npage_adv(efx, ecmd->advertising);
482 
483 		/* Enable and restart AN */
484 		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
485 					 MDIO_MMDREG_CTRL1);
486 		reg |= BMCR_ANENABLE;
487 		if (!(EFX_WORKAROUND_15195(efx) &&
488 		      LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
489 			reg |= BMCR_ANRESTART;
490 		if (xnp)
491 			reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
492 		else
493 			reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
494 		mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
495 				    MDIO_MMDREG_CTRL1, reg);
496 	} else {
497 		/* Disable AN */
498 		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
499 				       MDIO_MMDREG_CTRL1,
500 				       __ffs(BMCR_ANENABLE), false);
501 
502 		/* Set the basic control bits */
503 		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
504 					 MDIO_MMDREG_CTRL1);
505 		reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
506 			 0x003c);
507 		if (ecmd->speed == SPEED_100)
508 			reg |= BMCR_SPEED100;
509 		if (ecmd->duplex)
510 			reg |= BMCR_FULLDPLX;
511 		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
512 				    MDIO_MMDREG_CTRL1, reg);
513 	}
514 
515 	return 0;
516 }
517 
mdio_clause45_set_pause(struct efx_nic * efx)518 void mdio_clause45_set_pause(struct efx_nic *efx)
519 {
520 	int phy_id = efx->mii.phy_id;
521 	int reg;
522 
523 	if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
524 		/* Set pause capability advertising */
525 		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
526 					 MDIO_AN_ADVERTISE);
527 		reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
528 		reg |= efx_fc_advertise(efx->wanted_fc);
529 		mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
530 				    MDIO_AN_ADVERTISE, reg);
531 
532 		/* Restart auto-negotiation */
533 		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
534 					 MDIO_MMDREG_CTRL1);
535 		if (reg & BMCR_ANENABLE) {
536 			reg |= BMCR_ANRESTART;
537 			mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
538 					    MDIO_MMDREG_CTRL1, reg);
539 		}
540 	}
541 }
542 
mdio_clause45_get_pause(struct efx_nic * efx)543 enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx)
544 {
545 	int phy_id = efx->mii.phy_id;
546 	int lpa;
547 
548 	if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)))
549 		return efx->wanted_fc;
550 	lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA);
551 	return efx_fc_resolve(efx->wanted_fc, lpa);
552 }
553 
mdio_clause45_set_flag(struct efx_nic * efx,u8 prt,u8 dev,u16 addr,int bit,bool sense)554 void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
555 			    u16 addr, int bit, bool sense)
556 {
557 	int old_val = mdio_clause45_read(efx, prt, dev, addr);
558 	int new_val;
559 
560 	if (sense)
561 		new_val = old_val | (1 << bit);
562 	else
563 		new_val = old_val & ~(1 << bit);
564 	if (old_val != new_val)
565 		mdio_clause45_write(efx, prt, dev, addr, new_val);
566 }
567