Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'net-dsa-vsc73xx-convert-to-phylink-and-do-some-cleanup'

Pawel Dembicki says:

====================
net: dsa: vsc73xx: convert to PHYLINK and do some cleanup

This patch series is a result of splitting a larger patch series [0],
where some parts needed to be refactored.

The first patch switches from a poll loop to read_poll_timeout.

The second patch is a simple conversion to phylink because adjust_link
won't work anymore.

The third patch is preparation for future use. Using the
"phy_interface_mode_is_rgmii" macro allows for the proper recognition
of all RGMII modes.

Patches 4-5 involve some cleanup: The fourth patch introduces
a definition with the maximum number of ports to avoid using
magic numbers. The next one fills in documentation.

[0] https://patchwork.kernel.org/project/netdevbpf/list/?series=841034&state=%2A&archive=both
====================

Link: https://lore.kernel.org/r/20240417205048.3542839-1-paweldembicki@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+148 -142
+122 -141
drivers/net/dsa/vitesse-vsc73xx-core.c
··· 17 17 #include <linux/kernel.h> 18 18 #include <linux/module.h> 19 19 #include <linux/device.h> 20 + #include <linux/iopoll.h> 20 21 #include <linux/of.h> 21 22 #include <linux/of_mdio.h> 22 23 #include <linux/bitops.h> ··· 268 267 #define IS_7395(a) ((a)->chipid == VSC73XX_CHIPID_ID_7395) 269 268 #define IS_7398(a) ((a)->chipid == VSC73XX_CHIPID_ID_7398) 270 269 #define IS_739X(a) (IS_7395(a) || IS_7398(a)) 270 + 271 + #define VSC73XX_POLL_SLEEP_US 1000 272 + #define VSC73XX_POLL_TIMEOUT_US 10000 271 273 272 274 struct vsc73xx_counter { 273 275 u8 counter; ··· 717 713 port, VSC73XX_C_RX0, 0); 718 714 } 719 715 720 - static void vsc73xx_adjust_enable_port(struct vsc73xx *vsc, 721 - int port, struct phy_device *phydev, 722 - u32 initval) 716 + static void vsc73xx_reset_port(struct vsc73xx *vsc, int port, u32 initval) 723 717 { 724 - u32 val = initval; 718 + int ret, err; 719 + u32 val; 720 + 721 + /* Disable RX on this port */ 722 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, 723 + VSC73XX_MAC_CFG, 724 + VSC73XX_MAC_CFG_RX_EN, 0); 725 + 726 + /* Discard packets */ 727 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 728 + VSC73XX_ARBDISC, BIT(port), BIT(port)); 729 + 730 + /* Wait until queue is empty */ 731 + ret = read_poll_timeout(vsc73xx_read, err, 732 + err < 0 || (val & BIT(port)), 733 + VSC73XX_POLL_SLEEP_US, 734 + VSC73XX_POLL_TIMEOUT_US, false, 735 + vsc, VSC73XX_BLOCK_ARBITER, 0, 736 + VSC73XX_ARBEMPTY, &val); 737 + if (ret) 738 + dev_err(vsc->dev, 739 + "timeout waiting for block arbiter\n"); 740 + else if (err < 0) 741 + dev_err(vsc->dev, "error reading arbiter\n"); 742 + 743 + /* Put this port into reset */ 744 + vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG, 745 + VSC73XX_MAC_CFG_RESET | initval); 746 + } 747 + 748 + static void vsc73xx_mac_config(struct phylink_config *config, unsigned int mode, 749 + const struct phylink_link_state *state) 750 + { 751 + struct dsa_port *dp = dsa_phylink_to_port(config); 752 + struct vsc73xx *vsc = dp->ds->priv; 753 + int port = dp->index; 754 + 755 + /* Special handling of the CPU-facing port */ 756 + if (port == CPU_PORT) { 757 + /* Other ports are already initialized but not this one */ 758 + vsc73xx_init_port(vsc, CPU_PORT); 759 + /* Select the external port for this interface (EXT_PORT) 760 + * Enable the GMII GTX external clock 761 + * Use double data rate (DDR mode) 762 + */ 763 + vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, 764 + CPU_PORT, 765 + VSC73XX_ADVPORTM, 766 + VSC73XX_ADVPORTM_EXT_PORT | 767 + VSC73XX_ADVPORTM_ENA_GTX | 768 + VSC73XX_ADVPORTM_DDR_MODE); 769 + } 770 + } 771 + 772 + static void vsc73xx_mac_link_down(struct phylink_config *config, 773 + unsigned int mode, phy_interface_t interface) 774 + { 775 + struct dsa_port *dp = dsa_phylink_to_port(config); 776 + struct vsc73xx *vsc = dp->ds->priv; 777 + int port = dp->index; 778 + 779 + /* This routine is described in the datasheet (below ARBDISC register 780 + * description) 781 + */ 782 + vsc73xx_reset_port(vsc, port, 0); 783 + 784 + /* Allow backward dropping of frames from this port */ 785 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 786 + VSC73XX_SBACKWDROP, BIT(port), BIT(port)); 787 + 788 + /* Receive mask (disable forwarding) */ 789 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 790 + VSC73XX_RECVMASK, BIT(port), 0); 791 + } 792 + 793 + static void vsc73xx_mac_link_up(struct phylink_config *config, 794 + struct phy_device *phy, unsigned int mode, 795 + phy_interface_t interface, int speed, 796 + int duplex, bool tx_pause, bool rx_pause) 797 + { 798 + struct dsa_port *dp = dsa_phylink_to_port(config); 799 + struct vsc73xx *vsc = dp->ds->priv; 800 + int port = dp->index; 801 + u32 val; 725 802 u8 seed; 726 803 727 - /* Reset this port FIXME: break out subroutine */ 728 - val |= VSC73XX_MAC_CFG_RESET; 729 - vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG, val); 804 + if (speed == SPEED_1000) 805 + val = VSC73XX_MAC_CFG_GIGA_MODE | VSC73XX_MAC_CFG_TX_IPG_1000M; 806 + else 807 + val = VSC73XX_MAC_CFG_TX_IPG_100_10M; 808 + 809 + if (phy_interface_mode_is_rgmii(interface)) 810 + val |= VSC73XX_MAC_CFG_CLK_SEL_1000M; 811 + else 812 + val |= VSC73XX_MAC_CFG_CLK_SEL_EXT; 813 + 814 + if (duplex == DUPLEX_FULL) 815 + val |= VSC73XX_MAC_CFG_FDX; 816 + 817 + /* This routine is described in the datasheet (below ARBDISC register 818 + * description) 819 + */ 820 + vsc73xx_reset_port(vsc, port, val); 730 821 731 822 /* Seed the port randomness with randomness */ 732 823 get_random_bytes(&seed, 1); ··· 840 741 VSC73XX_FCCONF_FLOW_CTRL_OBEY | 841 742 0xff); 842 743 744 + /* Accept packets again */ 745 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 746 + VSC73XX_ARBDISC, BIT(port), 0); 747 + 748 + /* Enable port (forwarding) in the receive mask */ 749 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 750 + VSC73XX_RECVMASK, BIT(port), BIT(port)); 751 + 843 752 /* Disallow backward dropping of frames from this port */ 844 753 vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 845 754 VSC73XX_SBACKWDROP, BIT(port), 0); ··· 858 751 VSC73XX_MAC_CFG_RESET | VSC73XX_MAC_CFG_SEED_LOAD | 859 752 VSC73XX_MAC_CFG_TX_EN | VSC73XX_MAC_CFG_RX_EN, 860 753 VSC73XX_MAC_CFG_TX_EN | VSC73XX_MAC_CFG_RX_EN); 861 - } 862 - 863 - static void vsc73xx_adjust_link(struct dsa_switch *ds, int port, 864 - struct phy_device *phydev) 865 - { 866 - struct vsc73xx *vsc = ds->priv; 867 - u32 val; 868 - 869 - /* Special handling of the CPU-facing port */ 870 - if (port == CPU_PORT) { 871 - /* Other ports are already initialized but not this one */ 872 - vsc73xx_init_port(vsc, CPU_PORT); 873 - /* Select the external port for this interface (EXT_PORT) 874 - * Enable the GMII GTX external clock 875 - * Use double data rate (DDR mode) 876 - */ 877 - vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, 878 - CPU_PORT, 879 - VSC73XX_ADVPORTM, 880 - VSC73XX_ADVPORTM_EXT_PORT | 881 - VSC73XX_ADVPORTM_ENA_GTX | 882 - VSC73XX_ADVPORTM_DDR_MODE); 883 - } 884 - 885 - /* This is the MAC confiuration that always need to happen 886 - * after a PHY or the CPU port comes up or down. 887 - */ 888 - if (!phydev->link) { 889 - int maxloop = 10; 890 - 891 - dev_dbg(vsc->dev, "port %d: went down\n", 892 - port); 893 - 894 - /* Disable RX on this port */ 895 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, 896 - VSC73XX_MAC_CFG, 897 - VSC73XX_MAC_CFG_RX_EN, 0); 898 - 899 - /* Discard packets */ 900 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 901 - VSC73XX_ARBDISC, BIT(port), BIT(port)); 902 - 903 - /* Wait until queue is empty */ 904 - vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0, 905 - VSC73XX_ARBEMPTY, &val); 906 - while (!(val & BIT(port))) { 907 - msleep(1); 908 - vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0, 909 - VSC73XX_ARBEMPTY, &val); 910 - if (--maxloop == 0) { 911 - dev_err(vsc->dev, 912 - "timeout waiting for block arbiter\n"); 913 - /* Continue anyway */ 914 - break; 915 - } 916 - } 917 - 918 - /* Put this port into reset */ 919 - vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG, 920 - VSC73XX_MAC_CFG_RESET); 921 - 922 - /* Accept packets again */ 923 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 924 - VSC73XX_ARBDISC, BIT(port), 0); 925 - 926 - /* Allow backward dropping of frames from this port */ 927 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 928 - VSC73XX_SBACKWDROP, BIT(port), BIT(port)); 929 - 930 - /* Receive mask (disable forwarding) */ 931 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 932 - VSC73XX_RECVMASK, BIT(port), 0); 933 - 934 - return; 935 - } 936 - 937 - /* Figure out what speed was negotiated */ 938 - if (phydev->speed == SPEED_1000) { 939 - dev_dbg(vsc->dev, "port %d: 1000 Mbit mode full duplex\n", 940 - port); 941 - 942 - /* Set up default for internal port or external RGMII */ 943 - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) 944 - val = VSC73XX_MAC_CFG_1000M_F_RGMII; 945 - else 946 - val = VSC73XX_MAC_CFG_1000M_F_PHY; 947 - vsc73xx_adjust_enable_port(vsc, port, phydev, val); 948 - } else if (phydev->speed == SPEED_100) { 949 - if (phydev->duplex == DUPLEX_FULL) { 950 - val = VSC73XX_MAC_CFG_100_10M_F_PHY; 951 - dev_dbg(vsc->dev, 952 - "port %d: 100 Mbit full duplex mode\n", 953 - port); 954 - } else { 955 - val = VSC73XX_MAC_CFG_100_10M_H_PHY; 956 - dev_dbg(vsc->dev, 957 - "port %d: 100 Mbit half duplex mode\n", 958 - port); 959 - } 960 - vsc73xx_adjust_enable_port(vsc, port, phydev, val); 961 - } else if (phydev->speed == SPEED_10) { 962 - if (phydev->duplex == DUPLEX_FULL) { 963 - val = VSC73XX_MAC_CFG_100_10M_F_PHY; 964 - dev_dbg(vsc->dev, 965 - "port %d: 10 Mbit full duplex mode\n", 966 - port); 967 - } else { 968 - val = VSC73XX_MAC_CFG_100_10M_H_PHY; 969 - dev_dbg(vsc->dev, 970 - "port %d: 10 Mbit half duplex mode\n", 971 - port); 972 - } 973 - vsc73xx_adjust_enable_port(vsc, port, phydev, val); 974 - } else { 975 - dev_err(vsc->dev, 976 - "could not adjust link: unknown speed\n"); 977 - } 978 - 979 - /* Enable port (forwarding) in the receieve mask */ 980 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 981 - VSC73XX_RECVMASK, BIT(port), BIT(port)); 982 754 } 983 755 984 756 static int vsc73xx_port_enable(struct dsa_switch *ds, int port, ··· 1039 1053 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000; 1040 1054 } 1041 1055 1056 + static const struct phylink_mac_ops vsc73xx_phylink_mac_ops = { 1057 + .mac_config = vsc73xx_mac_config, 1058 + .mac_link_down = vsc73xx_mac_link_down, 1059 + .mac_link_up = vsc73xx_mac_link_up, 1060 + }; 1061 + 1042 1062 static const struct dsa_switch_ops vsc73xx_ds_ops = { 1043 1063 .get_tag_protocol = vsc73xx_get_tag_protocol, 1044 1064 .setup = vsc73xx_setup, 1045 1065 .phy_read = vsc73xx_phy_read, 1046 1066 .phy_write = vsc73xx_phy_write, 1047 - .adjust_link = vsc73xx_adjust_link, 1048 1067 .get_strings = vsc73xx_get_strings, 1049 1068 .get_ethtool_stats = vsc73xx_get_ethtool_stats, 1050 1069 .get_sset_count = vsc73xx_get_sset_count, ··· 1186 1195 vsc->addr[0], vsc->addr[1], vsc->addr[2], 1187 1196 vsc->addr[3], vsc->addr[4], vsc->addr[5]); 1188 1197 1189 - /* The VSC7395 switch chips have 5+1 ports which means 5 1190 - * ordinary ports and a sixth CPU port facing the processor 1191 - * with an RGMII interface. These ports are numbered 0..4 1192 - * and 6, so they leave a "hole" in the port map for port 5, 1193 - * which is invalid. 1194 - * 1195 - * The VSC7398 has 8 ports, port 7 is again the CPU port. 1196 - * 1197 - * We allocate 8 ports and avoid access to the nonexistant 1198 - * ports. 1199 - */ 1200 1198 vsc->ds = devm_kzalloc(dev, sizeof(*vsc->ds), GFP_KERNEL); 1201 1199 if (!vsc->ds) 1202 1200 return -ENOMEM; 1203 1201 1204 1202 vsc->ds->dev = dev; 1205 - vsc->ds->num_ports = 8; 1203 + vsc->ds->num_ports = VSC73XX_MAX_NUM_PORTS; 1206 1204 vsc->ds->priv = vsc; 1207 1205 1208 1206 vsc->ds->ops = &vsc73xx_ds_ops; 1207 + vsc->ds->phylink_mac_ops = &vsc73xx_phylink_mac_ops; 1209 1208 ret = dsa_register_switch(vsc->ds); 1210 1209 if (ret) { 1211 1210 dev_err(dev, "unable to register switch (%d)\n", ret);
+26 -1
drivers/net/dsa/vitesse-vsc73xx.h
··· 3 3 #include <linux/etherdevice.h> 4 4 #include <linux/gpio/driver.h> 5 5 6 + /* The VSC7395 switch chips have 5+1 ports which means 5 ordinary ports and 7 + * a sixth CPU port facing the processor with an RGMII interface. These ports 8 + * are numbered 0..4 and 6, so they leave a "hole" in the port map for port 5, 9 + * which is invalid. 10 + * 11 + * The VSC7398 has 8 ports, port 7 is again the CPU port. 12 + * 13 + * We allocate 8 ports and avoid access to the nonexistent ports. 14 + */ 15 + #define VSC73XX_MAX_NUM_PORTS 8 16 + 6 17 /** 7 - * struct vsc73xx - VSC73xx state container 18 + * struct vsc73xx - VSC73xx state container: main data structure 19 + * @dev: The device pointer 20 + * @reset: The descriptor for the GPIO line tied to the reset pin 21 + * @ds: Pointer to the DSA core structure 22 + * @gc: Main structure of the GPIO controller 23 + * @chipid: Storage for the Chip ID value read from the CHIPID register of the 24 + * switch 25 + * @addr: MAC address used in flow control frames 26 + * @ops: Structure with hardware-dependent operations 27 + * @priv: Pointer to the configuration interface structure 8 28 */ 9 29 struct vsc73xx { 10 30 struct device *dev; ··· 37 17 void *priv; 38 18 }; 39 19 20 + /** 21 + * struct vsc73xx_ops - VSC73xx methods container 22 + * @read: Method for register reading over the hardware-dependent interface 23 + * @write: Method for register writing over the hardware-dependent interface 24 + */ 40 25 struct vsc73xx_ops { 41 26 int (*read)(struct vsc73xx *vsc, u8 block, u8 subblock, u8 reg, 42 27 u32 *val);