diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2009-04-29 04:20:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-29 20:32:37 -0400 |
commit | 3f926da82f128c68c479247b1771729b9487502a (patch) | |
tree | c55d11e34dc361895a618afa128077176915dc06 /drivers/net/sfc | |
parent | af2a3eac2fe6a6d8e9fdf6927284b34466a7d808 (diff) |
sfc: Use generic MDIO flow control auto-negotiation functions
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r-- | drivers/net/sfc/ethtool.c | 3 | ||||
-rw-r--r-- | drivers/net/sfc/mdio_10g.c | 22 | ||||
-rw-r--r-- | drivers/net/sfc/mdio_10g.h | 3 | ||||
-rw-r--r-- | drivers/net/sfc/net_driver.h | 26 | ||||
-rw-r--r-- | drivers/net/sfc/tenxpress.c | 1 |
5 files changed, 7 insertions, 48 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 1c7b6849fe01..997ea2a3d53f 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -711,7 +711,8 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, | |||
711 | mutex_lock(&efx->mac_lock); | 711 | mutex_lock(&efx->mac_lock); |
712 | 712 | ||
713 | efx->wanted_fc = wanted_fc; | 713 | efx->wanted_fc = wanted_fc; |
714 | efx_mdio_set_pause(efx); | 714 | if (efx->phy_op->mmds & MDIO_DEVS_AN) |
715 | mdio45_ethtool_spauseparam_an(&efx->mdio, pause); | ||
715 | __efx_reconfigure_port(efx); | 716 | __efx_reconfigure_port(efx); |
716 | 717 | ||
717 | mutex_unlock(&efx->mac_lock); | 718 | mutex_unlock(&efx->mac_lock); |
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 11c231a1f875..6c33459f9ea9 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c | |||
@@ -304,7 +304,7 @@ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | |||
304 | else if (ecmd->advertising & (ADVERTISED_1000baseT_Half | | 304 | else if (ecmd->advertising & (ADVERTISED_1000baseT_Half | |
305 | ADVERTISED_1000baseT_Full)) | 305 | ADVERTISED_1000baseT_Full)) |
306 | reg |= ADVERTISE_NPAGE; | 306 | reg |= ADVERTISE_NPAGE; |
307 | reg |= efx_fc_advertise(efx->wanted_fc); | 307 | reg |= mii_advertise_flowctrl(efx->wanted_fc); |
308 | efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); | 308 | efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); |
309 | 309 | ||
310 | /* Set up the (extended) next page if necessary */ | 310 | /* Set up the (extended) next page if necessary */ |
@@ -340,26 +340,6 @@ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | |||
340 | return 0; | 340 | return 0; |
341 | } | 341 | } |
342 | 342 | ||
343 | void efx_mdio_set_pause(struct efx_nic *efx) | ||
344 | { | ||
345 | int reg; | ||
346 | |||
347 | if (efx->phy_op->mmds & MDIO_DEVS_AN) { | ||
348 | /* Set pause capability advertising */ | ||
349 | reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE); | ||
350 | reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); | ||
351 | reg |= efx_fc_advertise(efx->wanted_fc); | ||
352 | efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); | ||
353 | |||
354 | /* Restart auto-negotiation */ | ||
355 | reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1); | ||
356 | if (reg & MDIO_AN_CTRL1_ENABLE) { | ||
357 | reg |= MDIO_AN_CTRL1_RESTART; | ||
358 | efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg); | ||
359 | } | ||
360 | } | ||
361 | } | ||
362 | |||
363 | enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx) | 343 | enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx) |
364 | { | 344 | { |
365 | int lpa; | 345 | int lpa; |
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index ea4587d93698..6b14421a7444 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h | |||
@@ -87,9 +87,6 @@ extern void efx_mdio_set_mmds_lpower(struct efx_nic *efx, | |||
87 | /* Set (some of) the PHY settings over MDIO */ | 87 | /* Set (some of) the PHY settings over MDIO */ |
88 | extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd); | 88 | extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd); |
89 | 89 | ||
90 | /* Set pause parameters to be advertised through AN (if available) */ | ||
91 | extern void efx_mdio_set_pause(struct efx_nic *efx); | ||
92 | |||
93 | /* Get pause parameters from AN if available (otherwise return | 90 | /* Get pause parameters from AN if available (otherwise return |
94 | * requested pause parameters) | 91 | * requested pause parameters) |
95 | */ | 92 | */ |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 457e2f1d4b43..5eabede9ac18 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -495,8 +495,8 @@ struct efx_nic; | |||
495 | 495 | ||
496 | /* Pseudo bit-mask flow control field */ | 496 | /* Pseudo bit-mask flow control field */ |
497 | enum efx_fc_type { | 497 | enum efx_fc_type { |
498 | EFX_FC_RX = 1, | 498 | EFX_FC_RX = FLOW_CTRL_RX, |
499 | EFX_FC_TX = 2, | 499 | EFX_FC_TX = FLOW_CTRL_TX, |
500 | EFX_FC_AUTO = 4, | 500 | EFX_FC_AUTO = 4, |
501 | }; | 501 | }; |
502 | 502 | ||
@@ -506,33 +506,15 @@ enum efx_mac_type { | |||
506 | EFX_XMAC = 2, | 506 | EFX_XMAC = 2, |
507 | }; | 507 | }; |
508 | 508 | ||
509 | static inline unsigned int efx_fc_advertise(enum efx_fc_type wanted_fc) | ||
510 | { | ||
511 | unsigned int adv = 0; | ||
512 | if (wanted_fc & EFX_FC_RX) | ||
513 | adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | ||
514 | if (wanted_fc & EFX_FC_TX) | ||
515 | adv ^= ADVERTISE_PAUSE_ASYM; | ||
516 | return adv; | ||
517 | } | ||
518 | |||
519 | static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc, | 509 | static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc, |
520 | unsigned int lpa) | 510 | unsigned int lpa) |
521 | { | 511 | { |
522 | unsigned int adv = efx_fc_advertise(wanted_fc); | 512 | BUILD_BUG_ON(EFX_FC_AUTO & (EFX_FC_RX | EFX_FC_TX)); |
523 | 513 | ||
524 | if (!(wanted_fc & EFX_FC_AUTO)) | 514 | if (!(wanted_fc & EFX_FC_AUTO)) |
525 | return wanted_fc; | 515 | return wanted_fc; |
526 | 516 | ||
527 | if (adv & lpa & ADVERTISE_PAUSE_CAP) | 517 | return mii_resolve_flowctrl_fdx(mii_advertise_flowctrl(wanted_fc), lpa); |
528 | return EFX_FC_RX | EFX_FC_TX; | ||
529 | if (adv & lpa & ADVERTISE_PAUSE_ASYM) { | ||
530 | if (adv & ADVERTISE_PAUSE_CAP) | ||
531 | return EFX_FC_RX; | ||
532 | if (lpa & ADVERTISE_PAUSE_CAP) | ||
533 | return EFX_FC_TX; | ||
534 | } | ||
535 | return 0; | ||
536 | } | 518 | } |
537 | 519 | ||
538 | /** | 520 | /** |
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 403f7d70c223..0421190db7de 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -343,7 +343,6 @@ static int tenxpress_phy_init(struct efx_nic *efx) | |||
343 | rc = tenxpress_init(efx); | 343 | rc = tenxpress_init(efx); |
344 | if (rc < 0) | 344 | if (rc < 0) |
345 | goto fail; | 345 | goto fail; |
346 | efx_mdio_set_pause(efx); | ||
347 | 346 | ||
348 | if (efx->phy_type == PHY_TYPE_SFT9001B) { | 347 | if (efx->phy_type == PHY_TYPE_SFT9001B) { |
349 | rc = device_create_file(&efx->pci_dev->dev, | 348 | rc = device_create_file(&efx->pci_dev->dev, |