diff options
Diffstat (limited to 'drivers/net/sfc/tenxpress.c')
-rw-r--r-- | drivers/net/sfc/tenxpress.c | 151 |
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 | ||
744 | static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) | 746 | static void |
747 | tenxpress_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 | |||
764 | static 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 | |||
772 | static 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 | ||
810 | static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 788 | static 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; | 796 | static 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 | ||
827 | static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising) | 804 | static 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 | ||
854 | struct efx_phy_operations falcon_sfx7101_phy_ops = { | 818 | struct 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, |