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-vsc73xx-implement-vlan-operations'

Pawel Dembicki says:

====================
net: dsa: vsc73xx: Implement VLAN operations

This patch series is a result of splitting a larger patch series [0],
where some parts was merged before.

The first patch implements port state configuration, which is required
for bridge functionality. STP frames are not forwarded at this moment.
BPDU frames are only forwarded from/to the PI/SI interface.
For more information, see chapter 2.7.1 (CPU Forwarding) in the
datasheet.

Patches 2, 7-9 and 11 provide a basic implementation of tag_8021q
functionality with QinQ support, without VLAN filtering in
the bridge and simple VLAN awareness in VLAN filtering mode.

Patches 3-6 came from Vladimir Oltean. They prepare for making
tag8021q more common. VSC73XX uses very similar tag recognition,
and some code from tag_sja1105 could be moved to tag_8021q for
common use.

Patch 10 is preparation for use tag_8021q bridge functions as generic
implementation of the 'ds->ops->port_bridge_*()'.

Patch 12 is required to avoid problem with learning on standalone ports.

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

Link: https://patch.msgid.link/20240713211620.1125910-1-paweldembicki@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+934 -98
+1 -1
drivers/net/dsa/Kconfig
··· 127 127 128 128 config NET_DSA_VITESSE_VSC73XX 129 129 tristate 130 - select NET_DSA_TAG_NONE 130 + select NET_DSA_TAG_VSC73XX_8021Q 131 131 select FIXED_PHY 132 132 select VITESSE_PHY 133 133 select GPIOLIB
+3 -5
drivers/net/dsa/sja1105/sja1105_main.c
··· 2133 2133 if (rc) 2134 2134 return rc; 2135 2135 2136 - rc = dsa_tag_8021q_bridge_join(ds, port, bridge); 2136 + rc = dsa_tag_8021q_bridge_join(ds, port, bridge, tx_fwd_offload, 2137 + extack); 2137 2138 if (rc) { 2138 2139 sja1105_bridge_member(ds, port, bridge, false); 2139 2140 return rc; 2140 2141 } 2141 - 2142 - *tx_fwd_offload = true; 2143 2142 2144 2143 return 0; 2145 2144 } ··· 3166 3167 ds->vlan_filtering_is_global = true; 3167 3168 ds->untag_bridge_pvid = true; 3168 3169 ds->fdb_isolation = true; 3169 - /* tag_8021q has 3 bits for the VBID, and the value 0 is reserved */ 3170 - ds->max_num_bridges = 7; 3170 + ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; 3171 3171 3172 3172 /* Advertise the 8 egress queues */ 3173 3173 ds->num_tx_queues = SJA1105_NUM_TC;
+718 -17
drivers/net/dsa/vitesse-vsc73xx-core.c
··· 22 22 #include <linux/of_mdio.h> 23 23 #include <linux/bitops.h> 24 24 #include <linux/if_bridge.h> 25 + #include <linux/if_vlan.h> 25 26 #include <linux/etherdevice.h> 26 27 #include <linux/gpio/consumer.h> 27 28 #include <linux/gpio/driver.h> 29 + #include <linux/dsa/8021q.h> 28 30 #include <linux/random.h> 29 31 #include <net/dsa.h> 30 32 ··· 64 62 #define VSC73XX_CAT_DROP 0x6e 65 63 #define VSC73XX_CAT_PR_MISC_L2 0x6f 66 64 #define VSC73XX_CAT_PR_USR_PRIO 0x75 65 + #define VSC73XX_CAT_VLAN_MISC 0x79 66 + #define VSC73XX_CAT_PORT_VLAN 0x7a 67 67 #define VSC73XX_Q_MISC_CONF 0xdf 68 68 69 69 /* MAC_CFG register bits */ ··· 126 122 #define VSC73XX_ADVPORTM_IO_LOOPBACK BIT(1) 127 123 #define VSC73XX_ADVPORTM_HOST_LOOPBACK BIT(0) 128 124 125 + /* TXUPDCFG transmit modify setup bits */ 126 + #define VSC73XX_TXUPDCFG_DSCP_REWR_MODE GENMASK(20, 19) 127 + #define VSC73XX_TXUPDCFG_DSCP_REWR_ENA BIT(18) 128 + #define VSC73XX_TXUPDCFG_TX_INT_TO_USRPRIO_ENA BIT(17) 129 + #define VSC73XX_TXUPDCFG_TX_UNTAGGED_VID GENMASK(15, 4) 130 + #define VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA BIT(3) 131 + #define VSC73XX_TXUPDCFG_TX_UPDATE_CRC_CPU_ENA BIT(1) 132 + #define VSC73XX_TXUPDCFG_TX_INSERT_TAG BIT(0) 133 + 134 + #define VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_SHIFT 4 135 + 129 136 /* CAT_DROP categorizer frame dropping register bits */ 130 137 #define VSC73XX_CAT_DROP_DROP_MC_SMAC_ENA BIT(6) 131 138 #define VSC73XX_CAT_DROP_FWD_CTRL_ENA BIT(4) ··· 149 134 #define VSC73XX_Q_MISC_CONF_EARLY_TX_MASK GENMASK(4, 1) 150 135 #define VSC73XX_Q_MISC_CONF_EARLY_TX_512 (1 << 1) 151 136 #define VSC73XX_Q_MISC_CONF_MAC_PAUSE_MODE BIT(0) 137 + 138 + /* CAT_VLAN_MISC categorizer VLAN miscellaneous bits */ 139 + #define VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA BIT(8) 140 + #define VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA BIT(7) 141 + 142 + /* CAT_PORT_VLAN categorizer port VLAN */ 143 + #define VSC73XX_CAT_PORT_VLAN_VLAN_CFI BIT(15) 144 + #define VSC73XX_CAT_PORT_VLAN_VLAN_USR_PRIO GENMASK(14, 12) 145 + #define VSC73XX_CAT_PORT_VLAN_VLAN_VID GENMASK(11, 0) 152 146 153 147 /* Frame analyzer block 2 registers */ 154 148 #define VSC73XX_STORMLIMIT 0x02 ··· 188 164 #define VSC73XX_AGENCTRL 0xf0 189 165 #define VSC73XX_CAPRST 0xff 190 166 167 + #define VSC73XX_SRCMASKS_CPU_COPY BIT(27) 168 + #define VSC73XX_SRCMASKS_MIRROR BIT(26) 169 + #define VSC73XX_SRCMASKS_PORTS_MASK GENMASK(7, 0) 170 + 191 171 #define VSC73XX_MACACCESS_CPU_COPY BIT(14) 192 172 #define VSC73XX_MACACCESS_FWD_KILL BIT(13) 193 173 #define VSC73XX_MACACCESS_IGNORE_VLAN BIT(12) ··· 213 185 #define VSC73XX_VLANACCESS_VLAN_MIRROR BIT(29) 214 186 #define VSC73XX_VLANACCESS_VLAN_SRC_CHECK BIT(28) 215 187 #define VSC73XX_VLANACCESS_VLAN_PORT_MASK GENMASK(9, 2) 216 - #define VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK GENMASK(2, 0) 188 + #define VSC73XX_VLANACCESS_VLAN_PORT_MASK_SHIFT 2 189 + #define VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK GENMASK(1, 0) 217 190 #define VSC73XX_VLANACCESS_VLAN_TBL_CMD_IDLE 0 218 191 #define VSC73XX_VLANACCESS_VLAN_TBL_CMD_READ_ENTRY 1 219 192 #define VSC73XX_VLANACCESS_VLAN_TBL_CMD_WRITE_ENTRY 2 ··· 370 341 { 27, "TxQoSClass1" }, /* non-standard counter */ 371 342 { 28, "TxQoSClass2" }, /* non-standard counter */ 372 343 { 29, "TxQoSClass3" }, /* non-standard counter */ 344 + }; 345 + 346 + struct vsc73xx_vlan_summary { 347 + size_t num_tagged; 348 + size_t num_untagged; 349 + }; 350 + 351 + enum vsc73xx_port_vlan_conf { 352 + VSC73XX_VLAN_FILTER, 353 + VSC73XX_VLAN_FILTER_UNTAG_ALL, 354 + VSC73XX_VLAN_IGNORE, 373 355 }; 374 356 375 357 int vsc73xx_is_addr_valid(u8 block, u8 subblock) ··· 597 557 * cannot access the tag. (See "Internal frame header" section 598 558 * 3.9.1 in the manual.) 599 559 */ 600 - return DSA_TAG_PROTO_NONE; 560 + return DSA_TAG_PROTO_VSC73XX_8021Q; 561 + } 562 + 563 + static int vsc73xx_wait_for_vlan_table_cmd(struct vsc73xx *vsc) 564 + { 565 + int ret, err; 566 + u32 val; 567 + 568 + ret = read_poll_timeout(vsc73xx_read, err, 569 + err < 0 || 570 + ((val & VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK) == 571 + VSC73XX_VLANACCESS_VLAN_TBL_CMD_IDLE), 572 + VSC73XX_POLL_SLEEP_US, VSC73XX_POLL_TIMEOUT_US, 573 + false, vsc, VSC73XX_BLOCK_ANALYZER, 574 + 0, VSC73XX_VLANACCESS, &val); 575 + if (ret) 576 + return ret; 577 + return err; 578 + } 579 + 580 + static int 581 + vsc73xx_read_vlan_table_entry(struct vsc73xx *vsc, u16 vid, u8 *portmap) 582 + { 583 + u32 val; 584 + int ret; 585 + 586 + vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANTIDX, vid); 587 + 588 + ret = vsc73xx_wait_for_vlan_table_cmd(vsc); 589 + if (ret) 590 + return ret; 591 + 592 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANACCESS, 593 + VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK, 594 + VSC73XX_VLANACCESS_VLAN_TBL_CMD_READ_ENTRY); 595 + 596 + ret = vsc73xx_wait_for_vlan_table_cmd(vsc); 597 + if (ret) 598 + return ret; 599 + 600 + vsc73xx_read(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANACCESS, &val); 601 + *portmap = (val & VSC73XX_VLANACCESS_VLAN_PORT_MASK) >> 602 + VSC73XX_VLANACCESS_VLAN_PORT_MASK_SHIFT; 603 + 604 + return 0; 605 + } 606 + 607 + static int 608 + vsc73xx_write_vlan_table_entry(struct vsc73xx *vsc, u16 vid, u8 portmap) 609 + { 610 + int ret; 611 + 612 + vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANTIDX, vid); 613 + 614 + ret = vsc73xx_wait_for_vlan_table_cmd(vsc); 615 + if (ret) 616 + return ret; 617 + 618 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANACCESS, 619 + VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK | 620 + VSC73XX_VLANACCESS_VLAN_SRC_CHECK | 621 + VSC73XX_VLANACCESS_VLAN_PORT_MASK, 622 + VSC73XX_VLANACCESS_VLAN_TBL_CMD_WRITE_ENTRY | 623 + VSC73XX_VLANACCESS_VLAN_SRC_CHECK | 624 + (portmap << VSC73XX_VLANACCESS_VLAN_PORT_MASK_SHIFT)); 625 + 626 + return vsc73xx_wait_for_vlan_table_cmd(vsc); 627 + } 628 + 629 + static int 630 + vsc73xx_update_vlan_table(struct vsc73xx *vsc, int port, u16 vid, bool set) 631 + { 632 + u8 portmap; 633 + int ret; 634 + 635 + ret = vsc73xx_read_vlan_table_entry(vsc, vid, &portmap); 636 + if (ret) 637 + return ret; 638 + 639 + if (set) 640 + portmap |= BIT(port); 641 + else 642 + portmap &= ~BIT(port); 643 + 644 + return vsc73xx_write_vlan_table_entry(vsc, vid, portmap); 601 645 } 602 646 603 647 static int vsc73xx_setup(struct dsa_switch *ds) 604 648 { 605 649 struct vsc73xx *vsc = ds->priv; 606 - int i; 650 + int i, ret; 607 651 608 652 dev_info(vsc->dev, "set up the switch\n"); 653 + 654 + ds->untag_bridge_pvid = true; 655 + ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; 609 656 610 657 /* Issue RESET */ 611 658 vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GLORESET, ··· 721 594 VSC73XX_MACACCESS, 722 595 VSC73XX_MACACCESS_CMD_CLEAR_TABLE); 723 596 724 - /* Clear VLAN table */ 597 + /* Set VLAN table to default values */ 725 598 vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, 726 599 VSC73XX_VLANACCESS, 727 600 VSC73XX_VLANACCESS_VLAN_TBL_CMD_CLEAR_TABLE); ··· 750 623 vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GMIIDELAY, 751 624 VSC73XX_GMIIDELAY_GMII0_GTXDELAY_2_0_NS | 752 625 VSC73XX_GMIIDELAY_GMII0_RXDELAY_2_0_NS); 753 - /* Enable reception of frames on all ports */ 754 - vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_RECVMASK, 755 - 0x5f); 626 + /* Ingess VLAN reception mask (table 145) */ 627 + vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANMASK, 628 + 0xff); 756 629 /* IP multicast flood mask (table 144) */ 757 630 vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_IFLODMSK, 758 631 0xff); ··· 765 638 766 639 udelay(4); 767 640 768 - return 0; 641 + /* Clear VLAN table */ 642 + for (i = 0; i < VLAN_N_VID; i++) 643 + vsc73xx_write_vlan_table_entry(vsc, i, 0); 644 + 645 + INIT_LIST_HEAD(&vsc->vlans); 646 + 647 + rtnl_lock(); 648 + ret = dsa_tag_8021q_register(ds, htons(ETH_P_8021Q)); 649 + rtnl_unlock(); 650 + 651 + return ret; 652 + } 653 + 654 + static void vsc73xx_teardown(struct dsa_switch *ds) 655 + { 656 + rtnl_lock(); 657 + dsa_tag_8021q_unregister(ds); 658 + rtnl_unlock(); 769 659 } 770 660 771 661 static void vsc73xx_init_port(struct vsc73xx *vsc, int port) ··· 932 788 /* Allow backward dropping of frames from this port */ 933 789 vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 934 790 VSC73XX_SBACKWDROP, BIT(port), BIT(port)); 935 - 936 - /* Receive mask (disable forwarding) */ 937 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 938 - VSC73XX_RECVMASK, BIT(port), 0); 939 791 } 940 792 941 793 static void vsc73xx_mac_link_up(struct phylink_config *config, ··· 968 828 val |= seed << VSC73XX_MAC_CFG_SEED_OFFSET; 969 829 val |= VSC73XX_MAC_CFG_SEED_LOAD; 970 830 val |= VSC73XX_MAC_CFG_WEXC_DIS; 831 + 832 + /* Those bits are responsible for MTU only. Kernel takes care about MTU, 833 + * let's enable +8 bytes frame length unconditionally. 834 + */ 835 + val |= VSC73XX_MAC_CFG_VLAN_AWR | VSC73XX_MAC_CFG_VLAN_DBLAWR; 836 + 971 837 vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG, val); 972 838 973 839 /* Flow control for the PHY facing ports: ··· 990 844 vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 991 845 VSC73XX_ARBDISC, BIT(port), 0); 992 846 993 - /* Enable port (forwarding) in the receive mask */ 994 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 995 - VSC73XX_RECVMASK, BIT(port), BIT(port)); 996 - 997 847 /* Disallow backward dropping of frames from this port */ 998 848 vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 999 849 VSC73XX_SBACKWDROP, BIT(port), 0); ··· 1002 860 VSC73XX_MAC_CFG_TX_EN | VSC73XX_MAC_CFG_RX_EN); 1003 861 } 1004 862 863 + static bool vsc73xx_tag_8021q_active(struct dsa_port *dp) 864 + { 865 + return !dsa_port_is_vlan_filtering(dp); 866 + } 867 + 868 + static struct vsc73xx_bridge_vlan * 869 + vsc73xx_bridge_vlan_find(struct vsc73xx *vsc, u16 vid) 870 + { 871 + struct vsc73xx_bridge_vlan *vlan; 872 + 873 + list_for_each_entry(vlan, &vsc->vlans, list) 874 + if (vlan->vid == vid) 875 + return vlan; 876 + 877 + return NULL; 878 + } 879 + 880 + static void 881 + vsc73xx_bridge_vlan_remove_port(struct vsc73xx_bridge_vlan *vsc73xx_vlan, 882 + int port) 883 + { 884 + vsc73xx_vlan->portmask &= ~BIT(port); 885 + 886 + if (vsc73xx_vlan->portmask) 887 + return; 888 + 889 + list_del(&vsc73xx_vlan->list); 890 + kfree(vsc73xx_vlan); 891 + } 892 + 893 + static void vsc73xx_bridge_vlan_summary(struct vsc73xx *vsc, int port, 894 + struct vsc73xx_vlan_summary *summary, 895 + u16 ignored_vid) 896 + { 897 + size_t num_tagged = 0, num_untagged = 0; 898 + struct vsc73xx_bridge_vlan *vlan; 899 + 900 + list_for_each_entry(vlan, &vsc->vlans, list) { 901 + if (!(vlan->portmask & BIT(port)) || vlan->vid == ignored_vid) 902 + continue; 903 + 904 + if (vlan->untagged & BIT(port)) 905 + num_untagged++; 906 + else 907 + num_tagged++; 908 + } 909 + 910 + summary->num_untagged = num_untagged; 911 + summary->num_tagged = num_tagged; 912 + } 913 + 914 + static u16 vsc73xx_find_first_vlan_untagged(struct vsc73xx *vsc, int port) 915 + { 916 + struct vsc73xx_bridge_vlan *vlan; 917 + 918 + list_for_each_entry(vlan, &vsc->vlans, list) 919 + if ((vlan->portmask & BIT(port)) && 920 + (vlan->untagged & BIT(port))) 921 + return vlan->vid; 922 + 923 + return VLAN_N_VID; 924 + } 925 + 926 + static int vsc73xx_set_vlan_conf(struct vsc73xx *vsc, int port, 927 + enum vsc73xx_port_vlan_conf port_vlan_conf) 928 + { 929 + u32 val = 0; 930 + int ret; 931 + 932 + if (port_vlan_conf == VSC73XX_VLAN_IGNORE) 933 + val = VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA | 934 + VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA; 935 + 936 + ret = vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, 937 + VSC73XX_CAT_VLAN_MISC, 938 + VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA | 939 + VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA, val); 940 + if (ret) 941 + return ret; 942 + 943 + val = (port_vlan_conf == VSC73XX_VLAN_FILTER) ? 944 + VSC73XX_TXUPDCFG_TX_INSERT_TAG : 0; 945 + 946 + return vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, 947 + VSC73XX_TXUPDCFG, 948 + VSC73XX_TXUPDCFG_TX_INSERT_TAG, val); 949 + } 950 + 951 + /** 952 + * vsc73xx_vlan_commit_conf - Update VLAN configuration of a port 953 + * @vsc: Switch private data structure 954 + * @port: Port index on which to operate 955 + * 956 + * Update the VLAN behavior of a port to make sure that when it is under 957 + * a VLAN filtering bridge, the port is either filtering with tag 958 + * preservation, or filtering with all VLANs egress-untagged. Otherwise, 959 + * the port ignores VLAN tags from packets and applies the port-based 960 + * VID. 961 + * 962 + * Must be called when changes are made to: 963 + * - the bridge VLAN filtering state of the port 964 + * - the number or attributes of VLANs from the bridge VLAN table, 965 + * while the port is currently VLAN-aware 966 + * 967 + * Return: 0 on success, or negative errno on error. 968 + */ 969 + static int vsc73xx_vlan_commit_conf(struct vsc73xx *vsc, int port) 970 + { 971 + enum vsc73xx_port_vlan_conf port_vlan_conf = VSC73XX_VLAN_IGNORE; 972 + struct dsa_port *dp = dsa_to_port(vsc->ds, port); 973 + 974 + if (port == CPU_PORT) { 975 + port_vlan_conf = VSC73XX_VLAN_FILTER; 976 + } else if (dsa_port_is_vlan_filtering(dp)) { 977 + struct vsc73xx_vlan_summary summary; 978 + 979 + port_vlan_conf = VSC73XX_VLAN_FILTER; 980 + 981 + vsc73xx_bridge_vlan_summary(vsc, port, &summary, VLAN_N_VID); 982 + if (summary.num_tagged == 0) 983 + port_vlan_conf = VSC73XX_VLAN_FILTER_UNTAG_ALL; 984 + } 985 + 986 + return vsc73xx_set_vlan_conf(vsc, port, port_vlan_conf); 987 + } 988 + 989 + static int 990 + vsc73xx_vlan_change_untagged(struct vsc73xx *vsc, int port, u16 vid, bool set) 991 + { 992 + u32 val = 0; 993 + 994 + if (set) 995 + val = VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA | 996 + ((vid << VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_SHIFT) & 997 + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID); 998 + 999 + return vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, 1000 + VSC73XX_TXUPDCFG, 1001 + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA | 1002 + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID, val); 1003 + } 1004 + 1005 + /** 1006 + * vsc73xx_vlan_commit_untagged - Update native VLAN of a port 1007 + * @vsc: Switch private data structure 1008 + * @port: Port index on which to operate 1009 + * 1010 + * Update the native VLAN of a port (the one VLAN which is transmitted 1011 + * as egress-tagged on a trunk port) when port is in VLAN filtering mode and 1012 + * only one untagged vid is configured. 1013 + * In other cases no need to configure it because switch can untag all vlans on 1014 + * the port. 1015 + * 1016 + * Return: 0 on success, or negative errno on error. 1017 + */ 1018 + static int vsc73xx_vlan_commit_untagged(struct vsc73xx *vsc, int port) 1019 + { 1020 + struct dsa_port *dp = dsa_to_port(vsc->ds, port); 1021 + struct vsc73xx_vlan_summary summary; 1022 + u16 vid = 0; 1023 + bool valid; 1024 + 1025 + if (!dsa_port_is_vlan_filtering(dp)) 1026 + /* Port is configured to untag all vlans in that case. 1027 + * No need to commit untagged config change. 1028 + */ 1029 + return 0; 1030 + 1031 + vsc73xx_bridge_vlan_summary(vsc, port, &summary, VLAN_N_VID); 1032 + 1033 + if (summary.num_untagged > 1) 1034 + /* Port must untag all vlans in that case. 1035 + * No need to commit untagged config change. 1036 + */ 1037 + return 0; 1038 + 1039 + valid = (summary.num_untagged == 1); 1040 + if (valid) 1041 + vid = vsc73xx_find_first_vlan_untagged(vsc, port); 1042 + 1043 + return vsc73xx_vlan_change_untagged(vsc, port, vid, valid); 1044 + } 1045 + 1046 + static int 1047 + vsc73xx_vlan_change_pvid(struct vsc73xx *vsc, int port, u16 vid, bool set) 1048 + { 1049 + u32 val = 0; 1050 + int ret; 1051 + 1052 + val = set ? 0 : VSC73XX_CAT_DROP_UNTAGGED_ENA; 1053 + 1054 + ret = vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, 1055 + VSC73XX_CAT_DROP, 1056 + VSC73XX_CAT_DROP_UNTAGGED_ENA, val); 1057 + if (!set || ret) 1058 + return ret; 1059 + 1060 + return vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, 1061 + VSC73XX_CAT_PORT_VLAN, 1062 + VSC73XX_CAT_PORT_VLAN_VLAN_VID, 1063 + vid & VSC73XX_CAT_PORT_VLAN_VLAN_VID); 1064 + } 1065 + 1066 + /** 1067 + * vsc73xx_vlan_commit_pvid - Update port-based default VLAN of a port 1068 + * @vsc: Switch private data structure 1069 + * @port: Port index on which to operate 1070 + * 1071 + * Update the PVID of a port so that it follows either the bridge PVID 1072 + * configuration, when the bridge is currently VLAN-aware, or the PVID 1073 + * from tag_8021q, when the port is standalone or under a VLAN-unaware 1074 + * bridge. A port with no PVID drops all untagged and VID 0 tagged 1075 + * traffic. 1076 + * 1077 + * Must be called when changes are made to: 1078 + * - the bridge VLAN filtering state of the port 1079 + * - the number or attributes of VLANs from the bridge VLAN table, 1080 + * while the port is currently VLAN-aware 1081 + * 1082 + * Return: 0 on success, or negative errno on error. 1083 + */ 1084 + static int vsc73xx_vlan_commit_pvid(struct vsc73xx *vsc, int port) 1085 + { 1086 + struct vsc73xx_portinfo *portinfo = &vsc->portinfo[port]; 1087 + bool valid = portinfo->pvid_tag_8021q_configured; 1088 + struct dsa_port *dp = dsa_to_port(vsc->ds, port); 1089 + u16 vid = portinfo->pvid_tag_8021q; 1090 + 1091 + if (dsa_port_is_vlan_filtering(dp)) { 1092 + vid = portinfo->pvid_vlan_filtering; 1093 + valid = portinfo->pvid_vlan_filtering_configured; 1094 + } 1095 + 1096 + return vsc73xx_vlan_change_pvid(vsc, port, vid, valid); 1097 + } 1098 + 1099 + static int vsc73xx_vlan_commit_settings(struct vsc73xx *vsc, int port) 1100 + { 1101 + int ret; 1102 + 1103 + ret = vsc73xx_vlan_commit_untagged(vsc, port); 1104 + if (ret) 1105 + return ret; 1106 + 1107 + ret = vsc73xx_vlan_commit_pvid(vsc, port); 1108 + if (ret) 1109 + return ret; 1110 + 1111 + return vsc73xx_vlan_commit_conf(vsc, port); 1112 + } 1113 + 1005 1114 static int vsc73xx_port_enable(struct dsa_switch *ds, int port, 1006 1115 struct phy_device *phy) 1007 1116 { ··· 1261 868 dev_info(vsc->dev, "enable port %d\n", port); 1262 869 vsc73xx_init_port(vsc, port); 1263 870 1264 - return 0; 871 + return vsc73xx_vlan_commit_settings(vsc, port); 1265 872 } 1266 873 1267 874 static void vsc73xx_port_disable(struct dsa_switch *ds, int port) ··· 1432 1039 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000; 1433 1040 } 1434 1041 1042 + static int 1043 + vsc73xx_port_vlan_filtering(struct dsa_switch *ds, int port, 1044 + bool vlan_filtering, struct netlink_ext_ack *extack) 1045 + { 1046 + struct vsc73xx *vsc = ds->priv; 1047 + 1048 + /* The commit to hardware processed below is required because vsc73xx 1049 + * is using tag_8021q. When vlan_filtering is disabled, tag_8021q uses 1050 + * pvid/untagged vlans for port recognition. The values configured for 1051 + * vlans and pvid/untagged states are stored in portinfo structure. 1052 + * When vlan_filtering is enabled, we need to restore pvid/untagged from 1053 + * portinfo structure. Analogous routine is processed when 1054 + * vlan_filtering is disabled, but values used for tag_8021q are 1055 + * restored. 1056 + */ 1057 + 1058 + return vsc73xx_vlan_commit_settings(vsc, port); 1059 + } 1060 + 1061 + static int vsc73xx_port_vlan_add(struct dsa_switch *ds, int port, 1062 + const struct switchdev_obj_port_vlan *vlan, 1063 + struct netlink_ext_ack *extack) 1064 + { 1065 + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; 1066 + bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; 1067 + struct dsa_port *dp = dsa_to_port(ds, port); 1068 + struct vsc73xx_bridge_vlan *vsc73xx_vlan; 1069 + struct vsc73xx_vlan_summary summary; 1070 + struct vsc73xx_portinfo *portinfo; 1071 + struct vsc73xx *vsc = ds->priv; 1072 + bool commit_to_hardware; 1073 + int ret = 0; 1074 + 1075 + /* Be sure to deny alterations to the configuration done by tag_8021q. 1076 + */ 1077 + if (vid_is_dsa_8021q(vlan->vid)) { 1078 + NL_SET_ERR_MSG_MOD(extack, 1079 + "Range 3072-4095 reserved for dsa_8021q operation"); 1080 + return -EBUSY; 1081 + } 1082 + 1083 + /* The processed vlan->vid is excluded from the search because the VLAN 1084 + * can be re-added with a different set of flags, so it's easiest to 1085 + * ignore its old flags from the VLAN database software copy. 1086 + */ 1087 + vsc73xx_bridge_vlan_summary(vsc, port, &summary, vlan->vid); 1088 + 1089 + /* VSC73XX allows only three untagged states: none, one or all */ 1090 + if ((untagged && summary.num_tagged > 0 && summary.num_untagged > 0) || 1091 + (!untagged && summary.num_untagged > 1)) { 1092 + NL_SET_ERR_MSG_MOD(extack, 1093 + "Port can have only none, one or all untagged vlan"); 1094 + return -EBUSY; 1095 + } 1096 + 1097 + vsc73xx_vlan = vsc73xx_bridge_vlan_find(vsc, vlan->vid); 1098 + 1099 + if (!vsc73xx_vlan) { 1100 + vsc73xx_vlan = kzalloc(sizeof(*vsc73xx_vlan), GFP_KERNEL); 1101 + if (!vsc73xx_vlan) 1102 + return -ENOMEM; 1103 + 1104 + vsc73xx_vlan->vid = vlan->vid; 1105 + 1106 + list_add_tail(&vsc73xx_vlan->list, &vsc->vlans); 1107 + } 1108 + 1109 + vsc73xx_vlan->portmask |= BIT(port); 1110 + 1111 + /* CPU port must be always tagged because source port identification is 1112 + * based on tag_8021q. 1113 + */ 1114 + if (port == CPU_PORT) 1115 + goto update_vlan_table; 1116 + 1117 + if (untagged) 1118 + vsc73xx_vlan->untagged |= BIT(port); 1119 + else 1120 + vsc73xx_vlan->untagged &= ~BIT(port); 1121 + 1122 + portinfo = &vsc->portinfo[port]; 1123 + 1124 + if (pvid) { 1125 + portinfo->pvid_vlan_filtering_configured = true; 1126 + portinfo->pvid_vlan_filtering = vlan->vid; 1127 + } else if (portinfo->pvid_vlan_filtering_configured && 1128 + portinfo->pvid_vlan_filtering == vlan->vid) { 1129 + portinfo->pvid_vlan_filtering_configured = false; 1130 + } 1131 + 1132 + commit_to_hardware = !vsc73xx_tag_8021q_active(dp); 1133 + if (commit_to_hardware) { 1134 + ret = vsc73xx_vlan_commit_settings(vsc, port); 1135 + if (ret) 1136 + goto err; 1137 + } 1138 + 1139 + update_vlan_table: 1140 + ret = vsc73xx_update_vlan_table(vsc, port, vlan->vid, true); 1141 + if (!ret) 1142 + return 0; 1143 + err: 1144 + vsc73xx_bridge_vlan_remove_port(vsc73xx_vlan, port); 1145 + return ret; 1146 + } 1147 + 1148 + static int vsc73xx_port_vlan_del(struct dsa_switch *ds, int port, 1149 + const struct switchdev_obj_port_vlan *vlan) 1150 + { 1151 + struct vsc73xx_bridge_vlan *vsc73xx_vlan; 1152 + struct vsc73xx_portinfo *portinfo; 1153 + struct vsc73xx *vsc = ds->priv; 1154 + bool commit_to_hardware; 1155 + int ret; 1156 + 1157 + ret = vsc73xx_update_vlan_table(vsc, port, vlan->vid, false); 1158 + if (ret) 1159 + return ret; 1160 + 1161 + portinfo = &vsc->portinfo[port]; 1162 + 1163 + if (portinfo->pvid_vlan_filtering_configured && 1164 + portinfo->pvid_vlan_filtering == vlan->vid) 1165 + portinfo->pvid_vlan_filtering_configured = false; 1166 + 1167 + vsc73xx_vlan = vsc73xx_bridge_vlan_find(vsc, vlan->vid); 1168 + 1169 + if (vsc73xx_vlan) 1170 + vsc73xx_bridge_vlan_remove_port(vsc73xx_vlan, port); 1171 + 1172 + commit_to_hardware = !vsc73xx_tag_8021q_active(dsa_to_port(ds, port)); 1173 + 1174 + if (commit_to_hardware) 1175 + return vsc73xx_vlan_commit_settings(vsc, port); 1176 + 1177 + return 0; 1178 + } 1179 + 1180 + static int vsc73xx_tag_8021q_vlan_add(struct dsa_switch *ds, int port, u16 vid, 1181 + u16 flags) 1182 + { 1183 + bool pvid = flags & BRIDGE_VLAN_INFO_PVID; 1184 + struct vsc73xx_portinfo *portinfo; 1185 + struct vsc73xx *vsc = ds->priv; 1186 + bool commit_to_hardware; 1187 + int ret; 1188 + 1189 + portinfo = &vsc->portinfo[port]; 1190 + 1191 + if (pvid) { 1192 + portinfo->pvid_tag_8021q_configured = true; 1193 + portinfo->pvid_tag_8021q = vid; 1194 + } 1195 + 1196 + commit_to_hardware = vsc73xx_tag_8021q_active(dsa_to_port(ds, port)); 1197 + if (commit_to_hardware) { 1198 + ret = vsc73xx_vlan_commit_settings(vsc, port); 1199 + if (ret) 1200 + return ret; 1201 + } 1202 + 1203 + return vsc73xx_update_vlan_table(vsc, port, vid, true); 1204 + } 1205 + 1206 + static int vsc73xx_tag_8021q_vlan_del(struct dsa_switch *ds, int port, u16 vid) 1207 + { 1208 + struct vsc73xx_portinfo *portinfo; 1209 + struct vsc73xx *vsc = ds->priv; 1210 + 1211 + portinfo = &vsc->portinfo[port]; 1212 + 1213 + if (portinfo->pvid_tag_8021q_configured && 1214 + portinfo->pvid_tag_8021q == vid) { 1215 + struct dsa_port *dp = dsa_to_port(ds, port); 1216 + bool commit_to_hardware; 1217 + int err; 1218 + 1219 + portinfo->pvid_tag_8021q_configured = false; 1220 + 1221 + commit_to_hardware = vsc73xx_tag_8021q_active(dp); 1222 + if (commit_to_hardware) { 1223 + err = vsc73xx_vlan_commit_settings(vsc, port); 1224 + if (err) 1225 + return err; 1226 + } 1227 + } 1228 + 1229 + return vsc73xx_update_vlan_table(vsc, port, vid, false); 1230 + } 1231 + 1232 + static int vsc73xx_port_pre_bridge_flags(struct dsa_switch *ds, int port, 1233 + struct switchdev_brport_flags flags, 1234 + struct netlink_ext_ack *extack) 1235 + { 1236 + if (flags.mask & ~BR_LEARNING) 1237 + return -EINVAL; 1238 + 1239 + return 0; 1240 + } 1241 + 1242 + static int vsc73xx_port_bridge_flags(struct dsa_switch *ds, int port, 1243 + struct switchdev_brport_flags flags, 1244 + struct netlink_ext_ack *extack) 1245 + { 1246 + if (flags.mask & BR_LEARNING) { 1247 + u32 val = flags.val & BR_LEARNING ? BIT(port) : 0; 1248 + struct vsc73xx *vsc = ds->priv; 1249 + 1250 + return vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1251 + VSC73XX_LEARNMASK, BIT(port), val); 1252 + } 1253 + 1254 + return 0; 1255 + } 1256 + 1257 + static void vsc73xx_refresh_fwd_map(struct dsa_switch *ds, int port, u8 state) 1258 + { 1259 + struct dsa_port *other_dp, *dp = dsa_to_port(ds, port); 1260 + struct vsc73xx *vsc = ds->priv; 1261 + u16 mask; 1262 + 1263 + if (state != BR_STATE_FORWARDING) { 1264 + /* Ports that aren't in the forwarding state must not 1265 + * forward packets anywhere. 1266 + */ 1267 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1268 + VSC73XX_SRCMASKS + port, 1269 + VSC73XX_SRCMASKS_PORTS_MASK, 0); 1270 + 1271 + dsa_switch_for_each_available_port(other_dp, ds) { 1272 + if (other_dp == dp) 1273 + continue; 1274 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1275 + VSC73XX_SRCMASKS + other_dp->index, 1276 + BIT(port), 0); 1277 + } 1278 + 1279 + return; 1280 + } 1281 + 1282 + /* Forwarding ports must forward to the CPU and to other ports 1283 + * in the same bridge 1284 + */ 1285 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1286 + VSC73XX_SRCMASKS + CPU_PORT, BIT(port), BIT(port)); 1287 + 1288 + mask = BIT(CPU_PORT); 1289 + 1290 + dsa_switch_for_each_user_port(other_dp, ds) { 1291 + int other_port = other_dp->index; 1292 + 1293 + if (port == other_port || !dsa_port_bridge_same(dp, other_dp) || 1294 + other_dp->stp_state != BR_STATE_FORWARDING) 1295 + continue; 1296 + 1297 + mask |= BIT(other_port); 1298 + 1299 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1300 + VSC73XX_SRCMASKS + other_port, 1301 + BIT(port), BIT(port)); 1302 + } 1303 + 1304 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1305 + VSC73XX_SRCMASKS + port, 1306 + VSC73XX_SRCMASKS_PORTS_MASK, mask); 1307 + } 1308 + 1309 + /* FIXME: STP frames aren't forwarded at this moment. BPDU frames are 1310 + * forwarded only from and to PI/SI interface. For more info see chapter 1311 + * 2.7.1 (CPU Forwarding) in datasheet. 1312 + * This function is required for tag_8021q operations. 1313 + */ 1314 + static void vsc73xx_port_stp_state_set(struct dsa_switch *ds, int port, 1315 + u8 state) 1316 + { 1317 + struct dsa_port *dp = dsa_to_port(ds, port); 1318 + struct vsc73xx *vsc = ds->priv; 1319 + u32 val = 0; 1320 + 1321 + if (state == BR_STATE_LEARNING || state == BR_STATE_FORWARDING) 1322 + val = dp->learning ? BIT(port) : 0; 1323 + 1324 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1325 + VSC73XX_LEARNMASK, BIT(port), val); 1326 + 1327 + val = (state == BR_STATE_BLOCKING || state == BR_STATE_DISABLED) ? 1328 + 0 : BIT(port); 1329 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1330 + VSC73XX_RECVMASK, BIT(port), val); 1331 + 1332 + /* CPU Port should always forward packets when user ports are forwarding 1333 + * so let's configure it from other ports only. 1334 + */ 1335 + if (port != CPU_PORT) 1336 + vsc73xx_refresh_fwd_map(ds, port, state); 1337 + } 1338 + 1435 1339 static const struct phylink_mac_ops vsc73xx_phylink_mac_ops = { 1436 1340 .mac_config = vsc73xx_mac_config, 1437 1341 .mac_link_down = vsc73xx_mac_link_down, ··· 1738 1048 static const struct dsa_switch_ops vsc73xx_ds_ops = { 1739 1049 .get_tag_protocol = vsc73xx_get_tag_protocol, 1740 1050 .setup = vsc73xx_setup, 1051 + .teardown = vsc73xx_teardown, 1741 1052 .phy_read = vsc73xx_phy_read, 1742 1053 .phy_write = vsc73xx_phy_write, 1743 1054 .get_strings = vsc73xx_get_strings, ··· 1746 1055 .get_sset_count = vsc73xx_get_sset_count, 1747 1056 .port_enable = vsc73xx_port_enable, 1748 1057 .port_disable = vsc73xx_port_disable, 1058 + .port_pre_bridge_flags = vsc73xx_port_pre_bridge_flags, 1059 + .port_bridge_flags = vsc73xx_port_bridge_flags, 1060 + .port_bridge_join = dsa_tag_8021q_bridge_join, 1061 + .port_bridge_leave = dsa_tag_8021q_bridge_leave, 1749 1062 .port_change_mtu = vsc73xx_change_mtu, 1750 1063 .port_max_mtu = vsc73xx_get_max_mtu, 1064 + .port_stp_state_set = vsc73xx_port_stp_state_set, 1065 + .port_vlan_filtering = vsc73xx_port_vlan_filtering, 1066 + .port_vlan_add = vsc73xx_port_vlan_add, 1067 + .port_vlan_del = vsc73xx_port_vlan_del, 1751 1068 .phylink_get_caps = vsc73xx_phylink_get_caps, 1069 + .tag_8021q_vlan_add = vsc73xx_tag_8021q_vlan_add, 1070 + .tag_8021q_vlan_del = vsc73xx_tag_8021q_vlan_del, 1752 1071 }; 1753 1072 1754 1073 static int vsc73xx_gpio_get(struct gpio_chip *chip, unsigned int offset)
+37
drivers/net/dsa/vitesse-vsc73xx.h
··· 15 15 #define VSC73XX_MAX_NUM_PORTS 8 16 16 17 17 /** 18 + * struct vsc73xx_portinfo - port data structure: contains storage data 19 + * @pvid_vlan_filtering: pvid vlan number used in vlan filtering mode 20 + * @pvid_tag_8021q: pvid vlan number used in tag_8021q mode 21 + * @pvid_vlan_filtering_configured: informs if port has configured pvid in vlan 22 + * filtering mode 23 + * @pvid_tag_8021q_configured: imforms if port have configured pvid in tag_8021q 24 + * mode 25 + */ 26 + struct vsc73xx_portinfo { 27 + u16 pvid_vlan_filtering; 28 + u16 pvid_tag_8021q; 29 + bool pvid_vlan_filtering_configured; 30 + bool pvid_tag_8021q_configured; 31 + }; 32 + 33 + /** 18 34 * struct vsc73xx - VSC73xx state container: main data structure 19 35 * @dev: The device pointer 20 36 * @reset: The descriptor for the GPIO line tied to the reset pin ··· 41 25 * @addr: MAC address used in flow control frames 42 26 * @ops: Structure with hardware-dependent operations 43 27 * @priv: Pointer to the configuration interface structure 28 + * @portinfo: Storage table portinfo structructures 29 + * @vlans: List of configured vlans. Contains port mask and untagged status of 30 + * every vlan configured in port vlan operation. It doesn't cover tag_8021q 31 + * vlans. 44 32 */ 45 33 struct vsc73xx { 46 34 struct device *dev; ··· 55 35 u8 addr[ETH_ALEN]; 56 36 const struct vsc73xx_ops *ops; 57 37 void *priv; 38 + struct vsc73xx_portinfo portinfo[VSC73XX_MAX_NUM_PORTS]; 39 + struct list_head vlans; 58 40 }; 59 41 60 42 /** ··· 69 47 u32 *val); 70 48 int (*write)(struct vsc73xx *vsc, u8 block, u8 subblock, u8 reg, 71 49 u32 val); 50 + }; 51 + 52 + /** 53 + * struct vsc73xx_bridge_vlan - VSC73xx driver structure which keeps vlan 54 + * database copy 55 + * @vid: VLAN number 56 + * @portmask: each bit represents one port 57 + * @untagged: each bit represents one port configured with @vid untagged 58 + * @list: list structure 59 + */ 60 + struct vsc73xx_bridge_vlan { 61 + u16 vid; 62 + u8 portmask; 63 + u8 untagged; 64 + struct list_head list; 72 65 }; 73 66 74 67 int vsc73xx_is_addr_valid(u8 block, u8 subblock);
+7 -1
include/linux/dsa/8021q.h
··· 8 8 #include <net/dsa.h> 9 9 #include <linux/types.h> 10 10 11 + /* VBID is limited to three bits only and zero is reserved. 12 + * Only 7 bridges can be enumerated. 13 + */ 14 + #define DSA_TAG_8021Q_MAX_NUM_BRIDGES 7 15 + 11 16 int dsa_tag_8021q_register(struct dsa_switch *ds, __be16 proto); 12 17 13 18 void dsa_tag_8021q_unregister(struct dsa_switch *ds); 14 19 15 20 int dsa_tag_8021q_bridge_join(struct dsa_switch *ds, int port, 16 - struct dsa_bridge bridge); 21 + struct dsa_bridge bridge, bool *tx_fwd_offload, 22 + struct netlink_ext_ack *extack); 17 23 18 24 void dsa_tag_8021q_bridge_leave(struct dsa_switch *ds, int port, 19 25 struct dsa_bridge bridge);
+2
include/net/dsa.h
··· 53 53 #define DSA_TAG_PROTO_RTL8_4T_VALUE 25 54 54 #define DSA_TAG_PROTO_RZN1_A5PSW_VALUE 26 55 55 #define DSA_TAG_PROTO_LAN937X_VALUE 27 56 + #define DSA_TAG_PROTO_VSC73XX_8021Q_VALUE 28 56 57 57 58 enum dsa_tag_protocol { 58 59 DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, ··· 84 83 DSA_TAG_PROTO_RTL8_4T = DSA_TAG_PROTO_RTL8_4T_VALUE, 85 84 DSA_TAG_PROTO_RZN1_A5PSW = DSA_TAG_PROTO_RZN1_A5PSW_VALUE, 86 85 DSA_TAG_PROTO_LAN937X = DSA_TAG_PROTO_LAN937X_VALUE, 86 + DSA_TAG_PROTO_VSC73XX_8021Q = DSA_TAG_PROTO_VSC73XX_8021Q_VALUE, 87 87 }; 88 88 89 89 struct dsa_switch;
+6
net/dsa/Kconfig
··· 166 166 Say Y or M if you want to enable support for tagging frames at 167 167 with a trailed. e.g. Marvell 88E6060. 168 168 169 + config NET_DSA_TAG_VSC73XX_8021Q 170 + tristate "Tag driver for Microchip/Vitesse VSC73xx family of switches, using VLAN" 171 + help 172 + Say Y or M if you want to enable support for tagging frames with a 173 + custom VLAN-based header. 174 + 169 175 config NET_DSA_TAG_XRS700X 170 176 tristate "Tag driver for XRS700x switches" 171 177 help
+1
net/dsa/Makefile
··· 37 37 obj-$(CONFIG_NET_DSA_TAG_RZN1_A5PSW) += tag_rzn1_a5psw.o 38 38 obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o 39 39 obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o 40 + obj-$(CONFIG_NET_DSA_TAG_VSC73XX_8021Q) += tag_vsc73xx_8021q.o 40 41 obj-$(CONFIG_NET_DSA_TAG_XRS700X) += tag_xrs700x.o 41 42 42 43 # for tracing framework to find trace.h
+75 -11
net/dsa/tag_8021q.c
··· 286 286 * be used for VLAN-unaware bridging. 287 287 */ 288 288 int dsa_tag_8021q_bridge_join(struct dsa_switch *ds, int port, 289 - struct dsa_bridge bridge) 289 + struct dsa_bridge bridge, bool *tx_fwd_offload, 290 + struct netlink_ext_ack *extack) 290 291 { 291 292 struct dsa_port *dp = dsa_to_port(ds, port); 292 293 u16 standalone_vid, bridge_vid; ··· 304 303 return err; 305 304 306 305 dsa_port_tag_8021q_vlan_del(dp, standalone_vid, false); 306 + 307 + *tx_fwd_offload = true; 307 308 308 309 return 0; 309 310 } ··· 471 468 } 472 469 EXPORT_SYMBOL_GPL(dsa_8021q_xmit); 473 470 474 - struct net_device *dsa_tag_8021q_find_port_by_vbid(struct net_device *conduit, 475 - int vbid) 471 + static struct net_device * 472 + dsa_tag_8021q_find_port_by_vbid(struct net_device *conduit, int vbid) 476 473 { 477 474 struct dsa_port *cpu_dp = conduit->dsa_ptr; 478 475 struct dsa_switch_tree *dst = cpu_dp->dst; ··· 498 495 499 496 return NULL; 500 497 } 501 - EXPORT_SYMBOL_GPL(dsa_tag_8021q_find_port_by_vbid); 502 498 503 - void dsa_8021q_rcv(struct sk_buff *skb, int *source_port, int *switch_id, 504 - int *vbid) 499 + struct net_device *dsa_tag_8021q_find_user(struct net_device *conduit, 500 + int source_port, int switch_id, 501 + int vid, int vbid) 505 502 { 506 - u16 vid, tci; 503 + /* Always prefer precise source port information, if available */ 504 + if (source_port != -1 && switch_id != -1) 505 + return dsa_conduit_find_user(conduit, switch_id, source_port); 506 + else if (vbid >= 1) 507 + return dsa_tag_8021q_find_port_by_vbid(conduit, vbid); 508 + 509 + return dsa_find_designated_bridge_port_by_vid(conduit, vid); 510 + } 511 + EXPORT_SYMBOL_GPL(dsa_tag_8021q_find_user); 512 + 513 + /** 514 + * dsa_8021q_rcv - Decode source information from tag_8021q header 515 + * @skb: RX socket buffer 516 + * @source_port: pointer to storage for precise source port information. 517 + * If this is known already from outside tag_8021q, the pre-initialized 518 + * value is preserved. If not known, pass -1. 519 + * @switch_id: similar to source_port. 520 + * @vbid: pointer to storage for imprecise bridge ID. Must be pre-initialized 521 + * with -1. If a positive value is returned, the source_port and switch_id 522 + * are invalid. 523 + * @vid: pointer to storage for original VID, in case tag_8021q decoding failed. 524 + * 525 + * If the packet has a tag_8021q header, decode it and set @source_port, 526 + * @switch_id and @vbid, and strip the header. Otherwise set @vid and keep the 527 + * header in the hwaccel area of the packet. 528 + */ 529 + void dsa_8021q_rcv(struct sk_buff *skb, int *source_port, int *switch_id, 530 + int *vbid, int *vid) 531 + { 532 + int tmp_source_port, tmp_switch_id, tmp_vbid; 533 + __be16 vlan_proto; 534 + u16 tmp_vid, tci; 507 535 508 536 if (skb_vlan_tag_present(skb)) { 537 + vlan_proto = skb->vlan_proto; 509 538 tci = skb_vlan_tag_get(skb); 510 539 __vlan_hwaccel_clear_tag(skb); 511 540 } else { 541 + struct vlan_ethhdr *hdr = vlan_eth_hdr(skb); 542 + 543 + vlan_proto = hdr->h_vlan_proto; 512 544 skb_push_rcsum(skb, ETH_HLEN); 513 545 __skb_vlan_pop(skb, &tci); 514 546 skb_pull_rcsum(skb, ETH_HLEN); 515 547 } 516 548 517 - vid = tci & VLAN_VID_MASK; 549 + tmp_vid = tci & VLAN_VID_MASK; 550 + if (!vid_is_dsa_8021q(tmp_vid)) { 551 + /* Not a tag_8021q frame, so return the VID to the 552 + * caller for further processing, and put the tag back 553 + */ 554 + if (vid) 555 + *vid = tmp_vid; 518 556 519 - *source_port = dsa_8021q_rx_source_port(vid); 520 - *switch_id = dsa_8021q_rx_switch_id(vid); 557 + __vlan_hwaccel_put_tag(skb, vlan_proto, tci); 558 + 559 + return; 560 + } 561 + 562 + tmp_source_port = dsa_8021q_rx_source_port(tmp_vid); 563 + tmp_switch_id = dsa_8021q_rx_switch_id(tmp_vid); 564 + tmp_vbid = dsa_tag_8021q_rx_vbid(tmp_vid); 565 + 566 + /* Precise source port information is unknown when receiving from a 567 + * VLAN-unaware bridging domain, and tmp_source_port and tmp_switch_id 568 + * are zeroes in this case. 569 + * 570 + * Preserve the source information from hardware-specific mechanisms, 571 + * if available. This allows us to not overwrite a valid source port 572 + * and switch ID with less precise values. 573 + */ 574 + if (tmp_vbid == 0 && *source_port == -1) 575 + *source_port = tmp_source_port; 576 + if (tmp_vbid == 0 && *switch_id == -1) 577 + *switch_id = tmp_switch_id; 521 578 522 579 if (vbid) 523 - *vbid = dsa_tag_8021q_rx_vbid(vid); 580 + *vbid = tmp_vbid; 524 581 525 582 skb->priority = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; 583 + return; 526 584 } 527 585 EXPORT_SYMBOL_GPL(dsa_8021q_rcv);
+4 -3
net/dsa/tag_8021q.h
··· 14 14 u16 tpid, u16 tci); 15 15 16 16 void dsa_8021q_rcv(struct sk_buff *skb, int *source_port, int *switch_id, 17 - int *vbid); 17 + int *vbid, int *vid); 18 18 19 - struct net_device *dsa_tag_8021q_find_port_by_vbid(struct net_device *conduit, 20 - int vbid); 19 + struct net_device *dsa_tag_8021q_find_user(struct net_device *conduit, 20 + int source_port, int switch_id, 21 + int vid, int vbid); 21 22 22 23 int dsa_switch_tag_8021q_vlan_add(struct dsa_switch *ds, 23 24 struct dsa_notifier_tag_8021q_vlan_info *info);
+1 -1
net/dsa/tag_ocelot_8021q.c
··· 81 81 { 82 82 int src_port, switch_id; 83 83 84 - dsa_8021q_rcv(skb, &src_port, &switch_id, NULL); 84 + dsa_8021q_rcv(skb, &src_port, &switch_id, NULL, NULL); 85 85 86 86 skb->dev = dsa_conduit_find_user(netdev, switch_id, src_port); 87 87 if (!skb->dev)
+11 -59
net/dsa/tag_sja1105.c
··· 472 472 return ntohs(eth_hdr(skb)->h_proto) == ETH_P_SJA1110; 473 473 } 474 474 475 - /* If the VLAN in the packet is a tag_8021q one, set @source_port and 476 - * @switch_id and strip the header. Otherwise set @vid and keep it in the 477 - * packet. 478 - */ 479 - static void sja1105_vlan_rcv(struct sk_buff *skb, int *source_port, 480 - int *switch_id, int *vbid, u16 *vid) 481 - { 482 - struct vlan_ethhdr *hdr = vlan_eth_hdr(skb); 483 - u16 vlan_tci; 484 - 485 - if (skb_vlan_tag_present(skb)) 486 - vlan_tci = skb_vlan_tag_get(skb); 487 - else 488 - vlan_tci = ntohs(hdr->h_vlan_TCI); 489 - 490 - if (vid_is_dsa_8021q(vlan_tci & VLAN_VID_MASK)) 491 - return dsa_8021q_rcv(skb, source_port, switch_id, vbid); 492 - 493 - /* Try our best with imprecise RX */ 494 - *vid = vlan_tci & VLAN_VID_MASK; 495 - } 496 - 497 475 static struct sk_buff *sja1105_rcv(struct sk_buff *skb, 498 476 struct net_device *netdev) 499 477 { 500 - int source_port = -1, switch_id = -1, vbid = -1; 478 + int source_port = -1, switch_id = -1, vbid = -1, vid = -1; 501 479 struct sja1105_meta meta = {0}; 502 480 struct ethhdr *hdr; 503 481 bool is_link_local; 504 482 bool is_meta; 505 - u16 vid; 506 483 507 484 hdr = eth_hdr(skb); 508 485 is_link_local = sja1105_is_link_local(skb); ··· 501 524 /* Normal data plane traffic and link-local frames are tagged with 502 525 * a tag_8021q VLAN which we have to strip 503 526 */ 504 - if (sja1105_skb_has_tag_8021q(skb)) { 505 - int tmp_source_port = -1, tmp_switch_id = -1; 506 - 507 - sja1105_vlan_rcv(skb, &tmp_source_port, &tmp_switch_id, &vbid, 508 - &vid); 509 - /* Preserve the source information from the INCL_SRCPT option, 510 - * if available. This allows us to not overwrite a valid source 511 - * port and switch ID with zeroes when receiving link-local 512 - * frames from a VLAN-unaware bridged port (non-zero vbid) or a 513 - * VLAN-aware bridged port (non-zero vid). Furthermore, the 514 - * tag_8021q source port information is only of trust when the 515 - * vbid is 0 (precise port). Otherwise, tmp_source_port and 516 - * tmp_switch_id will be zeroes. 517 - */ 518 - if (vbid == 0 && source_port == -1) 519 - source_port = tmp_source_port; 520 - if (vbid == 0 && switch_id == -1) 521 - switch_id = tmp_switch_id; 522 - } else if (source_port == -1 && switch_id == -1) { 527 + if (sja1105_skb_has_tag_8021q(skb)) 528 + dsa_8021q_rcv(skb, &source_port, &switch_id, &vbid, &vid); 529 + else if (source_port == -1 && switch_id == -1) 523 530 /* Packets with no source information have no chance of 524 531 * getting accepted, drop them straight away. 525 532 */ 526 533 return NULL; 527 - } 528 534 529 - if (source_port != -1 && switch_id != -1) 530 - skb->dev = dsa_conduit_find_user(netdev, switch_id, source_port); 531 - else if (vbid >= 1) 532 - skb->dev = dsa_tag_8021q_find_port_by_vbid(netdev, vbid); 533 - else 534 - skb->dev = dsa_find_designated_bridge_port_by_vid(netdev, vid); 535 + skb->dev = dsa_tag_8021q_find_user(netdev, source_port, switch_id, 536 + vid, vbid); 535 537 if (!skb->dev) { 536 538 netdev_warn(netdev, "Couldn't decode source port\n"); 537 539 return NULL; ··· 633 677 static struct sk_buff *sja1110_rcv(struct sk_buff *skb, 634 678 struct net_device *netdev) 635 679 { 636 - int source_port = -1, switch_id = -1, vbid = -1; 680 + int source_port = -1, switch_id = -1, vbid = -1, vid = -1; 637 681 bool host_only = false; 638 - u16 vid = 0; 639 682 640 683 if (sja1110_skb_has_inband_control_extension(skb)) { 641 684 skb = sja1110_rcv_inband_control_extension(skb, &source_port, ··· 646 691 647 692 /* Packets with in-band control extensions might still have RX VLANs */ 648 693 if (likely(sja1105_skb_has_tag_8021q(skb))) 649 - sja1105_vlan_rcv(skb, &source_port, &switch_id, &vbid, &vid); 694 + dsa_8021q_rcv(skb, &source_port, &switch_id, &vbid, &vid); 650 695 651 - if (vbid >= 1) 652 - skb->dev = dsa_tag_8021q_find_port_by_vbid(netdev, vbid); 653 - else if (source_port == -1 || switch_id == -1) 654 - skb->dev = dsa_find_designated_bridge_port_by_vid(netdev, vid); 655 - else 656 - skb->dev = dsa_conduit_find_user(netdev, switch_id, source_port); 696 + skb->dev = dsa_tag_8021q_find_user(netdev, source_port, switch_id, 697 + vid, vbid); 698 + 657 699 if (!skb->dev) { 658 700 netdev_warn(netdev, "Couldn't decode source port\n"); 659 701 return NULL;
+68
net/dsa/tag_vsc73xx_8021q.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR MIT 2 + /* Copyright (C) 2024 Pawel Dembicki <paweldembicki@gmail.com> 3 + */ 4 + #include <linux/dsa/8021q.h> 5 + 6 + #include "tag.h" 7 + #include "tag_8021q.h" 8 + 9 + #define VSC73XX_8021Q_NAME "vsc73xx-8021q" 10 + 11 + static struct sk_buff * 12 + vsc73xx_xmit(struct sk_buff *skb, struct net_device *netdev) 13 + { 14 + struct dsa_port *dp = dsa_user_to_port(netdev); 15 + u16 queue_mapping = skb_get_queue_mapping(skb); 16 + u16 tx_vid = dsa_tag_8021q_standalone_vid(dp); 17 + u8 pcp; 18 + 19 + if (skb->offload_fwd_mark) { 20 + unsigned int bridge_num = dsa_port_bridge_num_get(dp); 21 + struct net_device *br = dsa_port_bridge_dev_get(dp); 22 + 23 + if (br_vlan_enabled(br)) 24 + return skb; 25 + 26 + tx_vid = dsa_tag_8021q_bridge_vid(bridge_num); 27 + } 28 + 29 + pcp = netdev_txq_to_tc(netdev, queue_mapping); 30 + 31 + return dsa_8021q_xmit(skb, netdev, ETH_P_8021Q, 32 + ((pcp << VLAN_PRIO_SHIFT) | tx_vid)); 33 + } 34 + 35 + static struct sk_buff * 36 + vsc73xx_rcv(struct sk_buff *skb, struct net_device *netdev) 37 + { 38 + int src_port = -1, switch_id = -1, vbid = -1, vid = -1; 39 + 40 + dsa_8021q_rcv(skb, &src_port, &switch_id, &vbid, &vid); 41 + 42 + skb->dev = dsa_tag_8021q_find_user(netdev, src_port, switch_id, 43 + vid, vbid); 44 + if (!skb->dev) { 45 + dev_warn_ratelimited(&netdev->dev, 46 + "Couldn't decode source port\n"); 47 + return NULL; 48 + } 49 + 50 + dsa_default_offload_fwd_mark(skb); 51 + 52 + return skb; 53 + } 54 + 55 + static const struct dsa_device_ops vsc73xx_8021q_netdev_ops = { 56 + .name = VSC73XX_8021Q_NAME, 57 + .proto = DSA_TAG_PROTO_VSC73XX_8021Q, 58 + .xmit = vsc73xx_xmit, 59 + .rcv = vsc73xx_rcv, 60 + .needed_headroom = VLAN_HLEN, 61 + .promisc_on_conduit = true, 62 + }; 63 + 64 + MODULE_LICENSE("GPL"); 65 + MODULE_DESCRIPTION("DSA tag driver for VSC73XX family of switches, using VLAN"); 66 + MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_VSC73XX_8021Q, VSC73XX_8021Q_NAME); 67 + 68 + module_dsa_tag_driver(vsc73xx_8021q_netdev_ops);