aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/tenxpress.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/tenxpress.c')
-rw-r--r--drivers/net/sfc/tenxpress.c151
1 files changed, 58 insertions, 93 deletions
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index c9584619322a..412d209d8313 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -179,11 +179,13 @@
179#define C22EXT_STATUS_LINK_LBN 2 179#define C22EXT_STATUS_LINK_LBN 2
180#define C22EXT_STATUS_LINK_WIDTH 1 180#define C22EXT_STATUS_LINK_WIDTH 1
181 181
182#define C22EXT_MSTSLV_REG 49162 182#define C22EXT_MSTSLV_CTRL 49161
183#define C22EXT_MSTSLV_1000_HD_LBN 10 183#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8
184#define C22EXT_MSTSLV_1000_HD_WIDTH 1 184#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9
185#define C22EXT_MSTSLV_1000_FD_LBN 11 185
186#define C22EXT_MSTSLV_1000_FD_WIDTH 1 186#define C22EXT_MSTSLV_STATUS 49162
187#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10
188#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11
187 189
188/* Time to wait between powering down the LNPGA and turning off the power 190/* Time to wait between powering down the LNPGA and turning off the power
189 * rails */ 191 * rails */
@@ -741,114 +743,76 @@ reset:
741 return rc; 743 return rc;
742} 744}
743 745
744static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) 746static void
747tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
745{ 748{
746 int phy = efx->mii.phy_id; 749 int phy_id = efx->mii.phy_id;
747 u32 lpa = 0; 750 u32 adv = 0, lpa = 0;
748 int reg; 751 int reg;
749 752
750 if (efx->phy_type != PHY_TYPE_SFX7101) { 753 if (efx->phy_type != PHY_TYPE_SFX7101) {
751 reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT, 754 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
752 C22EXT_MSTSLV_REG); 755 C22EXT_MSTSLV_CTRL);
753 if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN)) 756 if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
757 adv |= ADVERTISED_1000baseT_Full;
758 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
759 C22EXT_MSTSLV_STATUS);
760 if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
754 lpa |= ADVERTISED_1000baseT_Half; 761 lpa |= ADVERTISED_1000baseT_Half;
755 if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN)) 762 if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
756 lpa |= ADVERTISED_1000baseT_Full; 763 lpa |= ADVERTISED_1000baseT_Full;
757 } 764 }
758 reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS); 765 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
766 MDIO_AN_10GBT_CTRL);
767 if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
768 adv |= ADVERTISED_10000baseT_Full;
769 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
770 MDIO_AN_10GBT_STATUS);
759 if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) 771 if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
760 lpa |= ADVERTISED_10000baseT_Full; 772 lpa |= ADVERTISED_10000baseT_Full;
761 return lpa;
762}
763
764static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
765{
766 mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full,
767 tenxpress_get_xnp_lpa(efx));
768 ecmd->supported |= SUPPORTED_10000baseT_Full;
769 ecmd->advertising |= ADVERTISED_10000baseT_Full;
770}
771
772static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
773{
774 int phy_id = efx->mii.phy_id;
775 u32 xnp_adv = 0;
776 int reg;
777
778 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
779 PMA_PMD_SPEED_ENABLE_REG);
780 if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN)))
781 xnp_adv |= ADVERTISED_100baseT_Full;
782 if (reg & (1 << PMA_PMD_1000T_ADV_LBN))
783 xnp_adv |= ADVERTISED_1000baseT_Full;
784 if (reg & (1 << PMA_PMD_10000T_ADV_LBN))
785 xnp_adv |= ADVERTISED_10000baseT_Full;
786
787 mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv,
788 tenxpress_get_xnp_lpa(efx));
789 773
790 ecmd->supported |= (SUPPORTED_100baseT_Half | 774 mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
791 SUPPORTED_100baseT_Full |
792 SUPPORTED_1000baseT_Full);
793 775
794 /* Use the vendor defined C22ext register for duplex settings */ 776 if (efx->phy_type != PHY_TYPE_SFX7101)
795 if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) { 777 ecmd->supported |= (SUPPORTED_100baseT_Full |
796 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, 778 SUPPORTED_1000baseT_Full);
797 GPHY_XCONTROL_REG);
798 ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
799 DUPLEX_FULL : DUPLEX_HALF);
800 }
801 779
802 /* In loopback, the PHY automatically brings up the correct interface, 780 /* In loopback, the PHY automatically brings up the correct interface,
803 * but doesn't advertise the correct speed. So override it */ 781 * but doesn't advertise the correct speed. So override it */
804 if (efx->loopback_mode == LOOPBACK_GPHY) 782 if (efx->loopback_mode == LOOPBACK_GPHY)
805 ecmd->speed = SPEED_1000; 783 ecmd->speed = SPEED_1000;
806 else if (LOOPBACK_MASK(efx) & SFT9001_LOOPBACKS) 784 else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
807 ecmd->speed = SPEED_10000; 785 ecmd->speed = SPEED_10000;
808} 786}
809 787
810static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 788static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
811{ 789{
812 int phy_id = efx->mii.phy_id; 790 if (!ecmd->autoneg)
813 int rc; 791 return -EINVAL;
814
815 rc = mdio_clause45_set_settings(efx, ecmd);
816 if (rc)
817 return rc;
818 792
819 if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) 793 return mdio_clause45_set_settings(efx, ecmd);
820 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, 794}
821 GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN,
822 ecmd->duplex == DUPLEX_FULL);
823 795
824 return rc; 796static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
797{
798 mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
799 MDIO_AN_10GBT_CTRL,
800 MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
801 advertising & ADVERTISED_10000baseT_Full);
825} 802}
826 803
827static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising) 804static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
828{ 805{
829 int phy = efx->mii.phy_id; 806 int phy_id = efx->mii.phy_id;
830 int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD, 807
831 PMA_PMD_SPEED_ENABLE_REG); 808 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
832 bool enabled; 809 C22EXT_MSTSLV_CTRL,
833 810 C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
834 reg &= ~((1 << 2) | (1 << 3)); 811 advertising & ADVERTISED_1000baseT_Full);
835 if (EFX_WORKAROUND_13204(efx) && 812 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
836 (advertising & ADVERTISED_100baseT_Full)) 813 MDIO_AN_10GBT_CTRL,
837 reg |= 1 << PMA_PMD_100TX_ADV_LBN; 814 MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
838 if (advertising & ADVERTISED_1000baseT_Full) 815 advertising & ADVERTISED_10000baseT_Full);
839 reg |= 1 << PMA_PMD_1000T_ADV_LBN;
840 if (advertising & ADVERTISED_10000baseT_Full)
841 reg |= 1 << PMA_PMD_10000T_ADV_LBN;
842 mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD,
843 PMA_PMD_SPEED_ENABLE_REG, reg);
844
845 enabled = (advertising &
846 (ADVERTISED_1000baseT_Half |
847 ADVERTISED_1000baseT_Full |
848 ADVERTISED_10000baseT_Full));
849 if (EFX_WORKAROUND_13204(efx))
850 enabled |= (advertising & ADVERTISED_100baseT_Full);
851 return enabled;
852} 816}
853 817
854struct efx_phy_operations falcon_sfx7101_phy_ops = { 818struct efx_phy_operations falcon_sfx7101_phy_ops = {
@@ -858,8 +822,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
858 .poll = tenxpress_phy_poll, 822 .poll = tenxpress_phy_poll,
859 .fini = tenxpress_phy_fini, 823 .fini = tenxpress_phy_fini,
860 .clear_interrupt = efx_port_dummy_op_void, 824 .clear_interrupt = efx_port_dummy_op_void,
861 .get_settings = sfx7101_get_settings, 825 .get_settings = tenxpress_get_settings,
862 .set_settings = mdio_clause45_set_settings, 826 .set_settings = tenxpress_set_settings,
827 .set_npage_adv = sfx7101_set_npage_adv,
863 .num_tests = ARRAY_SIZE(sfx7101_test_names), 828 .num_tests = ARRAY_SIZE(sfx7101_test_names),
864 .test_names = sfx7101_test_names, 829 .test_names = sfx7101_test_names,
865 .run_tests = sfx7101_run_tests, 830 .run_tests = sfx7101_run_tests,
@@ -874,9 +839,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = {
874 .poll = tenxpress_phy_poll, 839 .poll = tenxpress_phy_poll,
875 .fini = tenxpress_phy_fini, 840 .fini = tenxpress_phy_fini,
876 .clear_interrupt = efx_port_dummy_op_void, 841 .clear_interrupt = efx_port_dummy_op_void,
877 .get_settings = sft9001_get_settings, 842 .get_settings = tenxpress_get_settings,
878 .set_settings = sft9001_set_settings, 843 .set_settings = tenxpress_set_settings,
879 .set_xnp_advertise = sft9001_set_xnp_advertise, 844 .set_npage_adv = sft9001_set_npage_adv,
880 .num_tests = ARRAY_SIZE(sft9001_test_names), 845 .num_tests = ARRAY_SIZE(sft9001_test_names),
881 .test_names = sft9001_test_names, 846 .test_names = sft9001_test_names,
882 .run_tests = sft9001_run_tests, 847 .run_tests = sft9001_run_tests,