@@ -863,6 +863,148 @@ static int enetc_set_link_ksettings(struct net_device *dev,
863
863
return phylink_ethtool_ksettings_set (priv -> phylink , cmd );
864
864
}
865
865
866
+ static int enetc_get_mm (struct net_device * ndev , struct ethtool_mm_state * state )
867
+ {
868
+ struct enetc_ndev_priv * priv = netdev_priv (ndev );
869
+ struct enetc_si * si = priv -> si ;
870
+ struct enetc_hw * hw = & si -> hw ;
871
+ u32 lafs , rafs , val ;
872
+
873
+ if (!(si -> hw_features & ENETC_SI_F_QBU ))
874
+ return - EOPNOTSUPP ;
875
+
876
+ mutex_lock (& priv -> mm_lock );
877
+
878
+ val = enetc_port_rd (hw , ENETC_PFPMR );
879
+ state -> pmac_enabled = !!(val & ENETC_PFPMR_PMACE );
880
+
881
+ val = enetc_port_rd (hw , ENETC_MMCSR );
882
+
883
+ switch (ENETC_MMCSR_GET_VSTS (val )) {
884
+ case 0 :
885
+ state -> verify_status = ETHTOOL_MM_VERIFY_STATUS_DISABLED ;
886
+ break ;
887
+ case 2 :
888
+ state -> verify_status = ETHTOOL_MM_VERIFY_STATUS_VERIFYING ;
889
+ break ;
890
+ case 3 :
891
+ state -> verify_status = ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ;
892
+ break ;
893
+ case 4 :
894
+ state -> verify_status = ETHTOOL_MM_VERIFY_STATUS_FAILED ;
895
+ break ;
896
+ case 5 :
897
+ default :
898
+ state -> verify_status = ETHTOOL_MM_VERIFY_STATUS_UNKNOWN ;
899
+ break ;
900
+ }
901
+
902
+ rafs = ENETC_MMCSR_GET_RAFS (val );
903
+ state -> tx_min_frag_size = ethtool_mm_frag_size_add_to_min (rafs );
904
+ lafs = ENETC_MMCSR_GET_LAFS (val );
905
+ state -> rx_min_frag_size = ethtool_mm_frag_size_add_to_min (lafs );
906
+ state -> tx_enabled = !!(val & ENETC_MMCSR_LPE ); /* mirror of MMCSR_ME */
907
+ state -> tx_active = !!(val & ENETC_MMCSR_LPA );
908
+ state -> verify_enabled = !(val & ENETC_MMCSR_VDIS );
909
+ state -> verify_time = ENETC_MMCSR_GET_VT (val );
910
+ /* A verifyTime of 128 ms would exceed the 7 bit width
911
+ * of the ENETC_MMCSR_VT field
912
+ */
913
+ state -> max_verify_time = 127 ;
914
+
915
+ mutex_unlock (& priv -> mm_lock );
916
+
917
+ return 0 ;
918
+ }
919
+
920
+ static int enetc_set_mm (struct net_device * ndev , struct ethtool_mm_cfg * cfg ,
921
+ struct netlink_ext_ack * extack )
922
+ {
923
+ struct enetc_ndev_priv * priv = netdev_priv (ndev );
924
+ struct enetc_hw * hw = & priv -> si -> hw ;
925
+ struct enetc_si * si = priv -> si ;
926
+ u32 val , add_frag_size ;
927
+ int err ;
928
+
929
+ if (!(si -> hw_features & ENETC_SI_F_QBU ))
930
+ return - EOPNOTSUPP ;
931
+
932
+ err = ethtool_mm_frag_size_min_to_add (cfg -> tx_min_frag_size ,
933
+ & add_frag_size , extack );
934
+ if (err )
935
+ return err ;
936
+
937
+ mutex_lock (& priv -> mm_lock );
938
+
939
+ val = enetc_port_rd (hw , ENETC_PFPMR );
940
+ if (cfg -> pmac_enabled )
941
+ val |= ENETC_PFPMR_PMACE ;
942
+ else
943
+ val &= ~ENETC_PFPMR_PMACE ;
944
+ enetc_port_wr (hw , ENETC_PFPMR , val );
945
+
946
+ val = enetc_port_rd (hw , ENETC_MMCSR );
947
+
948
+ if (cfg -> verify_enabled )
949
+ val &= ~ENETC_MMCSR_VDIS ;
950
+ else
951
+ val |= ENETC_MMCSR_VDIS ;
952
+
953
+ if (cfg -> tx_enabled )
954
+ priv -> active_offloads |= ENETC_F_QBU ;
955
+ else
956
+ priv -> active_offloads &= ~ENETC_F_QBU ;
957
+
958
+ /* If link is up, enable MAC Merge right away */
959
+ if (!!(priv -> active_offloads & ENETC_F_QBU ) &&
960
+ !(val & ENETC_MMCSR_LINK_FAIL ))
961
+ val |= ENETC_MMCSR_ME ;
962
+
963
+ val &= ~ENETC_MMCSR_VT_MASK ;
964
+ val |= ENETC_MMCSR_VT (cfg -> verify_time );
965
+
966
+ val &= ~ENETC_MMCSR_RAFS_MASK ;
967
+ val |= ENETC_MMCSR_RAFS (add_frag_size );
968
+
969
+ enetc_port_wr (hw , ENETC_MMCSR , val );
970
+
971
+ mutex_unlock (& priv -> mm_lock );
972
+
973
+ return 0 ;
974
+ }
975
+
976
+ /* When the link is lost, the verification state machine goes to the FAILED
977
+ * state and doesn't restart on its own after a new link up event.
978
+ * According to 802.3 Figure 99-8 - Verify state diagram, the LINK_FAIL bit
979
+ * should have been sufficient to re-trigger verification, but for ENETC it
980
+ * doesn't. As a workaround, we need to toggle the Merge Enable bit to
981
+ * re-trigger verification when link comes up.
982
+ */
983
+ void enetc_mm_link_state_update (struct enetc_ndev_priv * priv , bool link )
984
+ {
985
+ struct enetc_hw * hw = & priv -> si -> hw ;
986
+ u32 val ;
987
+
988
+ mutex_lock (& priv -> mm_lock );
989
+
990
+ val = enetc_port_rd (hw , ENETC_MMCSR );
991
+
992
+ if (link ) {
993
+ val &= ~ENETC_MMCSR_LINK_FAIL ;
994
+ if (priv -> active_offloads & ENETC_F_QBU )
995
+ val |= ENETC_MMCSR_ME ;
996
+ } else {
997
+ val |= ENETC_MMCSR_LINK_FAIL ;
998
+ if (priv -> active_offloads & ENETC_F_QBU )
999
+ val &= ~ENETC_MMCSR_ME ;
1000
+ }
1001
+
1002
+ enetc_port_wr (hw , ENETC_MMCSR , val );
1003
+
1004
+ mutex_unlock (& priv -> mm_lock );
1005
+ }
1006
+ EXPORT_SYMBOL_GPL (enetc_mm_link_state_update );
1007
+
866
1008
static const struct ethtool_ops enetc_pf_ethtool_ops = {
867
1009
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
868
1010
ETHTOOL_COALESCE_MAX_FRAMES |
@@ -893,6 +1035,8 @@ static const struct ethtool_ops enetc_pf_ethtool_ops = {
893
1035
.set_wol = enetc_set_wol ,
894
1036
.get_pauseparam = enetc_get_pauseparam ,
895
1037
.set_pauseparam = enetc_set_pauseparam ,
1038
+ .get_mm = enetc_get_mm ,
1039
+ .set_mm = enetc_set_mm ,
896
1040
};
897
1041
898
1042
static const struct ethtool_ops enetc_vf_ethtool_ops = {
0 commit comments