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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-dsa-lantiq_gswip-clean-up-and-improve-vlan-handling'

Daniel Golle says:

====================
net: dsa: lantiq_gswip: clean up and improve VLAN handling

This series was developed by Vladimir Oltean to improve and clean up the
VLAN handling logic in the Lantiq GSWIP DSA driver.

As Vladimir currently doesn't have the availability to take care of the
submission process, we agreed that I would send the patches on his
behalf.

The series focuses on consolidating the VLAN management paths for both
VLAN-unaware and VLAN-aware bridges, simplifying internal logic, and
removing legacy or redundant code. It also fixes a number of subtle
inconsistencies regarding VLAN ID 0 handling, bridge FDB entries, and
brings the driver into shape to permit dynamic changes to the VLAN
filtering state.

Notable changes include:

- Support for bridge FDB entries on the CPU port

- Consolidation of gswip_vlan_add_unaware() and gswip_vlan_add_aware()
into a unified implementation

- Removal of legacy VLAN configuration options and redundant
assignments

- Improved handling of VLAN ID 0 and PVID behavior

- Better validation and error reporting in VLAN removal paths

- Support for dynamic VLAN filtering configuration changes

Overall, this refactor improves readability and maintainability of the
Lantiq GSWIP DSA driver. It also results in all local-termination.sh
tests now passing, and slightly improves the results of
bridge-vlan-{un,}aware.sh.

All patches have been authored by Vladimir Oltean; a small unintended
functional change in patch "net: dsa: lantiq_gswip: merge
gswip_vlan_add_unaware() and gswip_vlan_add_aware()" has been ironed out
and some of the commit descriptions were improved by me, apart from that
I'm only handling the submission and will help with follow-up
discussions or review feedback as needed.

Despite the fact that some changes here do actually fix things (in the
sense that selftests which would previously FAIL now PASS) we decided
that it would be the best for this series of patches to go via net-next.
If requested some of it can still be ported to stable kernels later on.
====================

Link: https://patch.msgid.link/cover.1760566491.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+107 -124
+101 -123
drivers/net/dsa/lantiq/lantiq_gswip.c
··· 432 432 433 433 vlan_active.index = port + 1; 434 434 vlan_active.table = GSWIP_TABLE_ACTIVE_VLAN; 435 - vlan_active.key[0] = 0; /* vid */ 435 + vlan_active.key[0] = GSWIP_VLAN_UNAWARE_PVID; 436 436 vlan_active.val[0] = port + 1 /* fid */; 437 437 vlan_active.valid = add; 438 438 err = gswip_pce_table_entry_write(priv, &vlan_active); ··· 446 446 447 447 vlan_mapping.index = port + 1; 448 448 vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING; 449 - vlan_mapping.val[0] = 0 /* vid */; 449 + vlan_mapping.val[0] = GSWIP_VLAN_UNAWARE_PVID; 450 450 vlan_mapping.val[1] = BIT(port) | dsa_cpu_ports(priv->ds); 451 451 vlan_mapping.val[2] = 0; 452 452 err = gswip_pce_table_entry_write(priv, &vlan_mapping); ··· 547 547 return 0; 548 548 } 549 549 550 + static void gswip_port_commit_pvid(struct gswip_priv *priv, int port) 551 + { 552 + struct dsa_port *dp = dsa_to_port(priv->ds, port); 553 + struct net_device *br = dsa_port_bridge_dev_get(dp); 554 + u32 vinr; 555 + int idx; 556 + 557 + if (!dsa_port_is_user(dp)) 558 + return; 559 + 560 + if (br) { 561 + u16 pvid = GSWIP_VLAN_UNAWARE_PVID; 562 + 563 + if (br_vlan_enabled(br)) 564 + br_vlan_get_pvid(br, &pvid); 565 + 566 + /* VLAN-aware bridge ports with no PVID will use Active VLAN 567 + * index 0. The expectation is that this drops all untagged and 568 + * VID-0 tagged ingress traffic. 569 + */ 570 + idx = 0; 571 + for (int i = priv->hw_info->max_ports; 572 + i < ARRAY_SIZE(priv->vlans); i++) { 573 + if (priv->vlans[i].bridge == br && 574 + priv->vlans[i].vid == pvid) { 575 + idx = i; 576 + break; 577 + } 578 + } 579 + } else { 580 + /* The Active VLAN table index as configured by 581 + * gswip_add_single_port_br() 582 + */ 583 + idx = port + 1; 584 + } 585 + 586 + vinr = idx ? GSWIP_PCE_VCTRL_VINR_ALL : GSWIP_PCE_VCTRL_VINR_TAGGED; 587 + gswip_switch_mask(priv, GSWIP_PCE_VCTRL_VINR, 588 + FIELD_PREP(GSWIP_PCE_VCTRL_VINR, vinr), 589 + GSWIP_PCE_VCTRL(port)); 590 + 591 + /* GSWIP 2.2 (GRX300) and later program here the VID directly. */ 592 + gswip_switch_w(priv, idx, GSWIP_PCE_DEFPVID(port)); 593 + } 594 + 550 595 static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port, 551 596 bool vlan_filtering, 552 597 struct netlink_ext_ack *extack) 553 598 { 554 - struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port)); 555 599 struct gswip_priv *priv = ds->priv; 556 - 557 - /* Do not allow changing the VLAN filtering options while in bridge */ 558 - if (bridge && !!(priv->port_vlan_filter & BIT(port)) != vlan_filtering) { 559 - NL_SET_ERR_MSG_MOD(extack, 560 - "Dynamic toggling of vlan_filtering not supported"); 561 - return -EIO; 562 - } 563 600 564 601 if (vlan_filtering) { 565 602 /* Use tag based VLAN */ 566 603 gswip_switch_mask(priv, 567 604 GSWIP_PCE_VCTRL_VSR, 568 605 GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR | 569 - GSWIP_PCE_VCTRL_VEMR, 606 + GSWIP_PCE_VCTRL_VEMR | GSWIP_PCE_VCTRL_VID0, 570 607 GSWIP_PCE_VCTRL(port)); 571 608 gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_TVM, 0, 572 609 GSWIP_PCE_PCTRL_0p(port)); ··· 611 574 /* Use port based VLAN */ 612 575 gswip_switch_mask(priv, 613 576 GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR | 614 - GSWIP_PCE_VCTRL_VEMR, 577 + GSWIP_PCE_VCTRL_VEMR | GSWIP_PCE_VCTRL_VID0, 615 578 GSWIP_PCE_VCTRL_VSR, 616 579 GSWIP_PCE_VCTRL(port)); 617 580 gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_TVM, 618 581 GSWIP_PCE_PCTRL_0p(port)); 619 582 } 583 + 584 + gswip_port_commit_pvid(priv, port); 620 585 621 586 return 0; 622 587 } ··· 716 677 717 678 ds->mtu_enforcement_ingress = true; 718 679 719 - ds->configure_vlan_while_not_filtering = false; 720 - 721 680 return 0; 722 681 } 723 682 ··· 787 750 return err; 788 751 } 789 752 790 - static int gswip_vlan_add_unaware(struct gswip_priv *priv, 791 - struct net_device *bridge, int port) 792 - { 793 - struct gswip_pce_table_entry vlan_mapping = {0,}; 794 - unsigned int max_ports = priv->hw_info->max_ports; 795 - bool active_vlan_created = false; 796 - int idx = -1; 797 - int i; 798 - int err; 799 - 800 - /* Check if there is already a page for this bridge */ 801 - for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { 802 - if (priv->vlans[i].bridge == bridge) { 803 - idx = i; 804 - break; 805 - } 806 - } 807 - 808 - /* If this bridge is not programmed yet, add a Active VLAN table 809 - * entry in a free slot and prepare the VLAN mapping table entry. 810 - */ 811 - if (idx == -1) { 812 - idx = gswip_vlan_active_create(priv, bridge, -1, 0); 813 - if (idx < 0) 814 - return idx; 815 - active_vlan_created = true; 816 - 817 - vlan_mapping.index = idx; 818 - vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING; 819 - /* VLAN ID byte, maps to the VLAN ID of vlan active table */ 820 - vlan_mapping.val[0] = 0; 821 - } else { 822 - /* Read the existing VLAN mapping entry from the switch */ 823 - vlan_mapping.index = idx; 824 - vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING; 825 - err = gswip_pce_table_entry_read(priv, &vlan_mapping); 826 - if (err) { 827 - dev_err(priv->dev, "failed to read VLAN mapping: %d\n", 828 - err); 829 - return err; 830 - } 831 - } 832 - 833 - /* Update the VLAN mapping entry and write it to the switch */ 834 - vlan_mapping.val[1] |= dsa_cpu_ports(priv->ds); 835 - vlan_mapping.val[1] |= BIT(port); 836 - err = gswip_pce_table_entry_write(priv, &vlan_mapping); 837 - if (err) { 838 - dev_err(priv->dev, "failed to write VLAN mapping: %d\n", err); 839 - /* In case an Active VLAN was creaetd delete it again */ 840 - if (active_vlan_created) 841 - gswip_vlan_active_remove(priv, idx); 842 - return err; 843 - } 844 - 845 - gswip_switch_w(priv, 0, GSWIP_PCE_DEFPVID(port)); 846 - return 0; 847 - } 848 - 849 - static int gswip_vlan_add_aware(struct gswip_priv *priv, 850 - struct net_device *bridge, int port, 851 - u16 vid, bool untagged, 852 - bool pvid) 753 + static int gswip_vlan_add(struct gswip_priv *priv, struct net_device *bridge, 754 + int port, u16 vid, bool untagged, bool pvid, 755 + bool vlan_aware) 853 756 { 854 757 struct gswip_pce_table_entry vlan_mapping = {0,}; 855 758 unsigned int max_ports = priv->hw_info->max_ports; 856 759 unsigned int cpu_ports = dsa_cpu_ports(priv->ds); 857 760 bool active_vlan_created = false; 858 - int idx = -1; 859 - int fid = -1; 860 - int i; 861 - int err; 761 + int fid = -1, idx = -1; 762 + int i, err; 862 763 863 764 /* Check if there is already a page for this bridge */ 864 765 for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { 865 766 if (priv->vlans[i].bridge == bridge) { 866 - if (fid != -1 && fid != priv->vlans[i].fid) 867 - dev_err(priv->dev, "one bridge with multiple flow ids\n"); 868 - fid = priv->vlans[i].fid; 767 + if (vlan_aware) { 768 + if (fid != -1 && fid != priv->vlans[i].fid) 769 + dev_err(priv->dev, "one bridge with multiple flow ids\n"); 770 + fid = priv->vlans[i].fid; 771 + } 869 772 if (priv->vlans[i].vid == vid) { 870 773 idx = i; 871 774 break; ··· 824 847 825 848 vlan_mapping.index = idx; 826 849 vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING; 827 - /* VLAN ID byte, maps to the VLAN ID of vlan active table */ 828 - vlan_mapping.val[0] = vid; 829 850 } else { 830 851 /* Read the existing VLAN mapping entry from the switch */ 831 852 vlan_mapping.index = idx; ··· 836 861 } 837 862 } 838 863 864 + /* VLAN ID byte, maps to the VLAN ID of vlan active table */ 839 865 vlan_mapping.val[0] = vid; 840 866 /* Update the VLAN mapping entry and write it to the switch */ 841 867 vlan_mapping.val[1] |= cpu_ports; 842 - vlan_mapping.val[2] |= cpu_ports; 843 868 vlan_mapping.val[1] |= BIT(port); 869 + if (vlan_aware) 870 + vlan_mapping.val[2] |= cpu_ports; 844 871 if (untagged) 845 872 vlan_mapping.val[2] &= ~BIT(port); 846 873 else ··· 856 879 return err; 857 880 } 858 881 859 - if (pvid) 860 - gswip_switch_w(priv, idx, GSWIP_PCE_DEFPVID(port)); 882 + gswip_port_commit_pvid(priv, port); 861 883 862 884 return 0; 863 885 } 864 886 865 887 static int gswip_vlan_remove(struct gswip_priv *priv, 866 888 struct net_device *bridge, int port, 867 - u16 vid, bool pvid, bool vlan_aware) 889 + u16 vid) 868 890 { 869 891 struct gswip_pce_table_entry vlan_mapping = {0,}; 870 892 unsigned int max_ports = priv->hw_info->max_ports; ··· 874 898 /* Check if there is already a page for this bridge */ 875 899 for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { 876 900 if (priv->vlans[i].bridge == bridge && 877 - (!vlan_aware || priv->vlans[i].vid == vid)) { 901 + priv->vlans[i].vid == vid) { 878 902 idx = i; 879 903 break; 880 904 } 881 905 } 882 906 883 907 if (idx == -1) { 884 - dev_err(priv->dev, "bridge to leave does not exists\n"); 908 + dev_err(priv->dev, "Port %d cannot find VID %u of bridge %s\n", 909 + port, vid, bridge ? bridge->name : "(null)"); 885 910 return -ENOENT; 886 911 } 887 912 ··· 912 935 } 913 936 } 914 937 915 - /* GSWIP 2.2 (GRX300) and later program here the VID directly. */ 916 - if (pvid) 917 - gswip_switch_w(priv, 0, GSWIP_PCE_DEFPVID(port)); 938 + gswip_port_commit_pvid(priv, port); 918 939 919 940 return 0; 920 941 } ··· 926 951 struct gswip_priv *priv = ds->priv; 927 952 int err; 928 953 929 - /* When the bridge uses VLAN filtering we have to configure VLAN 930 - * specific bridges. No bridge is configured here. 954 + /* Set up the VLAN for VLAN-unaware bridging for this port, and remove 955 + * it from the "single-port bridge" through which it was operating as 956 + * standalone. 931 957 */ 932 - if (!br_vlan_enabled(br)) { 933 - err = gswip_vlan_add_unaware(priv, br, port); 934 - if (err) 935 - return err; 936 - priv->port_vlan_filter &= ~BIT(port); 937 - } else { 938 - priv->port_vlan_filter |= BIT(port); 939 - } 958 + err = gswip_vlan_add(priv, br, port, GSWIP_VLAN_UNAWARE_PVID, 959 + true, true, false); 960 + if (err) 961 + return err; 962 + 940 963 return gswip_add_single_port_br(priv, port, false); 941 964 } 942 965 ··· 944 971 struct net_device *br = bridge.dev; 945 972 struct gswip_priv *priv = ds->priv; 946 973 947 - gswip_add_single_port_br(priv, port, true); 948 - 949 - /* When the bridge uses VLAN filtering we have to configure VLAN 950 - * specific bridges. No bridge is configured here. 974 + /* Add the port back to the "single-port bridge", and remove it from 975 + * the VLAN-unaware PVID created for this bridge. 951 976 */ 952 - if (!br_vlan_enabled(br)) 953 - gswip_vlan_remove(priv, br, port, 0, true, false); 977 + gswip_add_single_port_br(priv, port, true); 978 + gswip_vlan_remove(priv, br, port, GSWIP_VLAN_UNAWARE_PVID); 954 979 } 955 980 956 981 static int gswip_port_vlan_prepare(struct dsa_switch *ds, int port, ··· 1007 1036 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; 1008 1037 int err; 1009 1038 1039 + if (vlan->vid == GSWIP_VLAN_UNAWARE_PVID) 1040 + return 0; 1041 + 1010 1042 err = gswip_port_vlan_prepare(ds, port, vlan, extack); 1011 1043 if (err) 1012 1044 return err; ··· 1022 1048 if (dsa_is_cpu_port(ds, port)) 1023 1049 return 0; 1024 1050 1025 - return gswip_vlan_add_aware(priv, bridge, port, vlan->vid, 1026 - untagged, pvid); 1051 + return gswip_vlan_add(priv, bridge, port, vlan->vid, untagged, pvid, 1052 + true); 1027 1053 } 1028 1054 1029 1055 static int gswip_port_vlan_del(struct dsa_switch *ds, int port, ··· 1031 1057 { 1032 1058 struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port)); 1033 1059 struct gswip_priv *priv = ds->priv; 1034 - bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; 1060 + 1061 + if (vlan->vid == GSWIP_VLAN_UNAWARE_PVID) 1062 + return 0; 1035 1063 1036 1064 /* We have to receive all packets on the CPU port and should not 1037 1065 * do any VLAN filtering here. This is also called with bridge ··· 1043 1067 if (dsa_is_cpu_port(ds, port)) 1044 1068 return 0; 1045 1069 1046 - return gswip_vlan_remove(priv, bridge, port, vlan->vid, pvid, true); 1070 + return gswip_vlan_remove(priv, bridge, port, vlan->vid); 1047 1071 } 1048 1072 1049 1073 static void gswip_port_fast_age(struct dsa_switch *ds, int port) ··· 1116 1140 } 1117 1141 1118 1142 static int gswip_port_fdb(struct dsa_switch *ds, int port, 1119 - const unsigned char *addr, u16 vid, bool add) 1143 + struct net_device *bridge, const unsigned char *addr, 1144 + u16 vid, bool add) 1120 1145 { 1121 - struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port)); 1122 1146 struct gswip_priv *priv = ds->priv; 1123 1147 struct gswip_pce_table_entry mac_bridge = {0,}; 1124 1148 unsigned int max_ports = priv->hw_info->max_ports; 1125 1149 int fid = -1; 1126 1150 int i; 1127 1151 int err; 1128 - 1129 - /* Operation not supported on the CPU port, don't throw errors */ 1130 - if (!bridge) 1131 - return 0; 1132 1152 1133 1153 for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { 1134 1154 if (priv->vlans[i].bridge == bridge) { ··· 1160 1188 const unsigned char *addr, u16 vid, 1161 1189 struct dsa_db db) 1162 1190 { 1163 - return gswip_port_fdb(ds, port, addr, vid, true); 1191 + if (db.type != DSA_DB_BRIDGE) 1192 + return -EOPNOTSUPP; 1193 + 1194 + return gswip_port_fdb(ds, port, db.bridge.dev, addr, vid, true); 1164 1195 } 1165 1196 1166 1197 static int gswip_port_fdb_del(struct dsa_switch *ds, int port, 1167 1198 const unsigned char *addr, u16 vid, 1168 1199 struct dsa_db db) 1169 1200 { 1170 - return gswip_port_fdb(ds, port, addr, vid, false); 1201 + if (db.type != DSA_DB_BRIDGE) 1202 + return -EOPNOTSUPP; 1203 + 1204 + return gswip_port_fdb(ds, port, db.bridge.dev, addr, vid, false); 1171 1205 } 1172 1206 1173 1207 static int gswip_port_fdb_dump(struct dsa_switch *ds, int port,
+6 -1
drivers/net/dsa/lantiq/lantiq_gswip.h
··· 159 159 #define GSWIP_PCE_PCTRL_0_PSTATE_MASK GENMASK(2, 0) 160 160 #define GSWIP_PCE_VCTRL(p) (0x485 + ((p) * 0xA)) 161 161 #define GSWIP_PCE_VCTRL_UVR BIT(0) /* Unknown VLAN Rule */ 162 + #define GSWIP_PCE_VCTRL_VINR GENMASK(2, 1) /* VLAN Ingress Tag Rule */ 163 + #define GSWIP_PCE_VCTRL_VINR_ALL 0 /* Admit tagged and untagged packets */ 164 + #define GSWIP_PCE_VCTRL_VINR_TAGGED 1 /* Admit only tagged packets */ 165 + #define GSWIP_PCE_VCTRL_VINR_UNTAGGED 2 /* Admit only untagged packets */ 162 166 #define GSWIP_PCE_VCTRL_VIMR BIT(3) /* VLAN Ingress Member violation rule */ 163 167 #define GSWIP_PCE_VCTRL_VEMR BIT(4) /* VLAN Egress Member violation rule */ 164 168 #define GSWIP_PCE_VCTRL_VSR BIT(5) /* VLAN Security */ ··· 226 222 */ 227 223 #define GSWIP_MAX_PACKET_LENGTH 2400 228 224 225 + #define GSWIP_VLAN_UNAWARE_PVID 0 226 + 229 227 struct gswip_pce_microcode { 230 228 u16 val_3; 231 229 u16 val_2; ··· 274 268 struct gswip_vlan vlans[64]; 275 269 int num_gphy_fw; 276 270 struct gswip_gphy_fw *gphy_fw; 277 - u32 port_vlan_filter; 278 271 struct mutex pce_table_lock; 279 272 u16 version; 280 273 };