0001
0002
0003 #include "lan966x_main.h"
0004
0005 #define VLANACCESS_CMD_IDLE 0
0006 #define VLANACCESS_CMD_READ 1
0007 #define VLANACCESS_CMD_WRITE 2
0008 #define VLANACCESS_CMD_INIT 3
0009
0010 static int lan966x_vlan_get_status(struct lan966x *lan966x)
0011 {
0012 return lan_rd(lan966x, ANA_VLANACCESS);
0013 }
0014
0015 static int lan966x_vlan_wait_for_completion(struct lan966x *lan966x)
0016 {
0017 u32 val;
0018
0019 return readx_poll_timeout(lan966x_vlan_get_status,
0020 lan966x, val,
0021 (val & ANA_VLANACCESS_VLAN_TBL_CMD) ==
0022 VLANACCESS_CMD_IDLE,
0023 TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US);
0024 }
0025
0026 static void lan966x_vlan_set_mask(struct lan966x *lan966x, u16 vid)
0027 {
0028 u16 mask = lan966x->vlan_mask[vid];
0029 bool cpu_dis;
0030
0031 cpu_dis = !(mask & BIT(CPU_PORT));
0032
0033
0034 lan_rmw(ANA_VLANTIDX_VLAN_PGID_CPU_DIS_SET(cpu_dis) |
0035 ANA_VLANTIDX_V_INDEX_SET(vid),
0036 ANA_VLANTIDX_VLAN_PGID_CPU_DIS |
0037 ANA_VLANTIDX_V_INDEX,
0038 lan966x, ANA_VLANTIDX);
0039
0040
0041 lan_rmw(ANA_VLAN_PORT_MASK_VLAN_PORT_MASK_SET(mask),
0042 ANA_VLAN_PORT_MASK_VLAN_PORT_MASK,
0043 lan966x, ANA_VLAN_PORT_MASK);
0044
0045
0046 lan_rmw(ANA_VLANACCESS_VLAN_TBL_CMD_SET(VLANACCESS_CMD_WRITE),
0047 ANA_VLANACCESS_VLAN_TBL_CMD,
0048 lan966x, ANA_VLANACCESS);
0049
0050 if (lan966x_vlan_wait_for_completion(lan966x))
0051 dev_err(lan966x->dev, "Vlan set mask failed\n");
0052 }
0053
0054 static void lan966x_vlan_port_add_vlan_mask(struct lan966x_port *port, u16 vid)
0055 {
0056 struct lan966x *lan966x = port->lan966x;
0057 u8 p = port->chip_port;
0058
0059 lan966x->vlan_mask[vid] |= BIT(p);
0060 lan966x_vlan_set_mask(lan966x, vid);
0061 }
0062
0063 static void lan966x_vlan_port_del_vlan_mask(struct lan966x_port *port, u16 vid)
0064 {
0065 struct lan966x *lan966x = port->lan966x;
0066 u8 p = port->chip_port;
0067
0068 lan966x->vlan_mask[vid] &= ~BIT(p);
0069 lan966x_vlan_set_mask(lan966x, vid);
0070 }
0071
0072 static bool lan966x_vlan_port_any_vlan_mask(struct lan966x *lan966x, u16 vid)
0073 {
0074 return !!(lan966x->vlan_mask[vid] & ~BIT(CPU_PORT));
0075 }
0076
0077 static void lan966x_vlan_cpu_add_vlan_mask(struct lan966x *lan966x, u16 vid)
0078 {
0079 lan966x->vlan_mask[vid] |= BIT(CPU_PORT);
0080 lan966x_vlan_set_mask(lan966x, vid);
0081 }
0082
0083 static void lan966x_vlan_cpu_del_vlan_mask(struct lan966x *lan966x, u16 vid)
0084 {
0085 lan966x->vlan_mask[vid] &= ~BIT(CPU_PORT);
0086 lan966x_vlan_set_mask(lan966x, vid);
0087 }
0088
0089 static void lan966x_vlan_cpu_add_cpu_vlan_mask(struct lan966x *lan966x, u16 vid)
0090 {
0091 __set_bit(vid, lan966x->cpu_vlan_mask);
0092 }
0093
0094 static void lan966x_vlan_cpu_del_cpu_vlan_mask(struct lan966x *lan966x, u16 vid)
0095 {
0096 __clear_bit(vid, lan966x->cpu_vlan_mask);
0097 }
0098
0099 bool lan966x_vlan_cpu_member_cpu_vlan_mask(struct lan966x *lan966x, u16 vid)
0100 {
0101 return test_bit(vid, lan966x->cpu_vlan_mask);
0102 }
0103
0104 static u16 lan966x_vlan_port_get_pvid(struct lan966x_port *port)
0105 {
0106 struct lan966x *lan966x = port->lan966x;
0107
0108 if (!(lan966x->bridge_mask & BIT(port->chip_port)))
0109 return HOST_PVID;
0110
0111 return port->vlan_aware ? port->pvid : UNAWARE_PVID;
0112 }
0113
0114 int lan966x_vlan_port_set_vid(struct lan966x_port *port, u16 vid,
0115 bool pvid, bool untagged)
0116 {
0117 struct lan966x *lan966x = port->lan966x;
0118
0119
0120 if (untagged && port->vid != vid) {
0121 if (port->vid) {
0122 dev_err(lan966x->dev,
0123 "Port already has a native VLAN: %d\n",
0124 port->vid);
0125 return -EBUSY;
0126 }
0127 port->vid = vid;
0128 }
0129
0130
0131 if (pvid)
0132 port->pvid = vid;
0133
0134 return 0;
0135 }
0136
0137 static void lan966x_vlan_port_remove_vid(struct lan966x_port *port, u16 vid)
0138 {
0139 if (port->pvid == vid)
0140 port->pvid = 0;
0141
0142 if (port->vid == vid)
0143 port->vid = 0;
0144 }
0145
0146 void lan966x_vlan_port_set_vlan_aware(struct lan966x_port *port,
0147 bool vlan_aware)
0148 {
0149 port->vlan_aware = vlan_aware;
0150 }
0151
0152 void lan966x_vlan_port_apply(struct lan966x_port *port)
0153 {
0154 struct lan966x *lan966x = port->lan966x;
0155 u16 pvid;
0156 u32 val;
0157
0158 pvid = lan966x_vlan_port_get_pvid(port);
0159
0160
0161
0162 val = ANA_VLAN_CFG_VLAN_VID_SET(pvid);
0163 if (port->vlan_aware)
0164 val |= ANA_VLAN_CFG_VLAN_AWARE_ENA_SET(1) |
0165 ANA_VLAN_CFG_VLAN_POP_CNT_SET(1);
0166
0167 lan_rmw(val,
0168 ANA_VLAN_CFG_VLAN_VID | ANA_VLAN_CFG_VLAN_AWARE_ENA |
0169 ANA_VLAN_CFG_VLAN_POP_CNT,
0170 lan966x, ANA_VLAN_CFG(port->chip_port));
0171
0172
0173 val = ANA_DROP_CFG_DROP_MC_SMAC_ENA_SET(1);
0174 if (port->vlan_aware && !pvid)
0175
0176
0177
0178 val |= ANA_DROP_CFG_DROP_UNTAGGED_ENA_SET(1) |
0179 ANA_DROP_CFG_DROP_PRIO_S_TAGGED_ENA_SET(1) |
0180 ANA_DROP_CFG_DROP_PRIO_C_TAGGED_ENA_SET(1);
0181
0182 lan_wr(val, lan966x, ANA_DROP_CFG(port->chip_port));
0183
0184
0185 val = REW_TAG_CFG_TAG_TPID_CFG_SET(0);
0186 if (port->vlan_aware) {
0187 if (port->vid)
0188
0189 val |= REW_TAG_CFG_TAG_CFG_SET(1);
0190 else
0191 val |= REW_TAG_CFG_TAG_CFG_SET(3);
0192 }
0193
0194
0195 lan_rmw(val,
0196 REW_TAG_CFG_TAG_TPID_CFG | REW_TAG_CFG_TAG_CFG,
0197 lan966x, REW_TAG_CFG(port->chip_port));
0198
0199
0200 lan_rmw(REW_PORT_VLAN_CFG_PORT_TPID_SET(ETH_P_8021Q) |
0201 REW_PORT_VLAN_CFG_PORT_VID_SET(port->vid),
0202 REW_PORT_VLAN_CFG_PORT_TPID |
0203 REW_PORT_VLAN_CFG_PORT_VID,
0204 lan966x, REW_PORT_VLAN_CFG(port->chip_port));
0205 }
0206
0207 void lan966x_vlan_port_add_vlan(struct lan966x_port *port,
0208 u16 vid,
0209 bool pvid,
0210 bool untagged)
0211 {
0212 struct lan966x *lan966x = port->lan966x;
0213
0214
0215
0216
0217
0218
0219 if (lan966x_vlan_cpu_member_cpu_vlan_mask(lan966x, vid)) {
0220 lan966x_vlan_cpu_add_vlan_mask(lan966x, vid);
0221 lan966x_fdb_write_entries(lan966x, vid);
0222 lan966x_mdb_write_entries(lan966x, vid);
0223 }
0224
0225 lan966x_vlan_port_set_vid(port, vid, pvid, untagged);
0226 lan966x_vlan_port_add_vlan_mask(port, vid);
0227 lan966x_vlan_port_apply(port);
0228 }
0229
0230 void lan966x_vlan_port_del_vlan(struct lan966x_port *port, u16 vid)
0231 {
0232 struct lan966x *lan966x = port->lan966x;
0233
0234 lan966x_vlan_port_remove_vid(port, vid);
0235 lan966x_vlan_port_del_vlan_mask(port, vid);
0236 lan966x_vlan_port_apply(port);
0237
0238
0239
0240
0241
0242 if (!lan966x_vlan_port_any_vlan_mask(lan966x, vid)) {
0243 lan966x_vlan_cpu_del_vlan_mask(lan966x, vid);
0244 lan966x_fdb_erase_entries(lan966x, vid);
0245 lan966x_mdb_erase_entries(lan966x, vid);
0246 }
0247 }
0248
0249 void lan966x_vlan_cpu_add_vlan(struct lan966x *lan966x, u16 vid)
0250 {
0251
0252
0253
0254
0255
0256
0257
0258
0259 if (lan966x_vlan_port_any_vlan_mask(lan966x, vid)) {
0260 lan966x_vlan_cpu_add_vlan_mask(lan966x, vid);
0261 lan966x_mdb_write_entries(lan966x, vid);
0262 }
0263
0264 lan966x_vlan_cpu_add_cpu_vlan_mask(lan966x, vid);
0265 lan966x_fdb_write_entries(lan966x, vid);
0266 }
0267
0268 void lan966x_vlan_cpu_del_vlan(struct lan966x *lan966x, u16 vid)
0269 {
0270
0271 lan966x_vlan_cpu_del_cpu_vlan_mask(lan966x, vid);
0272 lan966x_vlan_cpu_del_vlan_mask(lan966x, vid);
0273 lan966x_fdb_erase_entries(lan966x, vid);
0274 lan966x_mdb_erase_entries(lan966x, vid);
0275 }
0276
0277 void lan966x_vlan_init(struct lan966x *lan966x)
0278 {
0279 u16 port, vid;
0280
0281
0282 lan_rmw(ANA_VLANACCESS_VLAN_TBL_CMD_SET(VLANACCESS_CMD_INIT),
0283 ANA_VLANACCESS_VLAN_TBL_CMD,
0284 lan966x, ANA_VLANACCESS);
0285 lan966x_vlan_wait_for_completion(lan966x);
0286
0287 for (vid = 1; vid < VLAN_N_VID; vid++) {
0288 lan966x->vlan_mask[vid] = 0;
0289 lan966x_vlan_set_mask(lan966x, vid);
0290 }
0291
0292
0293 lan966x->vlan_mask[HOST_PVID] =
0294 GENMASK(lan966x->num_phys_ports - 1, 0) | BIT(CPU_PORT);
0295 lan966x_vlan_set_mask(lan966x, HOST_PVID);
0296
0297 lan966x->vlan_mask[UNAWARE_PVID] =
0298 GENMASK(lan966x->num_phys_ports - 1, 0) | BIT(CPU_PORT);
0299 lan966x_vlan_set_mask(lan966x, UNAWARE_PVID);
0300
0301 lan966x_vlan_cpu_add_cpu_vlan_mask(lan966x, UNAWARE_PVID);
0302
0303
0304 lan_wr(ANA_VLAN_CFG_VLAN_VID_SET(0) |
0305 ANA_VLAN_CFG_VLAN_AWARE_ENA_SET(1) |
0306 ANA_VLAN_CFG_VLAN_POP_CNT_SET(1),
0307 lan966x, ANA_VLAN_CFG(CPU_PORT));
0308
0309
0310 lan_wr(GENMASK(lan966x->num_phys_ports, 0),
0311 lan966x, ANA_VLANMASK);
0312
0313 for (port = 0; port < lan966x->num_phys_ports; port++) {
0314 lan_wr(0, lan966x, REW_PORT_VLAN_CFG(port));
0315 lan_wr(0, lan966x, REW_TAG_CFG(port));
0316 }
0317 }