1 // SPDX-License-Identifier: GPL-2.0+ 2 3 #include "lan966x_main.h" 4 5 #define VLANACCESS_CMD_IDLE 0 6 #define VLANACCESS_CMD_READ 1 7 #define VLANACCESS_CMD_WRITE 2 8 #define VLANACCESS_CMD_INIT 3 9 10 static int lan966x_vlan_get_status(struct lan966x *lan966x) 11 { 12 return lan_rd(lan966x, ANA_VLANACCESS); 13 } 14 15 static int lan966x_vlan_wait_for_completion(struct lan966x *lan966x) 16 { 17 u32 val; 18 19 return readx_poll_timeout(lan966x_vlan_get_status, 20 lan966x, val, 21 (val & ANA_VLANACCESS_VLAN_TBL_CMD) == 22 VLANACCESS_CMD_IDLE, 23 TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US); 24 } 25 26 static void lan966x_vlan_set_mask(struct lan966x *lan966x, u16 vid) 27 { 28 u16 mask = lan966x->vlan_mask[vid]; 29 bool cpu_dis; 30 31 cpu_dis = !(mask & BIT(CPU_PORT)); 32 33 /* Set flags and the VID to configure */ 34 lan_rmw(ANA_VLANTIDX_VLAN_PGID_CPU_DIS_SET(cpu_dis) | 35 ANA_VLANTIDX_V_INDEX_SET(vid), 36 ANA_VLANTIDX_VLAN_PGID_CPU_DIS | 37 ANA_VLANTIDX_V_INDEX, 38 lan966x, ANA_VLANTIDX); 39 40 /* Set the vlan port members mask */ 41 lan_rmw(ANA_VLAN_PORT_MASK_VLAN_PORT_MASK_SET(mask), 42 ANA_VLAN_PORT_MASK_VLAN_PORT_MASK, 43 lan966x, ANA_VLAN_PORT_MASK); 44 45 /* Issue a write command */ 46 lan_rmw(ANA_VLANACCESS_VLAN_TBL_CMD_SET(VLANACCESS_CMD_WRITE), 47 ANA_VLANACCESS_VLAN_TBL_CMD, 48 lan966x, ANA_VLANACCESS); 49 50 if (lan966x_vlan_wait_for_completion(lan966x)) 51 dev_err(lan966x->dev, "Vlan set mask failed\n"); 52 } 53 54 static void lan966x_vlan_port_add_vlan_mask(struct lan966x_port *port, u16 vid) 55 { 56 struct lan966x *lan966x = port->lan966x; 57 u8 p = port->chip_port; 58 59 lan966x->vlan_mask[vid] |= BIT(p); 60 lan966x_vlan_set_mask(lan966x, vid); 61 } 62 63 static void lan966x_vlan_port_del_vlan_mask(struct lan966x_port *port, u16 vid) 64 { 65 struct lan966x *lan966x = port->lan966x; 66 u8 p = port->chip_port; 67 68 lan966x->vlan_mask[vid] &= ~BIT(p); 69 lan966x_vlan_set_mask(lan966x, vid); 70 } 71 72 static bool lan966x_vlan_port_any_vlan_mask(struct lan966x *lan966x, u16 vid) 73 { 74 return !!(lan966x->vlan_mask[vid] & ~BIT(CPU_PORT)); 75 } 76 77 static void lan966x_vlan_cpu_add_vlan_mask(struct lan966x *lan966x, u16 vid) 78 { 79 lan966x->vlan_mask[vid] |= BIT(CPU_PORT); 80 lan966x_vlan_set_mask(lan966x, vid); 81 } 82 83 static void lan966x_vlan_cpu_del_vlan_mask(struct lan966x *lan966x, u16 vid) 84 { 85 lan966x->vlan_mask[vid] &= ~BIT(CPU_PORT); 86 lan966x_vlan_set_mask(lan966x, vid); 87 } 88 89 static void lan966x_vlan_cpu_add_cpu_vlan_mask(struct lan966x *lan966x, u16 vid) 90 { 91 __set_bit(vid, lan966x->cpu_vlan_mask); 92 } 93 94 static void lan966x_vlan_cpu_del_cpu_vlan_mask(struct lan966x *lan966x, u16 vid) 95 { 96 __clear_bit(vid, lan966x->cpu_vlan_mask); 97 } 98 99 bool lan966x_vlan_cpu_member_cpu_vlan_mask(struct lan966x *lan966x, u16 vid) 100 { 101 return test_bit(vid, lan966x->cpu_vlan_mask); 102 } 103 104 static u16 lan966x_vlan_port_get_pvid(struct lan966x_port *port) 105 { 106 struct lan966x *lan966x = port->lan966x; 107 108 if (!(lan966x->bridge_mask & BIT(port->chip_port))) 109 return HOST_PVID; 110 111 return port->vlan_aware ? port->pvid : UNAWARE_PVID; 112 } 113 114 int lan966x_vlan_port_set_vid(struct lan966x_port *port, u16 vid, 115 bool pvid, bool untagged) 116 { 117 struct lan966x *lan966x = port->lan966x; 118 119 /* Egress vlan classification */ 120 if (untagged && port->vid != vid) { 121 if (port->vid) { 122 dev_err(lan966x->dev, 123 "Port already has a native VLAN: %d\n", 124 port->vid); 125 return -EBUSY; 126 } 127 port->vid = vid; 128 } 129 130 /* Default ingress vlan classification */ 131 if (pvid) 132 port->pvid = vid; 133 134 return 0; 135 } 136 137 static void lan966x_vlan_port_remove_vid(struct lan966x_port *port, u16 vid) 138 { 139 if (port->pvid == vid) 140 port->pvid = 0; 141 142 if (port->vid == vid) 143 port->vid = 0; 144 } 145 146 void lan966x_vlan_port_set_vlan_aware(struct lan966x_port *port, 147 bool vlan_aware) 148 { 149 port->vlan_aware = vlan_aware; 150 } 151 152 void lan966x_vlan_port_apply(struct lan966x_port *port) 153 { 154 struct lan966x *lan966x = port->lan966x; 155 u16 pvid; 156 u32 val; 157 158 pvid = lan966x_vlan_port_get_pvid(port); 159 160 /* Ingress clasification (ANA_PORT_VLAN_CFG) */ 161 /* Default vlan to classify for untagged frames (may be zero) */ 162 val = ANA_VLAN_CFG_VLAN_VID_SET(pvid); 163 if (port->vlan_aware) 164 val |= ANA_VLAN_CFG_VLAN_AWARE_ENA_SET(1) | 165 ANA_VLAN_CFG_VLAN_POP_CNT_SET(1); 166 167 lan_rmw(val, 168 ANA_VLAN_CFG_VLAN_VID | ANA_VLAN_CFG_VLAN_AWARE_ENA | 169 ANA_VLAN_CFG_VLAN_POP_CNT, 170 lan966x, ANA_VLAN_CFG(port->chip_port)); 171 172 /* Drop frames with multicast source address */ 173 val = ANA_DROP_CFG_DROP_MC_SMAC_ENA_SET(1); 174 if (port->vlan_aware && !pvid) 175 /* If port is vlan-aware and tagged, drop untagged and priority 176 * tagged frames. 177 */ 178 val |= ANA_DROP_CFG_DROP_UNTAGGED_ENA_SET(1) | 179 ANA_DROP_CFG_DROP_PRIO_S_TAGGED_ENA_SET(1) | 180 ANA_DROP_CFG_DROP_PRIO_C_TAGGED_ENA_SET(1); 181 182 lan_wr(val, lan966x, ANA_DROP_CFG(port->chip_port)); 183 184 /* Egress configuration (REW_TAG_CFG): VLAN tag type to 8021Q */ 185 val = REW_TAG_CFG_TAG_TPID_CFG_SET(0); 186 if (port->vlan_aware) { 187 if (port->vid) 188 /* Tag all frames except when VID == DEFAULT_VLAN */ 189 val |= REW_TAG_CFG_TAG_CFG_SET(1); 190 else 191 val |= REW_TAG_CFG_TAG_CFG_SET(3); 192 } 193 194 /* Update only some bits in the register */ 195 lan_rmw(val, 196 REW_TAG_CFG_TAG_TPID_CFG | REW_TAG_CFG_TAG_CFG, 197 lan966x, REW_TAG_CFG(port->chip_port)); 198 199 /* Set default VLAN and tag type to 8021Q */ 200 lan_rmw(REW_PORT_VLAN_CFG_PORT_TPID_SET(ETH_P_8021Q) | 201 REW_PORT_VLAN_CFG_PORT_VID_SET(port->vid), 202 REW_PORT_VLAN_CFG_PORT_TPID | 203 REW_PORT_VLAN_CFG_PORT_VID, 204 lan966x, REW_PORT_VLAN_CFG(port->chip_port)); 205 } 206 207 void lan966x_vlan_port_add_vlan(struct lan966x_port *port, 208 u16 vid, 209 bool pvid, 210 bool untagged) 211 { 212 struct lan966x *lan966x = port->lan966x; 213 214 /* If the CPU(br) is already part of the vlan then add the fdb 215 * entries in MAC table to copy the frames to the CPU(br). 216 * If the CPU(br) is not part of the vlan then it would 217 * just drop the frames. 218 */ 219 if (lan966x_vlan_cpu_member_cpu_vlan_mask(lan966x, vid)) { 220 lan966x_vlan_cpu_add_vlan_mask(lan966x, vid); 221 lan966x_fdb_write_entries(lan966x, vid); 222 lan966x_mdb_write_entries(lan966x, vid); 223 } 224 225 lan966x_vlan_port_set_vid(port, vid, pvid, untagged); 226 lan966x_vlan_port_add_vlan_mask(port, vid); 227 lan966x_vlan_port_apply(port); 228 } 229 230 void lan966x_vlan_port_del_vlan(struct lan966x_port *port, u16 vid) 231 { 232 struct lan966x *lan966x = port->lan966x; 233 234 lan966x_vlan_port_remove_vid(port, vid); 235 lan966x_vlan_port_del_vlan_mask(port, vid); 236 lan966x_vlan_port_apply(port); 237 238 /* In case there are no other ports in vlan then remove the CPU from 239 * that vlan but still keep it in the mask because it may be needed 240 * again then another port gets added in that vlan 241 */ 242 if (!lan966x_vlan_port_any_vlan_mask(lan966x, vid)) { 243 lan966x_vlan_cpu_del_vlan_mask(lan966x, vid); 244 lan966x_fdb_erase_entries(lan966x, vid); 245 lan966x_mdb_erase_entries(lan966x, vid); 246 } 247 } 248 249 void lan966x_vlan_cpu_add_vlan(struct lan966x *lan966x, u16 vid) 250 { 251 /* Add an entry in the MAC table for the CPU 252 * Add the CPU part of the vlan only if there is another port in that 253 * vlan otherwise all the broadcast frames in that vlan will go to CPU 254 * even if none of the ports are in the vlan and then the CPU will just 255 * need to discard these frames. It is required to store this 256 * information so when a front port is added then it would add also the 257 * CPU port. 258 */ 259 if (lan966x_vlan_port_any_vlan_mask(lan966x, vid)) { 260 lan966x_vlan_cpu_add_vlan_mask(lan966x, vid); 261 lan966x_mdb_write_entries(lan966x, vid); 262 } 263 264 lan966x_vlan_cpu_add_cpu_vlan_mask(lan966x, vid); 265 lan966x_fdb_write_entries(lan966x, vid); 266 } 267 268 void lan966x_vlan_cpu_del_vlan(struct lan966x *lan966x, u16 vid) 269 { 270 /* Remove the CPU part of the vlan */ 271 lan966x_vlan_cpu_del_cpu_vlan_mask(lan966x, vid); 272 lan966x_vlan_cpu_del_vlan_mask(lan966x, vid); 273 lan966x_fdb_erase_entries(lan966x, vid); 274 lan966x_mdb_erase_entries(lan966x, vid); 275 } 276 277 void lan966x_vlan_init(struct lan966x *lan966x) 278 { 279 u16 port, vid; 280 281 /* Clear VLAN table, by default all ports are members of all VLANS */ 282 lan_rmw(ANA_VLANACCESS_VLAN_TBL_CMD_SET(VLANACCESS_CMD_INIT), 283 ANA_VLANACCESS_VLAN_TBL_CMD, 284 lan966x, ANA_VLANACCESS); 285 lan966x_vlan_wait_for_completion(lan966x); 286 287 for (vid = 1; vid < VLAN_N_VID; vid++) { 288 lan966x->vlan_mask[vid] = 0; 289 lan966x_vlan_set_mask(lan966x, vid); 290 } 291 292 /* Set all the ports + cpu to be part of HOST_PVID and UNAWARE_PVID */ 293 lan966x->vlan_mask[HOST_PVID] = 294 GENMASK(lan966x->num_phys_ports - 1, 0) | BIT(CPU_PORT); 295 lan966x_vlan_set_mask(lan966x, HOST_PVID); 296 297 lan966x->vlan_mask[UNAWARE_PVID] = 298 GENMASK(lan966x->num_phys_ports - 1, 0) | BIT(CPU_PORT); 299 lan966x_vlan_set_mask(lan966x, UNAWARE_PVID); 300 301 lan966x_vlan_cpu_add_cpu_vlan_mask(lan966x, UNAWARE_PVID); 302 303 /* Configure the CPU port to be vlan aware */ 304 lan_wr(ANA_VLAN_CFG_VLAN_VID_SET(0) | 305 ANA_VLAN_CFG_VLAN_AWARE_ENA_SET(1) | 306 ANA_VLAN_CFG_VLAN_POP_CNT_SET(1), 307 lan966x, ANA_VLAN_CFG(CPU_PORT)); 308 309 /* Set vlan ingress filter mask to all ports */ 310 lan_wr(GENMASK(lan966x->num_phys_ports, 0), 311 lan966x, ANA_VLANMASK); 312 313 for (port = 0; port < lan966x->num_phys_ports; port++) { 314 lan_wr(0, lan966x, REW_PORT_VLAN_CFG(port)); 315 lan_wr(0, lan966x, REW_TAG_CFG(port)); 316 } 317 } 318