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

Merge branch 'dsa-MT7530-vlan'

Sean Wang says:

====================
add VLAN support to DSA MT7530

Changes sicne v2:
update to the latest code base from net-next and fix up all building
errors with -Werror.

Changes since v1:
- fix up the typo
- prefer ordering declarations longest to shortest
- update that vlan_prepare callback should not change any state
- use lower case letter for function naming

The patchset extends DSA MT7530 to VLAN support through filling required
callbacks in patch 1 and merging the special tag with VLAN tag in patch 2
for allowing that the hardware can handle these packets with VID from the
CPU port.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+400 -16
+7
MAINTAINERS
··· 8728 8728 S: Maintained 8729 8729 F: drivers/net/ethernet/mediatek/ 8730 8730 8731 + MEDIATEK SWITCH DRIVER 8732 + M: Sean Wang <sean.wang@mediatek.com> 8733 + L: netdev@vger.kernel.org 8734 + S: Maintained 8735 + F: drivers/net/dsa/mt7530.* 8736 + F: net/dsa/tag_mtk.c 8737 + 8731 8738 MEDIATEK JPEG DRIVER 8732 8739 M: Rick Chang <rick.chang@mediatek.com> 8733 8740 M: Bin Liu <bin.liu@mediatek.com>
+287 -1
drivers/net/dsa/mt7530.c
··· 805 805 } 806 806 807 807 static void 808 + mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port) 809 + { 810 + struct mt7530_priv *priv = ds->priv; 811 + bool all_user_ports_removed = true; 812 + int i; 813 + 814 + /* When a port is removed from the bridge, the port would be set up 815 + * back to the default as is at initial boot which is a VLAN-unaware 816 + * port. 817 + */ 818 + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, 819 + MT7530_PORT_MATRIX_MODE); 820 + mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK, 821 + VLAN_ATTR(MT7530_VLAN_TRANSPARENT)); 822 + 823 + priv->ports[port].vlan_filtering = false; 824 + 825 + for (i = 0; i < MT7530_NUM_PORTS; i++) { 826 + if (dsa_is_user_port(ds, i) && 827 + priv->ports[i].vlan_filtering) { 828 + all_user_ports_removed = false; 829 + break; 830 + } 831 + } 832 + 833 + /* CPU port also does the same thing until all user ports belonging to 834 + * the CPU port get out of VLAN filtering mode. 835 + */ 836 + if (all_user_ports_removed) { 837 + mt7530_write(priv, MT7530_PCR_P(MT7530_CPU_PORT), 838 + PCR_MATRIX(dsa_user_ports(priv->ds))); 839 + mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), 840 + PORT_SPEC_TAG); 841 + } 842 + } 843 + 844 + static void 845 + mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port) 846 + { 847 + struct mt7530_priv *priv = ds->priv; 848 + 849 + /* The real fabric path would be decided on the membership in the 850 + * entry of VLAN table. PCR_MATRIX set up here with ALL_MEMBERS 851 + * means potential VLAN can be consisting of certain subset of all 852 + * ports. 853 + */ 854 + mt7530_rmw(priv, MT7530_PCR_P(port), 855 + PCR_MATRIX_MASK, PCR_MATRIX(MT7530_ALL_MEMBERS)); 856 + 857 + /* Trapped into security mode allows packet forwarding through VLAN 858 + * table lookup. 859 + */ 860 + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, 861 + MT7530_PORT_SECURITY_MODE); 862 + 863 + /* Set the port as a user port which is to be able to recognize VID 864 + * from incoming packets before fetching entry within the VLAN table. 865 + */ 866 + mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK, 867 + VLAN_ATTR(MT7530_VLAN_USER)); 868 + } 869 + 870 + static void 808 871 mt7530_port_bridge_leave(struct dsa_switch *ds, int port, 809 872 struct net_device *bridge) 810 873 { ··· 880 817 /* Remove this port from the port matrix of the other ports 881 818 * in the same bridge. If the port is disabled, port matrix 882 819 * is kept and not being setup until the port becomes enabled. 820 + * And the other port's port matrix cannot be broken when the 821 + * other port is still a VLAN-aware port. 883 822 */ 884 - if (dsa_is_user_port(ds, i) && i != port) { 823 + if (!priv->ports[i].vlan_filtering && 824 + dsa_is_user_port(ds, i) && i != port) { 885 825 if (dsa_to_port(ds, i)->bridge_dev != bridge) 886 826 continue; 887 827 if (priv->ports[i].enable) ··· 901 835 mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, 902 836 PCR_MATRIX(BIT(MT7530_CPU_PORT))); 903 837 priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT)); 838 + 839 + mt7530_port_set_vlan_unaware(ds, port); 904 840 905 841 mutex_unlock(&priv->reg_mutex); 906 842 } ··· 969 901 !(rsp & ATC_SRCH_END) && 970 902 !mt7530_fdb_cmd(priv, MT7530_FDB_NEXT, &rsp)); 971 903 err: 904 + mutex_unlock(&priv->reg_mutex); 905 + 906 + return 0; 907 + } 908 + 909 + static int 910 + mt7530_vlan_cmd(struct mt7530_priv *priv, enum mt7530_vlan_cmd cmd, u16 vid) 911 + { 912 + struct mt7530_dummy_poll p; 913 + u32 val; 914 + int ret; 915 + 916 + val = VTCR_BUSY | VTCR_FUNC(cmd) | vid; 917 + mt7530_write(priv, MT7530_VTCR, val); 918 + 919 + INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_VTCR); 920 + ret = readx_poll_timeout(_mt7530_read, &p, val, 921 + !(val & VTCR_BUSY), 20, 20000); 922 + if (ret < 0) { 923 + dev_err(priv->dev, "poll timeout\n"); 924 + return ret; 925 + } 926 + 927 + val = mt7530_read(priv, MT7530_VTCR); 928 + if (val & VTCR_INVALID) { 929 + dev_err(priv->dev, "read VTCR invalid\n"); 930 + return -EINVAL; 931 + } 932 + 933 + return 0; 934 + } 935 + 936 + static int 937 + mt7530_port_vlan_filtering(struct dsa_switch *ds, int port, 938 + bool vlan_filtering) 939 + { 940 + struct mt7530_priv *priv = ds->priv; 941 + 942 + priv->ports[port].vlan_filtering = vlan_filtering; 943 + 944 + if (vlan_filtering) { 945 + /* The port is being kept as VLAN-unaware port when bridge is 946 + * set up with vlan_filtering not being set, Otherwise, the 947 + * port and the corresponding CPU port is required the setup 948 + * for becoming a VLAN-aware port. 949 + */ 950 + mt7530_port_set_vlan_aware(ds, port); 951 + mt7530_port_set_vlan_aware(ds, MT7530_CPU_PORT); 952 + } 953 + 954 + return 0; 955 + } 956 + 957 + static int 958 + mt7530_port_vlan_prepare(struct dsa_switch *ds, int port, 959 + const struct switchdev_obj_port_vlan *vlan) 960 + { 961 + /* nothing needed */ 962 + 963 + return 0; 964 + } 965 + 966 + static void 967 + mt7530_hw_vlan_add(struct mt7530_priv *priv, 968 + struct mt7530_hw_vlan_entry *entry) 969 + { 970 + u8 new_members; 971 + u32 val; 972 + 973 + new_members = entry->old_members | BIT(entry->port) | 974 + BIT(MT7530_CPU_PORT); 975 + 976 + /* Validate the entry with independent learning, create egress tag per 977 + * VLAN and joining the port as one of the port members. 978 + */ 979 + val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | VLAN_VALID; 980 + mt7530_write(priv, MT7530_VAWD1, val); 981 + 982 + /* Decide whether adding tag or not for those outgoing packets from the 983 + * port inside the VLAN. 984 + */ 985 + val = entry->untagged ? MT7530_VLAN_EGRESS_UNTAG : 986 + MT7530_VLAN_EGRESS_TAG; 987 + mt7530_rmw(priv, MT7530_VAWD2, 988 + ETAG_CTRL_P_MASK(entry->port), 989 + ETAG_CTRL_P(entry->port, val)); 990 + 991 + /* CPU port is always taken as a tagged port for serving more than one 992 + * VLANs across and also being applied with egress type stack mode for 993 + * that VLAN tags would be appended after hardware special tag used as 994 + * DSA tag. 995 + */ 996 + mt7530_rmw(priv, MT7530_VAWD2, 997 + ETAG_CTRL_P_MASK(MT7530_CPU_PORT), 998 + ETAG_CTRL_P(MT7530_CPU_PORT, 999 + MT7530_VLAN_EGRESS_STACK)); 1000 + } 1001 + 1002 + static void 1003 + mt7530_hw_vlan_del(struct mt7530_priv *priv, 1004 + struct mt7530_hw_vlan_entry *entry) 1005 + { 1006 + u8 new_members; 1007 + u32 val; 1008 + 1009 + new_members = entry->old_members & ~BIT(entry->port); 1010 + 1011 + val = mt7530_read(priv, MT7530_VAWD1); 1012 + if (!(val & VLAN_VALID)) { 1013 + dev_err(priv->dev, 1014 + "Cannot be deleted due to invalid entry\n"); 1015 + return; 1016 + } 1017 + 1018 + /* If certain member apart from CPU port is still alive in the VLAN, 1019 + * the entry would be kept valid. Otherwise, the entry is got to be 1020 + * disabled. 1021 + */ 1022 + if (new_members && new_members != BIT(MT7530_CPU_PORT)) { 1023 + val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | 1024 + VLAN_VALID; 1025 + mt7530_write(priv, MT7530_VAWD1, val); 1026 + } else { 1027 + mt7530_write(priv, MT7530_VAWD1, 0); 1028 + mt7530_write(priv, MT7530_VAWD2, 0); 1029 + } 1030 + } 1031 + 1032 + static void 1033 + mt7530_hw_vlan_update(struct mt7530_priv *priv, u16 vid, 1034 + struct mt7530_hw_vlan_entry *entry, 1035 + mt7530_vlan_op vlan_op) 1036 + { 1037 + u32 val; 1038 + 1039 + /* Fetch entry */ 1040 + mt7530_vlan_cmd(priv, MT7530_VTCR_RD_VID, vid); 1041 + 1042 + val = mt7530_read(priv, MT7530_VAWD1); 1043 + 1044 + entry->old_members = (val >> PORT_MEM_SHFT) & PORT_MEM_MASK; 1045 + 1046 + /* Manipulate entry */ 1047 + vlan_op(priv, entry); 1048 + 1049 + /* Flush result to hardware */ 1050 + mt7530_vlan_cmd(priv, MT7530_VTCR_WR_VID, vid); 1051 + } 1052 + 1053 + static void 1054 + mt7530_port_vlan_add(struct dsa_switch *ds, int port, 1055 + const struct switchdev_obj_port_vlan *vlan) 1056 + { 1057 + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; 1058 + bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; 1059 + struct mt7530_hw_vlan_entry new_entry; 1060 + struct mt7530_priv *priv = ds->priv; 1061 + u16 vid; 1062 + 1063 + /* The port is kept as VLAN-unaware if bridge with vlan_filtering not 1064 + * being set. 1065 + */ 1066 + if (!priv->ports[port].vlan_filtering) 1067 + return; 1068 + 1069 + mutex_lock(&priv->reg_mutex); 1070 + 1071 + for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) { 1072 + mt7530_hw_vlan_entry_init(&new_entry, port, untagged); 1073 + mt7530_hw_vlan_update(priv, vid, &new_entry, 1074 + mt7530_hw_vlan_add); 1075 + } 1076 + 1077 + if (pvid) { 1078 + mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, 1079 + G0_PORT_VID(vlan->vid_end)); 1080 + priv->ports[port].pvid = vlan->vid_end; 1081 + } 1082 + 1083 + mutex_unlock(&priv->reg_mutex); 1084 + } 1085 + 1086 + static int 1087 + mt7530_port_vlan_del(struct dsa_switch *ds, int port, 1088 + const struct switchdev_obj_port_vlan *vlan) 1089 + { 1090 + struct mt7530_hw_vlan_entry target_entry; 1091 + struct mt7530_priv *priv = ds->priv; 1092 + u16 vid, pvid; 1093 + 1094 + /* The port is kept as VLAN-unaware if bridge with vlan_filtering not 1095 + * being set. 1096 + */ 1097 + if (!priv->ports[port].vlan_filtering) 1098 + return 0; 1099 + 1100 + mutex_lock(&priv->reg_mutex); 1101 + 1102 + pvid = priv->ports[port].pvid; 1103 + for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) { 1104 + mt7530_hw_vlan_entry_init(&target_entry, port, 0); 1105 + mt7530_hw_vlan_update(priv, vid, &target_entry, 1106 + mt7530_hw_vlan_del); 1107 + 1108 + /* PVID is being restored to the default whenever the PVID port 1109 + * is being removed from the VLAN. 1110 + */ 1111 + if (pvid == vid) 1112 + pvid = G0_PORT_VID_DEF; 1113 + } 1114 + 1115 + mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, pvid); 1116 + priv->ports[port].pvid = pvid; 1117 + 972 1118 mutex_unlock(&priv->reg_mutex); 973 1119 974 1120 return 0; ··· 1317 1035 .port_fdb_add = mt7530_port_fdb_add, 1318 1036 .port_fdb_del = mt7530_port_fdb_del, 1319 1037 .port_fdb_dump = mt7530_port_fdb_dump, 1038 + .port_vlan_filtering = mt7530_port_vlan_filtering, 1039 + .port_vlan_prepare = mt7530_port_vlan_prepare, 1040 + .port_vlan_add = mt7530_port_vlan_add, 1041 + .port_vlan_del = mt7530_port_vlan_del, 1320 1042 }; 1321 1043 1322 1044 static int
+77 -6
drivers/net/dsa/mt7530.h
··· 17 17 #define MT7530_NUM_PORTS 7 18 18 #define MT7530_CPU_PORT 6 19 19 #define MT7530_NUM_FDB_RECORDS 2048 20 + #define MT7530_ALL_MEMBERS 0xff 20 21 21 22 #define NUM_TRGMII_CTRL 5 22 23 ··· 89 88 /* Register for vlan table control */ 90 89 #define MT7530_VTCR 0x90 91 90 #define VTCR_BUSY BIT(31) 92 - #define VTCR_FUNC (((x) & 0xf) << 12) 93 - #define VTCR_FUNC_RD_VID 0x1 94 - #define VTCR_FUNC_WR_VID 0x2 95 - #define VTCR_FUNC_INV_VID 0x3 96 - #define VTCR_FUNC_VAL_VID 0x4 91 + #define VTCR_INVALID BIT(16) 92 + #define VTCR_FUNC(x) (((x) & 0xf) << 12) 97 93 #define VTCR_VID ((x) & 0xfff) 94 + 95 + enum mt7530_vlan_cmd { 96 + /* Read/Write the specified VID entry from VAWD register based 97 + * on VID. 98 + */ 99 + MT7530_VTCR_RD_VID = 0, 100 + MT7530_VTCR_WR_VID = 1, 101 + }; 98 102 99 103 /* Register for setup vlan and acl write data */ 100 104 #define MT7530_VAWD1 0x94 101 105 #define PORT_STAG BIT(31) 106 + /* Independent VLAN Learning */ 102 107 #define IVL_MAC BIT(30) 108 + /* Per VLAN Egress Tag Control */ 109 + #define VTAG_EN BIT(28) 110 + /* VLAN Member Control */ 103 111 #define PORT_MEM(x) (((x) & 0xff) << 16) 104 - #define VALID BIT(1) 112 + /* VLAN Entry Valid */ 113 + #define VLAN_VALID BIT(0) 114 + #define PORT_MEM_SHFT 16 115 + #define PORT_MEM_MASK 0xff 105 116 106 117 #define MT7530_VAWD2 0x98 118 + /* Egress Tag Control */ 119 + #define ETAG_CTRL_P(p, x) (((x) & 0x3) << ((p) << 1)) 120 + #define ETAG_CTRL_P_MASK(p) ETAG_CTRL_P(p, 3) 121 + 122 + enum mt7530_vlan_egress_attr { 123 + MT7530_VLAN_EGRESS_UNTAG = 0, 124 + MT7530_VLAN_EGRESS_TAG = 2, 125 + MT7530_VLAN_EGRESS_STACK = 3, 126 + }; 107 127 108 128 /* Register for port STP state control */ 109 129 #define MT7530_SSP_P(x) (0x2000 + ((x) * 0x100)) ··· 142 120 /* Register for port control */ 143 121 #define MT7530_PCR_P(x) (0x2004 + ((x) * 0x100)) 144 122 #define PORT_VLAN(x) ((x) & 0x3) 123 + 124 + enum mt7530_port_mode { 125 + /* Port Matrix Mode: Frames are forwarded by the PCR_MATRIX members. */ 126 + MT7530_PORT_MATRIX_MODE = PORT_VLAN(0), 127 + 128 + /* Security Mode: Discard any frame due to ingress membership 129 + * violation or VID missed on the VLAN table. 130 + */ 131 + MT7530_PORT_SECURITY_MODE = PORT_VLAN(3), 132 + }; 133 + 145 134 #define PCR_MATRIX(x) (((x) & 0xff) << 16) 146 135 #define PORT_PRI(x) (((x) & 0x7) << 24) 147 136 #define EG_TAG(x) (((x) & 0x3) << 28) 148 137 #define PCR_MATRIX_MASK PCR_MATRIX(0xff) 149 138 #define PCR_MATRIX_CLR PCR_MATRIX(0) 139 + #define PCR_PORT_VLAN_MASK PORT_VLAN(3) 150 140 151 141 /* Register for port security control */ 152 142 #define MT7530_PSC_P(x) (0x200c + ((x) * 0x100)) ··· 168 134 #define MT7530_PVC_P(x) (0x2010 + ((x) * 0x100)) 169 135 #define PORT_SPEC_TAG BIT(5) 170 136 #define VLAN_ATTR(x) (((x) & 0x3) << 6) 137 + #define VLAN_ATTR_MASK VLAN_ATTR(3) 138 + 139 + enum mt7530_vlan_port_attr { 140 + MT7530_VLAN_USER = 0, 141 + MT7530_VLAN_TRANSPARENT = 3, 142 + }; 143 + 171 144 #define STAG_VPID (((x) & 0xffff) << 16) 172 145 173 146 /* Register for port port-and-protocol based vlan 1 control */ 174 147 #define MT7530_PPBV1_P(x) (0x2014 + ((x) * 0x100)) 148 + #define G0_PORT_VID(x) (((x) & 0xfff) << 0) 149 + #define G0_PORT_VID_MASK G0_PORT_VID(0xfff) 150 + #define G0_PORT_VID_DEF G0_PORT_VID(1) 175 151 176 152 /* Register for port MAC control register */ 177 153 #define MT7530_PMCR_P(x) (0x3000 + ((x) * 0x100)) ··· 389 345 bool noarp; 390 346 }; 391 347 348 + /* struct mt7530_port - This is the main data structure for holding the state 349 + * of the port. 350 + * @enable: The status used for show port is enabled or not. 351 + * @pm: The matrix used to show all connections with the port. 352 + * @pvid: The VLAN specified is to be considered a PVID at ingress. Any 353 + * untagged frames will be assigned to the related VLAN. 354 + * @vlan_filtering: The flags indicating whether the port that can recognize 355 + * VLAN-tagged frames. 356 + */ 392 357 struct mt7530_port { 393 358 bool enable; 394 359 u32 pm; 360 + u16 pvid; 361 + bool vlan_filtering; 395 362 }; 396 363 397 364 /* struct mt7530_priv - This is the main data structure for holding the state ··· 436 381 /* protect among processes for registers access*/ 437 382 struct mutex reg_mutex; 438 383 }; 384 + 385 + struct mt7530_hw_vlan_entry { 386 + int port; 387 + u8 old_members; 388 + bool untagged; 389 + }; 390 + 391 + static inline void mt7530_hw_vlan_entry_init(struct mt7530_hw_vlan_entry *e, 392 + int port, bool untagged) 393 + { 394 + e->port = port; 395 + e->untagged = untagged; 396 + } 397 + 398 + typedef void (*mt7530_vlan_op)(struct mt7530_priv *, 399 + struct mt7530_hw_vlan_entry *); 439 400 440 401 struct mt7530_hw_stats { 441 402 const char *string;
+29 -9
net/dsa/tag_mtk.c
··· 13 13 */ 14 14 15 15 #include <linux/etherdevice.h> 16 + #include <linux/if_vlan.h> 16 17 17 18 #include "dsa_priv.h" 18 19 19 20 #define MTK_HDR_LEN 4 21 + #define MTK_HDR_XMIT_UNTAGGED 0 22 + #define MTK_HDR_XMIT_TAGGED_TPID_8100 1 20 23 #define MTK_HDR_RECV_SOURCE_PORT_MASK GENMASK(2, 0) 21 24 #define MTK_HDR_XMIT_DP_BIT_MASK GENMASK(5, 0) 22 25 ··· 28 25 { 29 26 struct dsa_port *dp = dsa_slave_to_port(dev); 30 27 u8 *mtk_tag; 28 + bool is_vlan_skb = true; 31 29 32 - if (skb_cow_head(skb, MTK_HDR_LEN) < 0) 33 - return NULL; 30 + /* Build the special tag after the MAC Source Address. If VLAN header 31 + * is present, it's required that VLAN header and special tag is 32 + * being combined. Only in this way we can allow the switch can parse 33 + * the both special and VLAN tag at the same time and then look up VLAN 34 + * table with VID. 35 + */ 36 + if (!skb_vlan_tagged(skb)) { 37 + if (skb_cow_head(skb, MTK_HDR_LEN) < 0) 38 + return NULL; 34 39 35 - skb_push(skb, MTK_HDR_LEN); 40 + skb_push(skb, MTK_HDR_LEN); 41 + memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); 42 + is_vlan_skb = false; 43 + } 36 44 37 - memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); 38 - 39 - /* Build the tag after the MAC Source Address */ 40 45 mtk_tag = skb->data + 2 * ETH_ALEN; 41 - mtk_tag[0] = 0; 46 + 47 + /* Mark tag attribute on special tag insertion to notify hardware 48 + * whether that's a combined special tag with 802.1Q header. 49 + */ 50 + mtk_tag[0] = is_vlan_skb ? MTK_HDR_XMIT_TAGGED_TPID_8100 : 51 + MTK_HDR_XMIT_UNTAGGED; 42 52 mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; 43 - mtk_tag[2] = 0; 44 - mtk_tag[3] = 0; 53 + 54 + /* Tag control information is kept for 802.1Q */ 55 + if (!is_vlan_skb) { 56 + mtk_tag[2] = 0; 57 + mtk_tag[3] = 0; 58 + } 45 59 46 60 return skb; 47 61 }