.. | .. |
---|
85 | 85 | int rx; |
---|
86 | 86 | int final_tx; |
---|
87 | 87 | int final_rx; |
---|
| 88 | + int max_delay; |
---|
88 | 89 | }; |
---|
89 | 90 | |
---|
90 | 91 | #define DMA_CONTROL_OSP BIT(4) |
---|
.. | .. |
---|
776 | 777 | return __dwmac_rk_loopback_run(priv, lb_priv); |
---|
777 | 778 | } |
---|
778 | 779 | |
---|
779 | | -static inline bool dwmac_rk_delayline_is_valid(int tx, int rx) |
---|
| 780 | +static inline bool dwmac_rk_delayline_is_txvalid(struct dwmac_rk_lb_priv *lb_priv, |
---|
| 781 | + int tx) |
---|
780 | 782 | { |
---|
781 | | - if ((tx > 0 && tx < MAX_DELAYLINE) && (rx > 0 && rx < MAX_DELAYLINE)) |
---|
| 783 | + if (tx > 0 && tx < lb_priv->max_delay) |
---|
| 784 | + return true; |
---|
| 785 | + else |
---|
| 786 | + return false; |
---|
| 787 | +} |
---|
| 788 | + |
---|
| 789 | +static inline bool dwmac_rk_delayline_is_valid(struct dwmac_rk_lb_priv *lb_priv, |
---|
| 790 | + int tx, int rx) |
---|
| 791 | +{ |
---|
| 792 | + if ((tx > 0 && tx < lb_priv->max_delay) && |
---|
| 793 | + (rx > 0 && rx < lb_priv->max_delay)) |
---|
782 | 794 | return true; |
---|
783 | 795 | else |
---|
784 | 796 | return false; |
---|
.. | .. |
---|
789 | 801 | { |
---|
790 | 802 | int tx_left, tx_right, rx_up, rx_down; |
---|
791 | 803 | int i, j, tx_index, rx_index; |
---|
792 | | - int tx_mid, rx_mid; |
---|
| 804 | + int tx_mid = 0, rx_mid = 0; |
---|
793 | 805 | |
---|
794 | 806 | /* initiation */ |
---|
795 | 807 | tx_index = SCAN_STEP; |
---|
.. | .. |
---|
797 | 809 | |
---|
798 | 810 | re_scan: |
---|
799 | 811 | /* start from rx based on the experience */ |
---|
800 | | - for (i = rx_index; i <= (MAX_DELAYLINE - SCAN_STEP); i += SCAN_STEP) { |
---|
| 812 | + for (i = rx_index; i <= (lb_priv->max_delay - SCAN_STEP); i += SCAN_STEP) { |
---|
801 | 813 | tx_left = 0; |
---|
802 | 814 | tx_right = 0; |
---|
803 | 815 | tx_mid = 0; |
---|
804 | 816 | |
---|
805 | | - for (j = tx_index; j <= (MAX_DELAYLINE - SCAN_STEP); |
---|
| 817 | + for (j = tx_index; j <= (lb_priv->max_delay - SCAN_STEP); |
---|
806 | 818 | j += SCAN_STEP) { |
---|
807 | 819 | if (!dwmac_rk_loopback_with_identify(priv, |
---|
808 | 820 | lb_priv, j, i)) { |
---|
.. | .. |
---|
820 | 832 | } |
---|
821 | 833 | |
---|
822 | 834 | /* Worst case: reach the end */ |
---|
823 | | - if (i >= (MAX_DELAYLINE - SCAN_STEP)) |
---|
| 835 | + if (i >= (lb_priv->max_delay - SCAN_STEP)) |
---|
824 | 836 | goto end; |
---|
825 | 837 | |
---|
826 | 838 | rx_up = 0; |
---|
827 | 839 | rx_down = 0; |
---|
828 | 840 | |
---|
829 | 841 | /* look for rx_mid base on the tx_mid */ |
---|
830 | | - for (i = SCAN_STEP; i <= (MAX_DELAYLINE - SCAN_STEP); |
---|
| 842 | + for (i = SCAN_STEP; i <= (lb_priv->max_delay - SCAN_STEP); |
---|
831 | 843 | i += SCAN_STEP) { |
---|
832 | 844 | if (!dwmac_rk_loopback_with_identify(priv, lb_priv, |
---|
833 | 845 | tx_mid, i)) { |
---|
.. | .. |
---|
846 | 858 | goto re_scan; |
---|
847 | 859 | } |
---|
848 | 860 | |
---|
849 | | - if (dwmac_rk_delayline_is_valid(tx_mid, rx_mid)) { |
---|
| 861 | + if (dwmac_rk_delayline_is_valid(lb_priv, tx_mid, rx_mid)) { |
---|
850 | 862 | lb_priv->final_tx = tx_mid; |
---|
851 | 863 | lb_priv->final_rx = rx_mid; |
---|
852 | 864 | |
---|
853 | | - pr_info("Find suitable tx_delay = 0x%02x, rx_delay = 0x%02x\n", |
---|
| 865 | + pr_info("Find available tx_delay = 0x%02x, rx_delay = 0x%02x\n", |
---|
854 | 866 | lb_priv->final_tx, lb_priv->final_rx); |
---|
855 | 867 | |
---|
856 | 868 | return 0; |
---|
857 | 869 | } |
---|
858 | 870 | end: |
---|
859 | | - pr_err("Can't find suitable delayline\n"); |
---|
| 871 | + pr_err("Can't find available delayline\n"); |
---|
860 | 872 | return -ENXIO; |
---|
861 | 873 | } |
---|
862 | 874 | |
---|
863 | 875 | static int dwmac_rk_delayline_scan(struct stmmac_priv *priv, |
---|
864 | 876 | struct dwmac_rk_lb_priv *lb_priv) |
---|
865 | 877 | { |
---|
| 878 | + int phy_iface = dwmac_rk_get_phy_interface(priv); |
---|
866 | 879 | int tx, rx, tx_sum, rx_sum, count; |
---|
867 | 880 | int tx_mid, rx_mid; |
---|
868 | 881 | int ret = -ENXIO; |
---|
.. | .. |
---|
871 | 884 | rx_sum = 0; |
---|
872 | 885 | count = 0; |
---|
873 | 886 | |
---|
874 | | - for (rx = 0x0; rx <= MAX_DELAYLINE; rx++) { |
---|
875 | | - printk(KERN_CONT "RX(0x%02x):", rx); |
---|
876 | | - for (tx = 0x0; tx <= MAX_DELAYLINE; tx++) { |
---|
| 887 | + for (rx = 0x0; rx <= lb_priv->max_delay; rx++) { |
---|
| 888 | + if (phy_iface == PHY_INTERFACE_MODE_RGMII_RXID) |
---|
| 889 | + rx = -1; |
---|
| 890 | + printk(KERN_CONT "RX(%03d):", rx); |
---|
| 891 | + for (tx = 0x0; tx <= lb_priv->max_delay; tx++) { |
---|
877 | 892 | if (!dwmac_rk_loopback_with_identify(priv, |
---|
878 | 893 | lb_priv, tx, rx)) { |
---|
879 | 894 | tx_sum += tx; |
---|
.. | .. |
---|
885 | 900 | } |
---|
886 | 901 | } |
---|
887 | 902 | printk(KERN_CONT "\n"); |
---|
| 903 | + |
---|
| 904 | + if (phy_iface == PHY_INTERFACE_MODE_RGMII_RXID) |
---|
| 905 | + break; |
---|
888 | 906 | } |
---|
889 | 907 | |
---|
890 | 908 | if (tx_sum && rx_sum && count) { |
---|
891 | 909 | tx_mid = tx_sum / count; |
---|
892 | 910 | rx_mid = rx_sum / count; |
---|
893 | 911 | |
---|
894 | | - if (dwmac_rk_delayline_is_valid(tx_mid, rx_mid)) { |
---|
895 | | - lb_priv->final_tx = tx_mid; |
---|
896 | | - lb_priv->final_rx = rx_mid; |
---|
897 | | - ret = 0; |
---|
| 912 | + if (phy_iface == PHY_INTERFACE_MODE_RGMII_RXID) { |
---|
| 913 | + if (dwmac_rk_delayline_is_txvalid(lb_priv, tx_mid)) { |
---|
| 914 | + lb_priv->final_tx = tx_mid; |
---|
| 915 | + lb_priv->final_rx = -1; |
---|
| 916 | + ret = 0; |
---|
| 917 | + } |
---|
| 918 | + } else { |
---|
| 919 | + if (dwmac_rk_delayline_is_valid(lb_priv, tx_mid, rx_mid)) { |
---|
| 920 | + lb_priv->final_tx = tx_mid; |
---|
| 921 | + lb_priv->final_rx = rx_mid; |
---|
| 922 | + ret = 0; |
---|
| 923 | + } |
---|
898 | 924 | } |
---|
899 | 925 | } |
---|
900 | 926 | |
---|
901 | | - if (ret) |
---|
| 927 | + if (ret) { |
---|
902 | 928 | pr_err("\nCan't find suitable delayline\n"); |
---|
903 | | - else |
---|
904 | | - pr_info("\nFind suitable tx_delay = 0x%02x, rx_delay = 0x%02x\n", |
---|
905 | | - lb_priv->final_tx, lb_priv->final_rx); |
---|
| 929 | + } else { |
---|
| 930 | + if (phy_iface == PHY_INTERFACE_MODE_RGMII_RXID) |
---|
| 931 | + pr_info("Find available tx_delay = 0x%02x, rx_delay = disable\n", |
---|
| 932 | + lb_priv->final_tx); |
---|
| 933 | + else |
---|
| 934 | + pr_info("\nFind suitable tx_delay = 0x%02x, rx_delay = 0x%02x\n", |
---|
| 935 | + lb_priv->final_tx, lb_priv->final_rx); |
---|
| 936 | + } |
---|
906 | 937 | |
---|
907 | 938 | return ret; |
---|
908 | 939 | } |
---|
.. | .. |
---|
1178 | 1209 | dwmac_rk_free_dma_desc_resources(priv, lb_priv); |
---|
1179 | 1210 | } |
---|
1180 | 1211 | |
---|
| 1212 | +static int dwmac_rk_get_max_delayline(struct stmmac_priv *priv) |
---|
| 1213 | +{ |
---|
| 1214 | + return MAX_DELAYLINE; |
---|
| 1215 | +} |
---|
| 1216 | + |
---|
1181 | 1217 | static int dwmac_rk_loopback_run(struct stmmac_priv *priv, |
---|
1182 | 1218 | struct dwmac_rk_lb_priv *lb_priv) |
---|
1183 | 1219 | { |
---|
.. | .. |
---|
1188 | 1224 | |
---|
1189 | 1225 | if (!ndev || !priv->mii) |
---|
1190 | 1226 | return -EINVAL; |
---|
| 1227 | + |
---|
| 1228 | + lb_priv->max_delay = dwmac_rk_get_max_delayline(priv); |
---|
1191 | 1229 | |
---|
1192 | 1230 | rtnl_lock(); |
---|
1193 | 1231 | /* check the netdevice up or not */ |
---|
.. | .. |
---|
1229 | 1267 | if (lb_priv->scan) { |
---|
1230 | 1268 | /* scan only support for rgmii mode */ |
---|
1231 | 1269 | if (phy_iface != PHY_INTERFACE_MODE_RGMII && |
---|
1232 | | - phy_iface != PHY_INTERFACE_MODE_RGMII_ID) { |
---|
| 1270 | + phy_iface != PHY_INTERFACE_MODE_RGMII_ID && |
---|
| 1271 | + phy_iface != PHY_INTERFACE_MODE_RGMII_RXID && |
---|
| 1272 | + phy_iface != PHY_INTERFACE_MODE_RGMII_TXID) { |
---|
1233 | 1273 | ret = -EINVAL; |
---|
1234 | 1274 | goto out; |
---|
1235 | 1275 | } |
---|
.. | .. |
---|
1291 | 1331 | *data = 0; |
---|
1292 | 1332 | data++; |
---|
1293 | 1333 | |
---|
1294 | | - if (kstrtoint(tmp, 0, &tx) || tx > MAX_DELAYLINE) |
---|
| 1334 | + if (kstrtoint(tmp, 0, &tx) || tx > dwmac_rk_get_max_delayline(priv)) |
---|
1295 | 1335 | goto out; |
---|
1296 | 1336 | |
---|
1297 | | - if (kstrtoint(data, 0, &rx) || rx > MAX_DELAYLINE) |
---|
| 1337 | + if (kstrtoint(data, 0, &rx) || rx > dwmac_rk_get_max_delayline(priv)) |
---|
1298 | 1338 | goto out; |
---|
1299 | 1339 | |
---|
1300 | 1340 | dwmac_rk_set_rgmii_delayline(priv, tx, rx); |
---|