Commit 28011cf19b75df9d3f35489a7599a97ec0b3f1a0

Authored by Matt Carlson
Committed by David S. Miller
1 parent f85fa27913

net: Add ethtool to mii advertisment conversion helpers

Translating between ethtool advertisement settings and MII
advertisements are common operations for ethernet drivers.  This patch
adds a set of helper functions that implements the conversion.  The
patch then modifies a couple of the drivers to use the new functions.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 6 changed files with 197 additions and 120 deletions Side-by-side Diff

drivers/net/ethernet/broadcom/bnx2.c
... ... @@ -2064,20 +2064,11 @@
2064 2064 bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg);
2065 2065 adv1000_reg &= PHY_ALL_1000_SPEED;
2066 2066  
2067   - if (bp->advertising & ADVERTISED_10baseT_Half)
2068   - new_adv_reg |= ADVERTISE_10HALF;
2069   - if (bp->advertising & ADVERTISED_10baseT_Full)
2070   - new_adv_reg |= ADVERTISE_10FULL;
2071   - if (bp->advertising & ADVERTISED_100baseT_Half)
2072   - new_adv_reg |= ADVERTISE_100HALF;
2073   - if (bp->advertising & ADVERTISED_100baseT_Full)
2074   - new_adv_reg |= ADVERTISE_100FULL;
2075   - if (bp->advertising & ADVERTISED_1000baseT_Full)
2076   - new_adv1000_reg |= ADVERTISE_1000FULL;
2077   -
  2067 + new_adv_reg = ethtool_adv_to_mii_100bt(bp->advertising);
2078 2068 new_adv_reg |= ADVERTISE_CSMA;
2079   -
2080 2069 new_adv_reg |= bnx2_phy_get_pause_adv(bp);
  2070 +
  2071 + new_adv1000_reg |= ethtool_adv_to_mii_1000T(bp->advertising);
2081 2072  
2082 2073 if ((adv1000_reg != new_adv1000_reg) ||
2083 2074 (adv_reg != new_adv_reg) ||
drivers/net/ethernet/broadcom/tg3.c
... ... @@ -3594,15 +3594,7 @@
3594 3594 u32 val, new_adv;
3595 3595  
3596 3596 new_adv = ADVERTISE_CSMA;
3597   - if (advertise & ADVERTISED_10baseT_Half)
3598   - new_adv |= ADVERTISE_10HALF;
3599   - if (advertise & ADVERTISED_10baseT_Full)
3600   - new_adv |= ADVERTISE_10FULL;
3601   - if (advertise & ADVERTISED_100baseT_Half)
3602   - new_adv |= ADVERTISE_100HALF;
3603   - if (advertise & ADVERTISED_100baseT_Full)
3604   - new_adv |= ADVERTISE_100FULL;
3605   -
  3597 + new_adv |= ethtool_adv_to_mii_100bt(advertise);
3606 3598 new_adv |= tg3_advert_flowctrl_1000T(flowctrl);
3607 3599  
3608 3600 err = tg3_writephy(tp, MII_ADVERTISE, new_adv);
... ... @@ -3612,11 +3604,7 @@
3612 3604 if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
3613 3605 goto done;
3614 3606  
3615   - new_adv = 0;
3616   - if (advertise & ADVERTISED_1000baseT_Half)
3617   - new_adv |= ADVERTISE_1000HALF;
3618   - if (advertise & ADVERTISED_1000baseT_Full)
3619   - new_adv |= ADVERTISE_1000FULL;
  3607 + new_adv = ethtool_adv_to_mii_1000T(advertise);
3620 3608  
3621 3609 if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
3622 3610 tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
... ... @@ -3790,14 +3778,7 @@
3790 3778 {
3791 3779 u32 adv_reg, all_mask = 0;
3792 3780  
3793   - if (mask & ADVERTISED_10baseT_Half)
3794   - all_mask |= ADVERTISE_10HALF;
3795   - if (mask & ADVERTISED_10baseT_Full)
3796   - all_mask |= ADVERTISE_10FULL;
3797   - if (mask & ADVERTISED_100baseT_Half)
3798   - all_mask |= ADVERTISE_100HALF;
3799   - if (mask & ADVERTISED_100baseT_Full)
3800   - all_mask |= ADVERTISE_100FULL;
  3781 + all_mask = ethtool_adv_to_mii_100bt(mask);
3801 3782  
3802 3783 if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg))
3803 3784 return 0;
... ... @@ -3808,11 +3789,7 @@
3808 3789 if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
3809 3790 u32 tg3_ctrl;
3810 3791  
3811   - all_mask = 0;
3812   - if (mask & ADVERTISED_1000baseT_Half)
3813   - all_mask |= ADVERTISE_1000HALF;
3814   - if (mask & ADVERTISED_1000baseT_Full)
3815   - all_mask |= ADVERTISE_1000FULL;
  3792 + all_mask = ethtool_adv_to_mii_1000T(mask);
3816 3793  
3817 3794 if (tg3_readphy(tp, MII_CTRL1000, &tg3_ctrl))
3818 3795 return 0;
3819 3796  
3820 3797  
3821 3798  
... ... @@ -4903,23 +4880,19 @@
4903 4880 (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) {
4904 4881 /* do nothing, just check for link up at the end */
4905 4882 } else if (tp->link_config.autoneg == AUTONEG_ENABLE) {
4906   - u32 adv, new_adv;
  4883 + u32 adv, newadv;
4907 4884  
4908 4885 err |= tg3_readphy(tp, MII_ADVERTISE, &adv);
4909   - new_adv = adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF |
4910   - ADVERTISE_1000XPAUSE |
4911   - ADVERTISE_1000XPSE_ASYM |
4912   - ADVERTISE_SLCT);
  4886 + newadv = adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF |
  4887 + ADVERTISE_1000XPAUSE |
  4888 + ADVERTISE_1000XPSE_ASYM |
  4889 + ADVERTISE_SLCT);
4913 4890  
4914   - new_adv |= tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
  4891 + newadv |= tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
  4892 + newadv |= ethtool_adv_to_mii_1000X(tp->link_config.advertising);
4915 4893  
4916   - if (tp->link_config.advertising & ADVERTISED_1000baseT_Half)
4917   - new_adv |= ADVERTISE_1000XHALF;
4918   - if (tp->link_config.advertising & ADVERTISED_1000baseT_Full)
4919   - new_adv |= ADVERTISE_1000XFULL;
4920   -
4921   - if ((new_adv != adv) || !(bmcr & BMCR_ANENABLE)) {
4922   - tg3_writephy(tp, MII_ADVERTISE, new_adv);
  4894 + if ((newadv != adv) || !(bmcr & BMCR_ANENABLE)) {
  4895 + tg3_writephy(tp, MII_ADVERTISE, newadv);
4923 4896 bmcr |= BMCR_ANENABLE | BMCR_ANRESTART;
4924 4897 tg3_writephy(tp, MII_BMCR, bmcr);
4925 4898  
drivers/net/ethernet/sun/niu.c
... ... @@ -1151,19 +1151,8 @@
1151 1151 supported |= SUPPORTED_1000baseT_Full;
1152 1152 lp->supported = supported;
1153 1153  
1154   - advertising = 0;
1155   - if (advert & ADVERTISE_10HALF)
1156   - advertising |= ADVERTISED_10baseT_Half;
1157   - if (advert & ADVERTISE_10FULL)
1158   - advertising |= ADVERTISED_10baseT_Full;
1159   - if (advert & ADVERTISE_100HALF)
1160   - advertising |= ADVERTISED_100baseT_Half;
1161   - if (advert & ADVERTISE_100FULL)
1162   - advertising |= ADVERTISED_100baseT_Full;
1163   - if (ctrl1000 & ADVERTISE_1000HALF)
1164   - advertising |= ADVERTISED_1000baseT_Half;
1165   - if (ctrl1000 & ADVERTISE_1000FULL)
1166   - advertising |= ADVERTISED_1000baseT_Full;
  1154 + advertising = mii_adv_to_ethtool_100bt(advert);
  1155 + advertising |= mii_adv_to_ethtool_1000T(ctrl1000);
1167 1156  
1168 1157 if (bmcr & BMCR_ANENABLE) {
1169 1158 int neg, neg1000;
... ... @@ -41,20 +41,8 @@
41 41 advert = mii->mdio_read(mii->dev, mii->phy_id, addr);
42 42 if (advert & LPA_LPACK)
43 43 result |= ADVERTISED_Autoneg;
44   - if (advert & ADVERTISE_10HALF)
45   - result |= ADVERTISED_10baseT_Half;
46   - if (advert & ADVERTISE_10FULL)
47   - result |= ADVERTISED_10baseT_Full;
48   - if (advert & ADVERTISE_100HALF)
49   - result |= ADVERTISED_100baseT_Half;
50   - if (advert & ADVERTISE_100FULL)
51   - result |= ADVERTISED_100baseT_Full;
52   - if (advert & ADVERTISE_PAUSE_CAP)
53   - result |= ADVERTISED_Pause;
54   - if (advert & ADVERTISE_PAUSE_ASYM)
55   - result |= ADVERTISED_Asym_Pause;
56 44  
57   - return result;
  45 + return result | mii_adv_to_ethtool_100bt(advert);
58 46 }
59 47  
60 48 /**
61 49  
... ... @@ -104,19 +92,13 @@
104 92 ecmd->autoneg = AUTONEG_ENABLE;
105 93  
106 94 ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE);
107   - if (ctrl1000 & ADVERTISE_1000HALF)
108   - ecmd->advertising |= ADVERTISED_1000baseT_Half;
109   - if (ctrl1000 & ADVERTISE_1000FULL)
110   - ecmd->advertising |= ADVERTISED_1000baseT_Full;
  95 + if (mii->supports_gmii)
  96 + ecmd->advertising |= mii_adv_to_ethtool_1000T(ctrl1000);
111 97  
112 98 if (bmsr & BMSR_ANEGCOMPLETE) {
113 99 ecmd->lp_advertising = mii_get_an(mii, MII_LPA);
114   - if (stat1000 & LPA_1000HALF)
115   - ecmd->lp_advertising |=
116   - ADVERTISED_1000baseT_Half;
117   - if (stat1000 & LPA_1000FULL)
118   - ecmd->lp_advertising |=
119   - ADVERTISED_1000baseT_Full;
  100 + ecmd->lp_advertising |=
  101 + mii_lpa_to_ethtool_1000T(stat1000);
120 102 } else {
121 103 ecmd->lp_advertising = 0;
122 104 }
... ... @@ -204,20 +186,10 @@
204 186 advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
205 187 tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
206 188 }
207   - if (ecmd->advertising & ADVERTISED_10baseT_Half)
208   - tmp |= ADVERTISE_10HALF;
209   - if (ecmd->advertising & ADVERTISED_10baseT_Full)
210   - tmp |= ADVERTISE_10FULL;
211   - if (ecmd->advertising & ADVERTISED_100baseT_Half)
212   - tmp |= ADVERTISE_100HALF;
213   - if (ecmd->advertising & ADVERTISED_100baseT_Full)
214   - tmp |= ADVERTISE_100FULL;
215   - if (mii->supports_gmii) {
216   - if (ecmd->advertising & ADVERTISED_1000baseT_Half)
217   - tmp2 |= ADVERTISE_1000HALF;
218   - if (ecmd->advertising & ADVERTISED_1000baseT_Full)
219   - tmp2 |= ADVERTISE_1000FULL;
220   - }
  189 + tmp |= ethtool_adv_to_mii_100bt(ecmd->advertising);
  190 +
  191 + if (mii->supports_gmii)
  192 + tmp2 |= ethtool_adv_to_mii_1000T(ecmd->advertising);
221 193 if (advert != tmp) {
222 194 mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
223 195 mii->advertising = tmp;
drivers/net/phy/phy_device.c
... ... @@ -563,20 +563,9 @@
563 563 if (adv < 0)
564 564 return adv;
565 565  
566   - adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
  566 + adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
567 567 ADVERTISE_PAUSE_ASYM);
568   - if (advertise & ADVERTISED_10baseT_Half)
569   - adv |= ADVERTISE_10HALF;
570   - if (advertise & ADVERTISED_10baseT_Full)
571   - adv |= ADVERTISE_10FULL;
572   - if (advertise & ADVERTISED_100baseT_Half)
573   - adv |= ADVERTISE_100HALF;
574   - if (advertise & ADVERTISED_100baseT_Full)
575   - adv |= ADVERTISE_100FULL;
576   - if (advertise & ADVERTISED_Pause)
577   - adv |= ADVERTISE_PAUSE_CAP;
578   - if (advertise & ADVERTISED_Asym_Pause)
579   - adv |= ADVERTISE_PAUSE_ASYM;
  568 + adv |= ethtool_adv_to_mii_100bt(advertise);
580 569  
581 570 if (adv != oldadv) {
582 571 err = phy_write(phydev, MII_ADVERTISE, adv);
... ... @@ -595,10 +584,7 @@
595 584 return adv;
596 585  
597 586 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
598   - if (advertise & SUPPORTED_1000baseT_Half)
599   - adv |= ADVERTISE_1000HALF;
600   - if (advertise & SUPPORTED_1000baseT_Full)
601   - adv |= ADVERTISE_1000FULL;
  587 + adv |= ethtool_adv_to_mii_1000T(advertise);
602 588  
603 589 if (adv != oldadv) {
604 590 err = phy_write(phydev, MII_CTRL1000, adv);
... ... @@ -9,6 +9,7 @@
9 9 #define __LINUX_MII_H__
10 10  
11 11 #include <linux/types.h>
  12 +#include <linux/ethtool.h>
12 13  
13 14 /* Generic MII registers. */
14 15 #define MII_BMCR 0x00 /* Basic mode control register */
... ... @@ -237,6 +238,171 @@
237 238 if (mii_nway_result(negotiated) & LPA_DUPLEX)
238 239 return 1;
239 240 return 0;
  241 +}
  242 +
  243 +/**
  244 + * ethtool_adv_to_mii_100bt
  245 + * @ethadv: the ethtool advertisement settings
  246 + *
  247 + * A small helper function that translates ethtool advertisement
  248 + * settings to phy autonegotiation advertisements for the
  249 + * MII_ADVERTISE register.
  250 + */
  251 +static inline u32 ethtool_adv_to_mii_100bt(u32 ethadv)
  252 +{
  253 + u32 result = 0;
  254 +
  255 + if (ethadv & ADVERTISED_10baseT_Half)
  256 + result |= ADVERTISE_10HALF;
  257 + if (ethadv & ADVERTISED_10baseT_Full)
  258 + result |= ADVERTISE_10FULL;
  259 + if (ethadv & ADVERTISED_100baseT_Half)
  260 + result |= ADVERTISE_100HALF;
  261 + if (ethadv & ADVERTISED_100baseT_Full)
  262 + result |= ADVERTISE_100FULL;
  263 + if (ethadv & ADVERTISED_Pause)
  264 + result |= ADVERTISE_PAUSE_CAP;
  265 + if (ethadv & ADVERTISED_Asym_Pause)
  266 + result |= ADVERTISE_PAUSE_ASYM;
  267 +
  268 + return result;
  269 +}
  270 +
  271 +/**
  272 + * mii_adv_to_ethtool_100bt
  273 + * @adv: value of the MII_ADVERTISE register
  274 + *
  275 + * A small helper function that translates MII_ADVERTISE bits
  276 + * to ethtool advertisement settings.
  277 + */
  278 +static inline u32 mii_adv_to_ethtool_100bt(u32 adv)
  279 +{
  280 + u32 result = 0;
  281 +
  282 + if (adv & ADVERTISE_10HALF)
  283 + result |= ADVERTISED_10baseT_Half;
  284 + if (adv & ADVERTISE_10FULL)
  285 + result |= ADVERTISED_10baseT_Full;
  286 + if (adv & ADVERTISE_100HALF)
  287 + result |= ADVERTISED_100baseT_Half;
  288 + if (adv & ADVERTISE_100FULL)
  289 + result |= ADVERTISED_100baseT_Full;
  290 + if (adv & ADVERTISE_PAUSE_CAP)
  291 + result |= ADVERTISED_Pause;
  292 + if (adv & ADVERTISE_PAUSE_ASYM)
  293 + result |= ADVERTISED_Asym_Pause;
  294 +
  295 + return result;
  296 +}
  297 +
  298 +/**
  299 + * ethtool_adv_to_mii_1000T
  300 + * @ethadv: the ethtool advertisement settings
  301 + *
  302 + * A small helper function that translates ethtool advertisement
  303 + * settings to phy autonegotiation advertisements for the
  304 + * MII_CTRL1000 register when in 1000T mode.
  305 + */
  306 +static inline u32 ethtool_adv_to_mii_1000T(u32 ethadv)
  307 +{
  308 + u32 result = 0;
  309 +
  310 + if (ethadv & ADVERTISED_1000baseT_Half)
  311 + result |= ADVERTISE_1000HALF;
  312 + if (ethadv & ADVERTISED_1000baseT_Full)
  313 + result |= ADVERTISE_1000FULL;
  314 +
  315 + return result;
  316 +}
  317 +
  318 +/**
  319 + * mii_adv_to_ethtool_1000T
  320 + * @adv: value of the MII_CTRL1000 register
  321 + *
  322 + * A small helper function that translates MII_CTRL1000
  323 + * bits, when in 1000Base-T mode, to ethtool
  324 + * advertisement settings.
  325 + */
  326 +static inline u32 mii_adv_to_ethtool_1000T(u32 adv)
  327 +{
  328 + u32 result = 0;
  329 +
  330 + if (adv & ADVERTISE_1000HALF)
  331 + result |= ADVERTISED_1000baseT_Half;
  332 + if (adv & ADVERTISE_1000FULL)
  333 + result |= ADVERTISED_1000baseT_Full;
  334 +
  335 + return result;
  336 +}
  337 +
  338 +#define mii_lpa_to_ethtool_100bt(lpa) mii_adv_to_ethtool_100bt(lpa)
  339 +
  340 +/**
  341 + * mii_lpa_to_ethtool_1000T
  342 + * @adv: value of the MII_STAT1000 register
  343 + *
  344 + * A small helper function that translates MII_STAT1000
  345 + * bits, when in 1000Base-T mode, to ethtool
  346 + * advertisement settings.
  347 + */
  348 +static inline u32 mii_lpa_to_ethtool_1000T(u32 lpa)
  349 +{
  350 + u32 result = 0;
  351 +
  352 + if (lpa & LPA_1000HALF)
  353 + result |= ADVERTISED_1000baseT_Half;
  354 + if (lpa & LPA_1000FULL)
  355 + result |= ADVERTISED_1000baseT_Full;
  356 +
  357 + return result;
  358 +}
  359 +
  360 +/**
  361 + * ethtool_adv_to_mii_1000X
  362 + * @ethadv: the ethtool advertisement settings
  363 + *
  364 + * A small helper function that translates ethtool advertisement
  365 + * settings to phy autonegotiation advertisements for the
  366 + * MII_CTRL1000 register when in 1000Base-X mode.
  367 + */
  368 +static inline u32 ethtool_adv_to_mii_1000X(u32 ethadv)
  369 +{
  370 + u32 result = 0;
  371 +
  372 + if (ethadv & ADVERTISED_1000baseT_Half)
  373 + result |= ADVERTISE_1000XHALF;
  374 + if (ethadv & ADVERTISED_1000baseT_Full)
  375 + result |= ADVERTISE_1000XFULL;
  376 + if (ethadv & ADVERTISED_Pause)
  377 + result |= ADVERTISE_1000XPAUSE;
  378 + if (ethadv & ADVERTISED_Asym_Pause)
  379 + result |= ADVERTISE_1000XPSE_ASYM;
  380 +
  381 + return result;
  382 +}
  383 +
  384 +/**
  385 + * mii_adv_to_ethtool_1000X
  386 + * @adv: value of the MII_CTRL1000 register
  387 + *
  388 + * A small helper function that translates MII_CTRL1000
  389 + * bits, when in 1000Base-X mode, to ethtool
  390 + * advertisement settings.
  391 + */
  392 +static inline u32 mii_adv_to_ethtool_1000X(u32 adv)
  393 +{
  394 + u32 result = 0;
  395 +
  396 + if (adv & ADVERTISE_1000XHALF)
  397 + result |= ADVERTISED_1000baseT_Half;
  398 + if (adv & ADVERTISE_1000XFULL)
  399 + result |= ADVERTISED_1000baseT_Full;
  400 + if (adv & ADVERTISE_1000XPAUSE)
  401 + result |= ADVERTISED_Pause;
  402 + if (adv & ADVERTISE_1000XPSE_ASYM)
  403 + result |= ADVERTISED_Asym_Pause;
  404 +
  405 + return result;
240 406 }
241 407  
242 408 /**