jfs: Fix error handling in metapage_writepage()
[profile/ivi/kernel-x86-ivi.git] / drivers / net / sfc / mdio_10g.c
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
19 int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
20                             int spins, int spintime)
21 {
22         u32 ctrl;
23         int phy_id = port->mii.phy_id;
24
25         /* Catch callers passing values in the wrong units (or just silly) */
26         EFX_BUG_ON_PARANOID(spins * spintime >= 5000);
27
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. */
31         do {
32                 msleep(spintime);
33                 ctrl = mdio_clause45_read(port, phy_id, mmd, MDIO_MMDREG_CTRL1);
34                 spins--;
35
36         } while (spins && (ctrl & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)));
37
38         return spins ? spins : -ETIMEDOUT;
39 }
40
41 static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
42                                    int fault_fatal)
43 {
44         int status;
45         int phy_id = efx->mii.phy_id;
46
47         if (LOOPBACK_INTERNAL(efx))
48                 return 0;
49
50         if (mmd != MDIO_MMD_AN) {
51                 /* Read MMD STATUS2 to check it is responding. */
52                 status = mdio_clause45_read(efx, phy_id, mmd,
53                                             MDIO_MMDREG_STAT2);
54                 if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
55                      ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) !=
56                     MDIO_MMDREG_STAT2_PRESENT_VAL) {
57                         EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd);
58                         return -EIO;
59                 }
60         }
61
62         /* Read MMD STATUS 1 to check for fault. */
63         status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT1);
64         if ((status & (1 << MDIO_MMDREG_STAT1_FAULT_LBN)) != 0) {
65                 if (fault_fatal) {
66                         EFX_ERR(efx, "PHY MMD %d reporting fatal"
67                                 " fault: status %x\n", mmd, status);
68                         return -EIO;
69                 } else {
70                         EFX_LOG(efx, "PHY MMD %d reporting status"
71                                 " %x (expected)\n", mmd, status);
72                 }
73         }
74         return 0;
75 }
76
77 /* This ought to be ridiculous overkill. We expect it to fail rarely */
78 #define MDIO45_RESET_TIME       1000 /* ms */
79 #define MDIO45_RESET_ITERS      100
80
81 int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
82                                   unsigned int mmd_mask)
83 {
84         const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS;
85         int tries = MDIO45_RESET_ITERS;
86         int rc = 0;
87         int in_reset;
88
89         while (tries) {
90                 int mask = mmd_mask;
91                 int mmd = 0;
92                 int stat;
93                 in_reset = 0;
94                 while (mask) {
95                         if (mask & 1) {
96                                 stat = mdio_clause45_read(efx,
97                                                           efx->mii.phy_id,
98                                                           mmd,
99                                                           MDIO_MMDREG_CTRL1);
100                                 if (stat < 0) {
101                                         EFX_ERR(efx, "failed to read status of"
102                                                 " MMD %d\n", mmd);
103                                         return -EIO;
104                                 }
105                                 if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))
106                                         in_reset |= (1 << mmd);
107                         }
108                         mask = mask >> 1;
109                         mmd++;
110                 }
111                 if (!in_reset)
112                         break;
113                 tries--;
114                 msleep(spintime);
115         }
116         if (in_reset != 0) {
117                 EFX_ERR(efx, "not all MMDs came out of reset in time."
118                         " MMDs still in reset: %x\n", in_reset);
119                 rc = -ETIMEDOUT;
120         }
121         return rc;
122 }
123
124 int mdio_clause45_check_mmds(struct efx_nic *efx,
125                              unsigned int mmd_mask, unsigned int fatal_mask)
126 {
127         u32 devices;
128         int mmd = 0, probe_mmd;
129
130         /* Historically we have probed the PHYXS to find out what devices are
131          * present,but that doesn't work so well if the PHYXS isn't expected
132          * to exist, if so just find the first item in the list supplied. */
133         probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
134             __ffs(mmd_mask);
135         devices = (mdio_clause45_read(efx, efx->mii.phy_id,
136                                       probe_mmd, MDIO_MMDREG_DEVS0) |
137                    mdio_clause45_read(efx, efx->mii.phy_id,
138                                       probe_mmd, MDIO_MMDREG_DEVS1) << 16);
139
140         /* Check all the expected MMDs are present */
141         if (devices < 0) {
142                 EFX_ERR(efx, "failed to read devices present\n");
143                 return -EIO;
144         }
145         if ((devices & mmd_mask) != mmd_mask) {
146                 EFX_ERR(efx, "required MMDs not present: got %x, "
147                         "wanted %x\n", devices, mmd_mask);
148                 return -ENODEV;
149         }
150         EFX_TRACE(efx, "Devices present: %x\n", devices);
151
152         /* Check all required MMDs are responding and happy. */
153         while (mmd_mask) {
154                 if (mmd_mask & 1) {
155                         int fault_fatal = fatal_mask & 1;
156                         if (mdio_clause45_check_mmd(efx, mmd, fault_fatal))
157                                 return -EIO;
158                 }
159                 mmd_mask = mmd_mask >> 1;
160                 fatal_mask = fatal_mask >> 1;
161                 mmd++;
162         }
163
164         return 0;
165 }
166
167 bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
168 {
169         int phy_id = efx->mii.phy_id;
170         u32 reg;
171         bool ok = true;
172         int mmd = 0;
173
174         /* If the port is in loopback, then we should only consider a subset
175          * of mmd's */
176         if (LOOPBACK_INTERNAL(efx))
177                 return true;
178         else if (efx->loopback_mode == LOOPBACK_NETWORK)
179                 return false;
180         else if (efx_phy_mode_disabled(efx->phy_mode))
181                 return false;
182         else if (efx->loopback_mode == LOOPBACK_PHYXS) {
183                 mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
184                               MDIO_MMDREG_DEVS_PCS |
185                               MDIO_MMDREG_DEVS_PMAPMD |
186                               MDIO_MMDREG_DEVS_AN);
187                 if (!mmd_mask) {
188                         reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
189                                                  MDIO_PHYXS_STATUS2);
190                         return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
191                 }
192         } else if (efx->loopback_mode == LOOPBACK_PCS)
193                 mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
194                               MDIO_MMDREG_DEVS_PMAPMD |
195                               MDIO_MMDREG_DEVS_AN);
196         else if (efx->loopback_mode == LOOPBACK_PMAPMD)
197                 mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
198                               MDIO_MMDREG_DEVS_AN);
199
200         while (mmd_mask) {
201                 if (mmd_mask & 1) {
202                         /* Double reads because link state is latched, and a
203                          * read moves the current state into the register */
204                         reg = mdio_clause45_read(efx, phy_id,
205                                                  mmd, MDIO_MMDREG_STAT1);
206                         reg = mdio_clause45_read(efx, phy_id,
207                                                  mmd, MDIO_MMDREG_STAT1);
208                         ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
209                 }
210                 mmd_mask = (mmd_mask >> 1);
211                 mmd++;
212         }
213         return ok;
214 }
215
216 void mdio_clause45_transmit_disable(struct efx_nic *efx)
217 {
218         mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
219                                MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN,
220                                efx->phy_mode & PHY_MODE_TX_DISABLED);
221 }
222
223 void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
224 {
225         int phy_id = efx->mii.phy_id;
226
227         mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
228                                MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN,
229                                efx->loopback_mode == LOOPBACK_PMAPMD);
230         mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS,
231                                MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
232                                efx->loopback_mode == LOOPBACK_PCS);
233         mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
234                                MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
235                                efx->loopback_mode == LOOPBACK_NETWORK);
236 }
237
238 static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
239                                          int lpower, int mmd)
240 {
241         int phy = efx->mii.phy_id;
242         int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1);
243
244         EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n",
245                   mmd, lpower);
246
247         if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) {
248                 mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1,
249                                        MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower);
250         }
251 }
252
253 void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
254                                    int low_power, unsigned int mmd_mask)
255 {
256         int mmd = 0;
257         mmd_mask &= ~MDIO_MMDREG_DEVS_AN;
258         while (mmd_mask) {
259                 if (mmd_mask & 1)
260                         mdio_clause45_set_mmd_lpower(efx, low_power, mmd);
261                 mmd_mask = (mmd_mask >> 1);
262                 mmd++;
263         }
264 }
265
266 static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
267 {
268         int phy_id = efx->mii.phy_id;
269         u32 result = 0;
270         int reg;
271
272         reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr);
273         if (reg & ADVERTISE_10HALF)
274                 result |= ADVERTISED_10baseT_Half;
275         if (reg & ADVERTISE_10FULL)
276                 result |= ADVERTISED_10baseT_Full;
277         if (reg & ADVERTISE_100HALF)
278                 result |= ADVERTISED_100baseT_Half;
279         if (reg & ADVERTISE_100FULL)
280                 result |= ADVERTISED_100baseT_Full;
281         if (reg & LPA_RESV)
282                 result |= xnp;
283
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  */
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  */
311 void mdio_clause45_get_settings_ext(struct efx_nic *efx,
312                                     struct ethtool_cmd *ecmd,
313                                     u32 xnp, u32 xnp_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,
365                                                      MDIO_AN_ADVERTISE, xnp);
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 common = ecmd->advertising;
375                 if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
376                                        MDIO_MMDREG_STAT1) &
377                     (1 << MDIO_AN_STATUS_AN_DONE_LBN)) {
378                         common &= mdio_clause45_get_an(efx, MDIO_AN_LPA,
379                                                        xnp_lpa);
380                 }
381                 if (common & ADVERTISED_10000baseT_Full) {
382                         ecmd->speed = SPEED_10000;
383                         ecmd->duplex = DUPLEX_FULL;
384                 } else if (common & (ADVERTISED_1000baseT_Full |
385                                      ADVERTISED_1000baseT_Half)) {
386                         ecmd->speed = SPEED_1000;
387                         ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full);
388                 } else if (common & (ADVERTISED_100baseT_Full |
389                                      ADVERTISED_100baseT_Half)) {
390                         ecmd->speed = SPEED_100;
391                         ecmd->duplex = !!(common & ADVERTISED_100baseT_Full);
392                 } else {
393                         ecmd->speed = SPEED_10;
394                         ecmd->duplex = !!(common & ADVERTISED_10baseT_Full);
395                 }
396         } else {
397                 /* Report forced settings */
398                 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
399                                          MDIO_MMDREG_CTRL1);
400                 ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) *
401                                ((reg & BMCR_SPEED100) ? 100 : 10));
402                 ecmd->duplex = (reg & BMCR_FULLDPLX ||
403                                 ecmd->speed == SPEED_10000);
404         }
405 }
406
407 /**
408  * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
409  * @efx:                Efx NIC
410  * @ecmd:               New settings
411  */
412 int mdio_clause45_set_settings(struct efx_nic *efx,
413                                struct ethtool_cmd *ecmd)
414 {
415         int phy_id = efx->mii.phy_id;
416         struct ethtool_cmd prev;
417         u32 required;
418         int ctrl1_bits, reg;
419
420         efx->phy_op->get_settings(efx, &prev);
421
422         if (ecmd->advertising == prev.advertising &&
423             ecmd->speed == prev.speed &&
424             ecmd->duplex == prev.duplex &&
425             ecmd->port == prev.port &&
426             ecmd->autoneg == prev.autoneg)
427                 return 0;
428
429         /* We can only change these settings for -T PHYs */
430         if (prev.port != PORT_TP || ecmd->port != PORT_TP)
431                 return -EINVAL;
432
433         /* Check that PHY supports these settings and work out the
434          * basic control bits */
435         if (ecmd->duplex) {
436                 switch (ecmd->speed) {
437                 case SPEED_10:
438                         ctrl1_bits = BMCR_FULLDPLX;
439                         required = SUPPORTED_10baseT_Full;
440                         break;
441                 case SPEED_100:
442                         ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX;
443                         required = SUPPORTED_100baseT_Full;
444                         break;
445                 case SPEED_1000:
446                         ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX;
447                         required = SUPPORTED_1000baseT_Full;
448                         break;
449                 case SPEED_10000:
450                         ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 |
451                                       BMCR_FULLDPLX);
452                         required = SUPPORTED_10000baseT_Full;
453                         break;
454                 default:
455                         return -EINVAL;
456                 }
457         } else {
458                 switch (ecmd->speed) {
459                 case SPEED_10:
460                         ctrl1_bits = 0;
461                         required = SUPPORTED_10baseT_Half;
462                         break;
463                 case SPEED_100:
464                         ctrl1_bits = BMCR_SPEED100;
465                         required = SUPPORTED_100baseT_Half;
466                         break;
467                 case SPEED_1000:
468                         ctrl1_bits = BMCR_SPEED1000;
469                         required = SUPPORTED_1000baseT_Half;
470                         break;
471                 default:
472                         return -EINVAL;
473                 }
474         }
475         if (ecmd->autoneg)
476                 required |= SUPPORTED_Autoneg;
477         required |= ecmd->advertising;
478         if (required & ~prev.supported)
479                 return -EINVAL;
480
481         /* Set the basic control bits */
482         reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
483                                  MDIO_MMDREG_CTRL1);
484         reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c);
485         reg |= ctrl1_bits;
486         mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1,
487                             reg);
488
489         /* Set the AN registers */
490         if (ecmd->autoneg != prev.autoneg ||
491             ecmd->advertising != prev.advertising) {
492                 bool xnp = false;
493
494                 if (efx->phy_op->set_xnp_advertise)
495                         xnp = efx->phy_op->set_xnp_advertise(efx,
496                                                              ecmd->advertising);
497
498                 if (ecmd->autoneg) {
499                         reg = 0;
500                         if (ecmd->advertising & ADVERTISED_10baseT_Half)
501                                 reg |= ADVERTISE_10HALF;
502                         if (ecmd->advertising & ADVERTISED_10baseT_Full)
503                                 reg |= ADVERTISE_10FULL;
504                         if (ecmd->advertising & ADVERTISED_100baseT_Half)
505                                 reg |= ADVERTISE_100HALF;
506                         if (ecmd->advertising & ADVERTISED_100baseT_Full)
507                                 reg |= ADVERTISE_100FULL;
508                         if (xnp)
509                                 reg |= ADVERTISE_RESV;
510                         mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
511                                             MDIO_AN_ADVERTISE, reg);
512                 }
513
514                 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
515                                          MDIO_MMDREG_CTRL1);
516                 if (ecmd->autoneg)
517                         reg |= BMCR_ANENABLE | BMCR_ANRESTART;
518                 else
519                         reg &= ~BMCR_ANENABLE;
520                 if (xnp)
521                         reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
522                 else
523                         reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
524                 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
525                                     MDIO_MMDREG_CTRL1, reg);
526         }
527
528         return 0;
529 }
530
531 void mdio_clause45_set_pause(struct efx_nic *efx)
532 {
533         int phy_id = efx->mii.phy_id;
534         int reg;
535
536         if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
537                 /* Set pause capability advertising */
538                 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
539                                          MDIO_AN_ADVERTISE);
540                 reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
541                 reg |= efx_fc_advertise(efx->wanted_fc);
542                 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
543                                     MDIO_AN_ADVERTISE, reg);
544
545                 /* Restart auto-negotiation */
546                 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
547                                          MDIO_MMDREG_CTRL1);
548                 if (reg & BMCR_ANENABLE) {
549                         reg |= BMCR_ANRESTART;
550                         mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
551                                             MDIO_MMDREG_CTRL1, reg);
552                 }
553         }
554 }
555
556 enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx)
557 {
558         int phy_id = efx->mii.phy_id;
559         int lpa;
560
561         if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)))
562                 return efx->wanted_fc;
563         lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA);
564         return efx_fc_resolve(efx->wanted_fc, lpa);
565 }
566
567 void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
568                             u16 addr, int bit, bool sense)
569 {
570         int old_val = mdio_clause45_read(efx, prt, dev, addr);
571         int new_val;
572
573         if (sense)
574                 new_val = old_val | (1 << bit);
575         else
576                 new_val = old_val & ~(1 << bit);
577         if (old_val != new_val)
578                 mdio_clause45_write(efx, prt, dev, addr, new_val);
579 }