aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/tenxpress.c
diff options
context:
space:
mode:
authorSteve Hodgson <shodgson@solarflare.com>2009-11-28 00:34:05 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-29 02:58:50 -0500
commitfdaa9aed21c8c8b529f3c94a5ffa138bf3360b75 (patch)
tree6db7fd76481b3f87f0f4e94e1bd55c0624fba296 /drivers/net/sfc/tenxpress.c
parent5e7565930524410f097f5b04f8aba663089a6ffc (diff)
sfc: Simplify PHY polling
Falcon can generate events for LASI interrupts from the PHY, but in practice we have never implemented this in reference designs. Instead we have polled, inserted the appropriate events, and then handled the events later. This is a waste of time and code. Instead, make PHY poll functions update the link state synchronously and report whether it changed. We can still make use of the LASI registers as a shortcut on the SFT9001. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/tenxpress.c')
-rw-r--r--drivers/net/sfc/tenxpress.c69
1 files changed, 27 insertions, 42 deletions
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index e6232fe26072..1bd79650a00f 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -503,7 +503,6 @@ static void tenxpress_low_power(struct efx_nic *efx)
503static void tenxpress_phy_reconfigure(struct efx_nic *efx) 503static void tenxpress_phy_reconfigure(struct efx_nic *efx)
504{ 504{
505 struct tenxpress_phy_data *phy_data = efx->phy_data; 505 struct tenxpress_phy_data *phy_data = efx->phy_data;
506 struct efx_link_state *link_state = &efx->link_state;
507 struct ethtool_cmd ecmd; 506 struct ethtool_cmd ecmd;
508 bool phy_mode_change, loop_reset; 507 bool phy_mode_change, loop_reset;
509 508
@@ -544,53 +543,41 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
544 543
545 phy_data->loopback_mode = efx->loopback_mode; 544 phy_data->loopback_mode = efx->loopback_mode;
546 phy_data->phy_mode = efx->phy_mode; 545 phy_data->phy_mode = efx->phy_mode;
547
548 if (efx->phy_type == PHY_TYPE_SFX7101) {
549 link_state->speed = 10000;
550 link_state->fd = true;
551 link_state->up = sfx7101_link_ok(efx);
552 } else {
553 efx->phy_op->get_settings(efx, &ecmd);
554 link_state->speed = ecmd.speed;
555 link_state->fd = ecmd.duplex == DUPLEX_FULL;
556 link_state->up = sft9001_link_ok(efx, &ecmd);
557 }
558 link_state->fc = efx_mdio_get_pause(efx);
559} 546}
560 547
561/* Poll PHY for interrupt */ 548static void
562static void tenxpress_phy_poll(struct efx_nic *efx) 549tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
550
551/* Poll for link state changes */
552static bool tenxpress_phy_poll(struct efx_nic *efx)
563{ 553{
564 struct tenxpress_phy_data *phy_data = efx->phy_data; 554 struct efx_link_state old_state = efx->link_state;
565 struct efx_link_state *link_state = &efx->link_state;
566 bool change = false;
567 555
568 if (efx->phy_type == PHY_TYPE_SFX7101) { 556 if (efx->phy_type == PHY_TYPE_SFX7101) {
569 bool link_ok = sfx7101_link_ok(efx); 557 efx->link_state.up = sfx7101_link_ok(efx);
570 if (link_ok != link_state->up) { 558 efx->link_state.speed = 10000;
571 change = true; 559 efx->link_state.fd = true;
572 } else { 560 efx->link_state.fc = efx_mdio_get_pause(efx);
573 unsigned int link_fc = efx_mdio_get_pause(efx); 561
574 if (link_fc != link_state->fc) 562 sfx7101_check_bad_lp(efx, efx->link_state.up);
575 change = true;
576 }
577 sfx7101_check_bad_lp(efx, link_ok);
578 } else if (efx->loopback_mode) {
579 bool link_ok = sft9001_link_ok(efx, NULL);
580 if (link_ok != link_state->up)
581 change = true;
582 } else { 563 } else {
583 int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD, 564 struct ethtool_cmd ecmd;
584 MDIO_PMA_LASI_STAT);
585 if (status & MDIO_PMA_LASI_LSALARM)
586 change = true;
587 }
588 565
589 if (change) 566 /* Check the LASI alarm first */
590 falcon_sim_phy_event(efx); 567 if (efx->loopback_mode == LOOPBACK_NONE &&
568 !(efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT) &
569 MDIO_PMA_LASI_LSALARM))
570 return false;
591 571
592 if (phy_data->phy_mode != PHY_MODE_NORMAL) 572 tenxpress_get_settings(efx, &ecmd);
593 return; 573
574 efx->link_state.up = sft9001_link_ok(efx, &ecmd);
575 efx->link_state.speed = ecmd.speed;
576 efx->link_state.fd = (ecmd.duplex == DUPLEX_FULL);
577 efx->link_state.fc = efx_mdio_get_pause(efx);
578 }
579
580 return !efx_link_state_equal(&efx->link_state, &old_state);
594} 581}
595 582
596static void tenxpress_phy_fini(struct efx_nic *efx) 583static void tenxpress_phy_fini(struct efx_nic *efx)
@@ -818,7 +805,6 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
818 .reconfigure = tenxpress_phy_reconfigure, 805 .reconfigure = tenxpress_phy_reconfigure,
819 .poll = tenxpress_phy_poll, 806 .poll = tenxpress_phy_poll,
820 .fini = tenxpress_phy_fini, 807 .fini = tenxpress_phy_fini,
821 .clear_interrupt = efx_port_dummy_op_void,
822 .get_settings = tenxpress_get_settings, 808 .get_settings = tenxpress_get_settings,
823 .set_settings = tenxpress_set_settings, 809 .set_settings = tenxpress_set_settings,
824 .set_npage_adv = sfx7101_set_npage_adv, 810 .set_npage_adv = sfx7101_set_npage_adv,
@@ -835,7 +821,6 @@ struct efx_phy_operations falcon_sft9001_phy_ops = {
835 .reconfigure = tenxpress_phy_reconfigure, 821 .reconfigure = tenxpress_phy_reconfigure,
836 .poll = tenxpress_phy_poll, 822 .poll = tenxpress_phy_poll,
837 .fini = tenxpress_phy_fini, 823 .fini = tenxpress_phy_fini,
838 .clear_interrupt = efx_port_dummy_op_void,
839 .get_settings = tenxpress_get_settings, 824 .get_settings = tenxpress_get_settings,
840 .set_settings = tenxpress_set_settings, 825 .set_settings = tenxpress_set_settings,
841 .set_npage_adv = sft9001_set_npage_adv, 826 .set_npage_adv = sft9001_set_npage_adv,