1 // SPDX-License-Identifier: GPL-2.0 2 /* VLAN configuration interface for the rtl8365mb switch family 3 * 4 * Copyright (C) 2022 Alvin Šipraga <alsi@bang-olufsen.dk> 5 * 6 * VLAN configuration takes place in two separate domains of the switch: the 7 * VLAN4k table and the VLAN membership configuration (MC) database. While the 8 * VLAN4k table is exhaustive and can be fully populated with 4096 VLAN 9 * configurations, the same does not hold for the VLAN membership configuration 10 * database, which is limited to 32 entries. 11 * 12 * The switch will normally only use the VLAN4k table when making forwarding 13 * decisions. The VLAN membership configuration database is a vestigial ASIC 14 * design and is only used for a few specific features in the rtl8365mb 15 * family. This means that the limit of 32 entries should not hinder us in 16 * programming a huge number of VLANs into the switch. 17 * 18 * One necessary use of the VLAN membership configuration database is for the 19 * programming of a port-based VLAN ID (PVID). The PVID is programmed on a 20 * per-port basis via register field, which refers to a specific VLAN membership 21 * configuration via an index 0~31. In order to maintain coherent behaviour on a 22 * port with a PVID, it is necessary to keep the VLAN configuration synchronized 23 * between the VLAN4k table and the VLAN membership configuration database. 24 * 25 * Since VLAN membership configs are a scarce resource, it will only be used 26 * when strictly needed (i.e. a VLAN with members using PVID). Otherwise, the 27 * VLAN4k will be enough. 28 * 29 * With some exceptions, the entries in both the VLAN4k table and the VLAN 30 * membership configuration database offer the same configuration options. The 31 * differences are as follows: 32 * 33 * 1. VLAN4k entries can specify whether to use Independent or Shared VLAN 34 * Learning (IVL or SVL respectively). VLAN membership config entries 35 * cannot. This underscores the fact that VLAN membership configs are not 36 * involved in the learning process of the ASIC. 37 * 38 * 2. VLAN membership config entries use an "enhanced VLAN ID" (efid), which has 39 * a range 0~8191 compared with the standard 0~4095 range of the VLAN4k 40 * table. This underscores the fact that VLAN membership configs can be used 41 * to group ports on a layer beyond the standard VLAN configuration, which 42 * may be useful for ACL rules which specify alternative forwarding 43 * decisions. 44 * 45 * VLANMC index 0 is reserved as a neutral PVID, used for standalone ports. 46 * 47 */ 48 49 #include "rtl8365mb_vlan.h" 50 #include "rtl8365mb_table.h" 51 #include <linux/if_bridge.h> 52 #include <linux/lockdep.h> 53 #include <linux/regmap.h> 54 55 /* CVLAN (i.e. VLAN4k) table entry layout, u16[3] */ 56 #define RTL8365MB_CVLAN_ENTRY_SIZE 3 /* 48-bits */ 57 #define RTL8365MB_CVLAN_ENTRY_D0_MBR_MASK GENMASK(7, 0) 58 #define RTL8365MB_CVLAN_MBR_LO_MASK GENMASK(7, 0) 59 #define RTL8365MB_CVLAN_ENTRY_D0_UNTAG_MASK GENMASK(15, 8) 60 #define RTL8365MB_CVLAN_UNTAG_LO_MASK GENMASK(7, 0) 61 #define RTL8365MB_CVLAN_ENTRY_D1_FID_MASK GENMASK(3, 0) 62 #define RTL8365MB_CVLAN_ENTRY_D1_VBPEN_MASK GENMASK(4, 4) 63 #define RTL8365MB_CVLAN_ENTRY_D1_VBPRI_MASK GENMASK(7, 5) 64 #define RTL8365MB_CVLAN_ENTRY_D1_ENVLANPOL_MASK GENMASK(8, 8) 65 #define RTL8365MB_CVLAN_ENTRY_D1_METERIDX_MASK GENMASK(13, 9) 66 #define RTL8365MB_CVLAN_METERIDX_LO_MASK GENMASK(4, 0) 67 #define RTL8365MB_CVLAN_ENTRY_D1_IVL_SVL_MASK GENMASK(14, 14) 68 /* extends RTL8365MB_CVLAN_ENTRY_D0_MBR_MASK */ 69 #define RTL8365MB_CVLAN_ENTRY_D2_MBR_EXT_MASK GENMASK(2, 0) 70 #define RTL8365MB_CVLAN_MBR_HI_MASK GENMASK(10, 8) 71 /* extends RTL8365MB_CVLAN_ENTRY_D0_UNTAG_MASK */ 72 #define RTL8365MB_CVLAN_ENTRY_D2_UNTAG_EXT_MASK GENMASK(5, 3) 73 #define RTL8365MB_CVLAN_UNTAG_HI_MASK GENMASK(10, 8) 74 /* extends RTL8365MB_CVLAN_ENTRY_D1_METERIDX_MASK */ 75 #define RTL8365MB_CVLAN_ENTRY_D2_METERIDX_EXT_MASK GENMASK(6, 6) 76 #define RTL8365MB_CVLAN_METERIDX_HI_MASK GENMASK(5, 5) 77 78 /* VLAN member configuration registers 0~31, u16[3] */ 79 #define RTL8365MB_VLAN_MC_BASE 0x0728 80 #define RTL8365MB_VLAN_MC_ENTRY_SIZE 4 /* 64-bit */ 81 #define RTL8365MB_VLAN_MC_REG(index) \ 82 (RTL8365MB_VLAN_MC_BASE + \ 83 (RTL8365MB_VLAN_MC_ENTRY_SIZE * (index))) 84 #define RTL8365MB_VLAN_MC_D0_MBR_MASK GENMASK(10, 0) 85 #define RTL8365MB_VLAN_MC_D1_FID_MASK GENMASK(3, 0) 86 87 #define RTL8365MB_VLAN_MC_D2_VBPEN_MASK GENMASK(0, 0) 88 #define RTL8365MB_VLAN_MC_D2_VBPRI_MASK GENMASK(3, 1) 89 #define RTL8365MB_VLAN_MC_D2_ENVLANPOL_MASK GENMASK(4, 4) 90 #define RTL8365MB_VLAN_MC_D2_METERIDX_MASK GENMASK(10, 5) 91 #define RTL8365MB_VLAN_MC_D3_EVID_MASK GENMASK(12, 0) 92 93 /* Some limits for VLAN4k/VLAN membership config entries */ 94 #define RTL8365MB_PRIORITYMAX 7 95 #define RTL8365MB_FIDMAX 15 96 #define RTL8365MB_METERMAX 63 97 #define RTL8365MB_VLAN_MCMAX 31 98 99 /* RTL8367S supports 4k vlans (vid<=4095) and 32 enhanced vlans 100 * for VIDs up to 8191 101 */ 102 #define RTL8365MB_MAX_4K_VID 0x0FFF /* 4095 */ 103 #define RTL8365MB_MAX_MC_VID 0x1FFF /* 8191 */ 104 105 /* Port-based VID registers 0~5 - each one holds an MC index for two ports */ 106 #define RTL8365MB_VLAN_PVID_CTRL_BASE 0x0700 107 #define RTL8365MB_VLAN_PVID_CTRL_REG(_p) \ 108 (RTL8365MB_VLAN_PVID_CTRL_BASE + ((_p) >> 1)) 109 #define RTL8365MB_VLAN_PVID_CTRL_PORT0_MCIDX_MASK 0x001F 110 #define RTL8365MB_VLAN_PVID_CTRL_PORT1_MCIDX_MASK 0x1F00 111 #define RTL8365MB_VLAN_PVID_CTRL_PORT_MCIDX_OFFSET(_p) \ 112 (((_p) & 1) << 3) 113 #define RTL8365MB_VLAN_PVID_CTRL_PORT_MCIDX_MASK(_p) \ 114 (0x1F << RTL8365MB_VLAN_PVID_CTRL_PORT_MCIDX_OFFSET(_p)) 115 116 /* Frame type filtering registers */ 117 #define RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_BASE 0x07aa 118 #define RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_REG(port) \ 119 (RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_BASE + ((port) >> 3)) 120 /* required as FIELD_PREP cannot use non-constant masks */ 121 #define RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_MASK(port) \ 122 (0x3 << RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_OFFSET(port)) 123 #define RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_OFFSET(port) \ 124 (((port) & 0x7) << 1) 125 126 /* 127 * struct rtl8365mb_vlan4k - VLAN4k table entry 128 * @vid: VLAN ID (0~4095) 129 * @member: port mask of ports in this VLAN 130 * @untag: port mask of ports which untag on egress 131 * @fid: filter ID - only used with SVL (unused) 132 * @priority: priority classification (unused) 133 * @priority_en: enable priority (unused) 134 * @policing_en: enable policing (unused) 135 * @ivl_en: enable IVL instead of default SVL 136 * @meteridx: metering index (unused) 137 * 138 * This structure is used to get/set entries in the VLAN4k table. The 139 * VLAN4k table dictates the VLAN configuration for the switch for the 140 * vast majority of features. 141 */ 142 struct rtl8365mb_vlan4k { 143 u16 vid; 144 u16 member; 145 u16 untag; 146 u8 fid : 4; 147 u8 priority : 3; 148 u8 priority_en : 1; 149 u8 policing_en : 1; 150 u8 ivl_en : 1; 151 u8 meteridx : 6; 152 }; 153 154 /* 155 * struct rtl8365mb_vlanmc - VLAN membership config 156 * @evid: Enhanced VLAN ID (0~8191) 157 * @member: port mask of ports in this VLAN 158 * @fid: filter ID - only used with SVL (unused) 159 * @priority: priority classification (unused) 160 * @priority_en: enable priority (unused) 161 * @policing_en: enable policing (unused) 162 * @meteridx: metering index (unused) 163 * 164 * This structure is used to get/set entries in the VLAN membership 165 * configuration database. This feature is largely vestigial, but 166 * still needed for at least the following features: 167 * - PVID configuration 168 * - ACL configuration 169 * - selection of VLAN by the CPU tag when VSEL=1, although the switch 170 * can also select VLAN based on the VLAN tag if VSEL=0 171 * 172 * This is a low-level structure and it is recommended to interface with 173 * the VLAN membership config database via &struct rtl8365mb_vlanmc_entry. 174 */ 175 struct rtl8365mb_vlanmc { 176 u16 evid; 177 u16 member; 178 u8 fid : 4; 179 u8 priority : 3; 180 u8 priority_en : 1; 181 u8 policing_en : 1; 182 u8 meteridx : 6; 183 }; 184 185 static int rtl8365mb_vlan_4k_read(struct realtek_priv *priv, u16 vid, 186 struct rtl8365mb_vlan4k *vlan4k) 187 { 188 u16 data[RTL8365MB_CVLAN_ENTRY_SIZE]; 189 int val; 190 int ret; 191 192 ret = rtl8365mb_table_query(priv, RTL8365MB_TABLE_CVLAN, 193 RTL8365MB_TABLE_OP_READ, &vid, 0, 0, 194 data, ARRAY_SIZE(data)); 195 if (ret) 196 return ret; 197 198 /* Unpack table entry */ 199 memset(vlan4k, 0, sizeof(*vlan4k)); 200 vlan4k->vid = vid; 201 202 val = FIELD_GET(RTL8365MB_CVLAN_ENTRY_D0_MBR_MASK, data[0]); 203 vlan4k->member = FIELD_PREP(RTL8365MB_CVLAN_MBR_LO_MASK, val); 204 val = FIELD_GET(RTL8365MB_CVLAN_ENTRY_D2_MBR_EXT_MASK, data[2]); 205 vlan4k->member |= FIELD_PREP(RTL8365MB_CVLAN_MBR_HI_MASK, val); 206 207 val = FIELD_GET(RTL8365MB_CVLAN_ENTRY_D0_UNTAG_MASK, data[0]); 208 vlan4k->untag = FIELD_PREP(RTL8365MB_CVLAN_UNTAG_LO_MASK, val); 209 val = FIELD_GET(RTL8365MB_CVLAN_ENTRY_D2_UNTAG_EXT_MASK, data[2]); 210 vlan4k->untag |= FIELD_PREP(RTL8365MB_CVLAN_UNTAG_HI_MASK, val); 211 212 vlan4k->fid = FIELD_GET(RTL8365MB_CVLAN_ENTRY_D1_FID_MASK, data[1]); 213 vlan4k->priority_en = 214 FIELD_GET(RTL8365MB_CVLAN_ENTRY_D1_VBPEN_MASK, data[1]); 215 vlan4k->priority = 216 FIELD_GET(RTL8365MB_CVLAN_ENTRY_D1_VBPRI_MASK, data[1]); 217 vlan4k->policing_en = 218 FIELD_GET(RTL8365MB_CVLAN_ENTRY_D1_ENVLANPOL_MASK, data[1]); 219 220 val = FIELD_GET(RTL8365MB_CVLAN_ENTRY_D1_METERIDX_MASK, data[1]); 221 val = FIELD_PREP(RTL8365MB_CVLAN_METERIDX_LO_MASK, val); 222 vlan4k->meteridx = val; 223 val = FIELD_GET(RTL8365MB_CVLAN_ENTRY_D2_METERIDX_EXT_MASK, data[2]); 224 val = FIELD_PREP(RTL8365MB_CVLAN_METERIDX_HI_MASK, val); 225 vlan4k->meteridx |= val; 226 227 vlan4k->ivl_en = 228 FIELD_GET(RTL8365MB_CVLAN_ENTRY_D1_IVL_SVL_MASK, data[1]); 229 230 return 0; 231 } 232 233 static int rtl8365mb_vlan_4k_write(struct realtek_priv *priv, 234 const struct rtl8365mb_vlan4k *vlan4k) 235 { 236 u16 data[RTL8365MB_CVLAN_ENTRY_SIZE] = { 0 }; 237 u16 vid; 238 int val; 239 240 /* Pack table entry value */ 241 val = FIELD_GET(RTL8365MB_CVLAN_MBR_LO_MASK, vlan4k->member); 242 data[0] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D0_MBR_MASK, val); 243 244 val = FIELD_GET(RTL8365MB_CVLAN_UNTAG_LO_MASK, vlan4k->untag); 245 data[0] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D0_UNTAG_MASK, val); 246 247 data[1] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D1_FID_MASK, vlan4k->fid); 248 data[1] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D1_VBPEN_MASK, 249 vlan4k->priority_en); 250 data[1] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D1_VBPRI_MASK, 251 vlan4k->priority); 252 data[1] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D1_ENVLANPOL_MASK, 253 vlan4k->policing_en); 254 255 /* FIELD_* does not play nice with struct bitfield. */ 256 val = vlan4k->meteridx; 257 val = FIELD_GET(RTL8365MB_CVLAN_METERIDX_LO_MASK, val); 258 data[1] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D1_METERIDX_MASK, val); 259 260 data[1] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D1_IVL_SVL_MASK, 261 vlan4k->ivl_en); 262 263 val = FIELD_GET(RTL8365MB_CVLAN_MBR_HI_MASK, vlan4k->member); 264 data[2] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D2_MBR_EXT_MASK, val); 265 266 val = FIELD_GET(RTL8365MB_CVLAN_UNTAG_HI_MASK, vlan4k->untag); 267 data[2] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D2_UNTAG_EXT_MASK, val); 268 269 val = vlan4k->meteridx; 270 val = FIELD_GET(RTL8365MB_CVLAN_METERIDX_HI_MASK, val); 271 data[2] |= FIELD_PREP(RTL8365MB_CVLAN_ENTRY_D2_METERIDX_EXT_MASK, val); 272 273 vid = vlan4k->vid; 274 return rtl8365mb_table_query(priv, RTL8365MB_TABLE_CVLAN, 275 RTL8365MB_TABLE_OP_WRITE, &vid, 0, 0, 276 data, ARRAY_SIZE(data)); 277 } 278 279 static int 280 rtl8365mb_vlan_4k_port_set(struct dsa_switch *ds, int port, 281 const struct switchdev_obj_port_vlan *vlan, 282 struct netlink_ext_ack *extack, 283 bool include) 284 { 285 struct realtek_priv *priv = ds->priv; 286 struct rtl8365mb_vlan4k vlan4k = {0}; 287 int ret; 288 289 dev_dbg(priv->dev, "%s VLAN %d 4K on port %d\n", 290 include ? "add" : "del", 291 vlan->vid, port); 292 293 if (vlan->vid > RTL8365MB_MAX_4K_VID) { 294 NL_SET_ERR_MSG_MOD(extack, "VLAN ID greater than " 295 __stringify(RTL8365MB_MAX_4K_VID)); 296 return -EINVAL; 297 } 298 299 ret = rtl8365mb_vlan_4k_read(priv, vlan->vid, &vlan4k); 300 if (ret) { 301 dev_err(priv->dev, "Failed to read VLAN 4k table\n"); 302 return ret; 303 } 304 305 if (include) 306 vlan4k.member |= BIT(port); 307 else 308 vlan4k.member &= ~BIT(port); 309 310 if (include && (vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)) 311 vlan4k.untag |= BIT(port); 312 else 313 vlan4k.untag &= ~BIT(port); 314 vlan4k.ivl_en = true; /* always use Independent VLAN Learning */ 315 316 ret = rtl8365mb_vlan_4k_write(priv, &vlan4k); 317 if (ret) { 318 dev_err(priv->dev, "Failed to write VLAN 4k table\n"); 319 return ret; 320 } 321 322 return 0; 323 } 324 325 /* 326 * rtl8365mb_vlan_4k_port_add() - Add a port to a VLAN 4K table entry 327 * @ds: dsa switch instance 328 * @port: port index 329 * @vlan: switchdev VLAN object containing the target VID and flags 330 * @extack: netlink extended ACK for error reporting 331 * 332 * Adds the specified port to the hardware VLAN 4K membership table. 333 * 334 * Context: Can sleep. Must be called with &priv->vlan_lock held. 335 * Takes and releases &priv->map_lock. 336 * Return: 0 on success, or a negative error code on failure. 337 */ 338 int rtl8365mb_vlan_4k_port_add(struct dsa_switch *ds, int port, 339 const struct switchdev_obj_port_vlan *vlan, 340 struct netlink_ext_ack *extack) 341 { 342 struct realtek_priv *priv = ds->priv; 343 344 lockdep_assert_held(&priv->vlan_lock); 345 346 return rtl8365mb_vlan_4k_port_set(ds, port, vlan, extack, true); 347 } 348 349 /* 350 * rtl8365mb_vlan_4k_port_del() - Remove a port from a VLAN 4K table entry 351 * @ds: dsa switch instance 352 * @port: port index 353 * @vlan: switchdev VLAN object containing the target VID 354 * 355 * Removes the specified port from the hardware VLAN 4K membership table. 356 * 357 * Context: Can sleep. Must be called with &priv->vlan_lock held. 358 * Takes and releases &priv->map_lock. 359 * Return: 0 on success, or a negative error code on failure. 360 */ 361 int rtl8365mb_vlan_4k_port_del(struct dsa_switch *ds, int port, 362 const struct switchdev_obj_port_vlan *vlan) 363 { 364 struct realtek_priv *priv = ds->priv; 365 366 lockdep_assert_held(&priv->vlan_lock); 367 368 return rtl8365mb_vlan_4k_port_set(ds, port, vlan, NULL, false); 369 } 370 371 static int rtl8365mb_vlan_mc_read(struct realtek_priv *priv, u32 index, 372 struct rtl8365mb_vlanmc *vlanmc) 373 { 374 u16 data[RTL8365MB_VLAN_MC_ENTRY_SIZE]; 375 int ret; 376 377 ret = regmap_bulk_read(priv->map, RTL8365MB_VLAN_MC_REG(index), &data, 378 RTL8365MB_VLAN_MC_ENTRY_SIZE); 379 if (ret) 380 return ret; 381 382 vlanmc->member = FIELD_GET(RTL8365MB_VLAN_MC_D0_MBR_MASK, data[0]); 383 vlanmc->fid = FIELD_GET(RTL8365MB_VLAN_MC_D1_FID_MASK, data[1]); 384 vlanmc->meteridx = FIELD_GET(RTL8365MB_VLAN_MC_D2_METERIDX_MASK, 385 data[2]); 386 vlanmc->policing_en = FIELD_GET(RTL8365MB_VLAN_MC_D2_ENVLANPOL_MASK, 387 data[2]); 388 vlanmc->priority = FIELD_GET(RTL8365MB_VLAN_MC_D2_VBPRI_MASK, data[2]); 389 vlanmc->priority_en = FIELD_GET(RTL8365MB_VLAN_MC_D2_VBPEN_MASK, 390 data[2]); 391 vlanmc->evid = FIELD_GET(RTL8365MB_VLAN_MC_D3_EVID_MASK, data[3]); 392 393 return 0; 394 } 395 396 static int rtl8365mb_vlan_mc_write(struct realtek_priv *priv, u32 index, 397 const struct rtl8365mb_vlanmc *vlanmc) 398 { 399 u16 data[RTL8365MB_VLAN_MC_ENTRY_SIZE] = { 0 }; 400 int ret; 401 402 data[0] |= FIELD_PREP(RTL8365MB_VLAN_MC_D0_MBR_MASK, vlanmc->member); 403 data[1] |= FIELD_PREP(RTL8365MB_VLAN_MC_D1_FID_MASK, vlanmc->fid); 404 data[2] |= FIELD_PREP(RTL8365MB_VLAN_MC_D2_METERIDX_MASK, 405 vlanmc->meteridx); 406 data[2] |= FIELD_PREP(RTL8365MB_VLAN_MC_D2_ENVLANPOL_MASK, 407 vlanmc->policing_en); 408 data[2] |= 409 FIELD_PREP(RTL8365MB_VLAN_MC_D2_VBPRI_MASK, vlanmc->priority); 410 data[2] |= FIELD_PREP(RTL8365MB_VLAN_MC_D2_VBPEN_MASK, 411 vlanmc->priority_en); 412 data[3] |= FIELD_PREP(RTL8365MB_VLAN_MC_D3_EVID_MASK, vlanmc->evid); 413 414 ret = regmap_bulk_write(priv->map, RTL8365MB_VLAN_MC_REG(index), &data, 415 RTL8365MB_VLAN_MC_ENTRY_SIZE); 416 417 return ret; 418 } 419 420 static int rtl8365mb_vlan_mc_erase(struct realtek_priv *priv, u32 index) 421 { 422 u16 data[RTL8365MB_VLAN_MC_ENTRY_SIZE] = { 0 }; 423 int ret; 424 425 ret = regmap_bulk_write(priv->map, RTL8365MB_VLAN_MC_REG(index), &data, 426 RTL8365MB_VLAN_MC_ENTRY_SIZE); 427 428 return ret; 429 } 430 431 /* 432 * rtl8365mb_vlan_mc_find() - find VLANMC index by VID or the first free index 433 * 434 * @priv: realtek_priv pointer 435 * @vid: VLAN ID 436 * @index: found index 437 * @first_free: found free index 438 * 439 * If a VLAN MC entry using @vid was found, @index will return the matched index 440 * and @first_free is undefined. If not found, @index will return 0 and 441 * @first_free will return the first found free index in VLAN MC or 0 if the 442 * table is full. 443 * 444 * Although 0 is a valid VLAN MC index, it is reserved for ports without PVID, 445 * including standalone, non-member ports. It uses VID == 0. 446 * 447 * Both @index and @first_free will be in the * 1..@RTL8365MB_VLAN_MCMAX range. 448 * 449 * Return: Returns 0 on success, a negative error on failure. 450 */ 451 static int rtl8365mb_vlan_mc_find(struct realtek_priv *priv, u16 vid, 452 u8 *index, u8 *first_free) 453 { 454 u32 vlan_entry_d3; 455 u8 vlanmc_idx; 456 u16 evid; 457 int ret; 458 459 *index = 0; 460 *first_free = 0; 461 462 /* look for existing entry or an empty one */ 463 /* By design, VlanMC[0] is reserved as a neutral PVID value for 464 * standalone ports. It always has EVID == 0. That way, we assume that 465 * all entries after index 0 with VID == 0 are empty. 466 **/ 467 for (vlanmc_idx = 1; vlanmc_idx <= RTL8365MB_VLAN_MCMAX; vlanmc_idx++) { 468 /* just read the 4th word, where the evid is */ 469 ret = regmap_read(priv->map, 470 RTL8365MB_VLAN_MC_REG(vlanmc_idx) + 3, 471 &vlan_entry_d3); 472 if (ret) 473 return ret; 474 475 evid = FIELD_GET(RTL8365MB_VLAN_MC_D3_EVID_MASK, vlan_entry_d3); 476 477 if (evid == vid) { 478 *index = vlanmc_idx; 479 return 0; 480 } 481 482 if (evid == 0x0 && *first_free < 1) 483 *first_free = vlanmc_idx; 484 } 485 return 0; 486 } 487 488 static int rtl8365mb_vlan_port_get_pvid_idx(struct realtek_priv *priv, 489 int port, u8 *vlanmc_idx) 490 { 491 u32 data; 492 int ret; 493 494 ret = regmap_read(priv->map, RTL8365MB_VLAN_PVID_CTRL_REG(port), &data); 495 if (ret) 496 return ret; 497 498 *vlanmc_idx = (data & RTL8365MB_VLAN_PVID_CTRL_PORT_MCIDX_MASK(port)) 499 >> RTL8365MB_VLAN_PVID_CTRL_PORT_MCIDX_OFFSET(port); 500 501 return 0; 502 } 503 504 /* 505 * rtl8365mb_vlan_mc_port_set() - include or exclude a port from VlanMC 506 * @ds: dsa switch 507 * @port: the port number 508 * @vid: the vlan VID to include/exclude @port 509 * @pvid: inform if vid is used as pvid in @port 510 * @extack: optional extack to return errors 511 * @include: whether to include or exclude @port 512 * 513 * This function is used to include/exclude ports to the VlanMC table. 514 * 515 * VlanMC stands for VLAN membership config and it is used exclusively for 516 * PVID. If @vlan members are not using PVID, this function will either 517 * remove or not create a new VlanMC entry. 518 * 519 * VlanMC members are used as a reference port map, cleaning the entry once 520 * no port is using it. 521 * 522 * Port PVID and accepted frame type are updated as well. 523 * 524 * Context: Can sleep. Must be called with &priv->vlan_lock held. 525 * Takes and releases &priv->map_lock. 526 * Return: Returns 0 on success, a negative error on failure. 527 */ 528 static 529 int rtl8365mb_vlan_mc_port_set(struct dsa_switch *ds, int port, 530 u16 vid, bool pvid, 531 struct netlink_ext_ack *extack, 532 bool include) 533 { 534 struct realtek_priv *priv = ds->priv; 535 struct rtl8365mb_vlanmc vlanmc = {0}; 536 u8 first_unused = 0; 537 u8 vlanmc_idx = 0; 538 int ret; 539 540 dev_dbg(priv->dev, "%s VLAN %d MC on port %d\n", 541 include ? "add" : "del", 542 vid, port); 543 544 if (vid > RTL8365MB_MAX_MC_VID) { 545 NL_SET_ERR_MSG_MOD(extack, "VLAN ID greater than " 546 __stringify(RTL8365MB_MAX_MC_VID)); 547 return -EINVAL; 548 } 549 550 /* look for existing entry or an empty slot */ 551 ret = rtl8365mb_vlan_mc_find(priv, vid, &vlanmc_idx, 552 &first_unused); 553 if (ret) { 554 dev_err(priv->dev, "Failed to find a VLAN MC table index\n"); 555 return ret; 556 } 557 558 if (vlanmc_idx) { 559 ret = rtl8365mb_vlan_mc_read(priv, vlanmc_idx, &vlanmc); 560 if (ret) { 561 dev_err(priv->dev, "Failed to read VLAN MC table\n"); 562 return ret; 563 } 564 } else if (include) { 565 /* for now, vlan_mc is only required for PVID. Defer allocation 566 * until at least one port uses PVID. 567 */ 568 if (!pvid) { 569 dev_dbg(priv->dev, 570 "Not creating VlanMC for vlan %d until a port uses PVID (%d does not)\n", 571 vid, port); 572 return 0; 573 } 574 575 if (!first_unused) { 576 NL_SET_ERR_MSG_MOD(extack, "All VLAN MC entries (0.." 577 __stringify(RTL8365MB_VLAN_MCMAX) 578 ") are in use."); 579 return -ENOSPC; 580 } 581 582 vlanmc_idx = first_unused; 583 vlanmc.evid = vid; 584 585 } else /* excluding and VLANMC not found */ { 586 return 0; 587 } 588 589 dev_dbg(priv->dev, 590 "VLAN %d (idx: %d) PVID curr members: %08x\n", 591 vid, vlanmc_idx, vlanmc.member); 592 593 /* here we either have an existing VLANMC (with PVID members) or the 594 * added port is using this VLAN as PVID 595 */ 596 if (include) 597 vlanmc.member |= BIT(port); 598 else 599 vlanmc.member &= ~BIT(port); 600 601 /* just like we don't need to create a VLAN_MC when there is no port 602 * using it as PVID, we can erase it when there is no more port using 603 * it as PVID. 604 */ 605 if (!vlanmc.member) { 606 dev_dbg(priv->dev, 607 "Clearing VlanMC index %d previously used by VID %d\n", 608 vlanmc_idx, vid); 609 ret = rtl8365mb_vlan_mc_erase(priv, vlanmc_idx); 610 } else { 611 dev_dbg(priv->dev, 612 "Saving VlanMC index %d with VID %d\n", 613 vlanmc_idx, vid); 614 ret = rtl8365mb_vlan_mc_write(priv, vlanmc_idx, &vlanmc); 615 } 616 if (ret) { 617 dev_err(priv->dev, "Failed to write vlan MC entry\n"); 618 return ret; 619 } 620 621 return 0; 622 } 623 624 static int rtl8365mb_vlan_port_set_pvid(struct realtek_priv *priv, 625 int port, u16 vlanmc_idx) 626 { 627 int ret; 628 u32 val; 629 630 dev_dbg(priv->dev, "set PVID IDX %d on port %d\n", vlanmc_idx, port); 631 632 val = vlanmc_idx << RTL8365MB_VLAN_PVID_CTRL_PORT_MCIDX_OFFSET(port); 633 ret = regmap_update_bits(priv->map, 634 RTL8365MB_VLAN_PVID_CTRL_REG(port), 635 RTL8365MB_VLAN_PVID_CTRL_PORT_MCIDX_MASK(port), 636 val); 637 if (ret) 638 return ret; 639 640 return 0; 641 } 642 643 static int rtl8365mb_vlan_get_pvid_mc(struct realtek_priv *priv, 644 int port, u8 *vlanmc_idx, 645 struct rtl8365mb_vlanmc *vlanmc) 646 { 647 int ret; 648 649 ret = rtl8365mb_vlan_port_get_pvid_idx(priv, port, vlanmc_idx); 650 if (ret) 651 return ret; 652 653 memset(vlanmc, 0, sizeof(*vlanmc)); 654 655 if (!*vlanmc_idx) 656 return 0; 657 658 ret = rtl8365mb_vlan_mc_read(priv, *vlanmc_idx, vlanmc); 659 if (ret) 660 return ret; 661 662 return 0; 663 } 664 665 /* 666 * rtl8365mb_vlan_port_get_pvid - Retrieve the port PVID 667 * @priv: realtek switch private structure 668 * @port: port index 669 * @pvid: pointer to store the retrieved VLAN ID 670 * 671 * Returns the port PVID if defined or 0 if not. 672 * 673 * Context: Can sleep. Takes and releases &priv->map_lock. 674 * Return: 0 on success or a negative error code on failure. 675 */ 676 int rtl8365mb_vlan_port_get_pvid(struct realtek_priv *priv, int port, u16 *pvid) 677 { 678 struct rtl8365mb_vlanmc vlanmc; 679 u8 vlanmc_idx; 680 int ret; 681 682 ret = rtl8365mb_vlan_get_pvid_mc(priv, port, &vlanmc_idx, &vlanmc); 683 if (ret) 684 return ret; 685 686 *pvid = vlanmc.evid; 687 return 0; 688 } 689 690 /* 691 * rtl8365mb_vlan_port_get_framefilter() - Get the ingress frame filtering mode 692 * for a port 693 * @priv: realtek switch private structure 694 * @port: port index 695 * @frame_type: pointer to store the retrieved ingress frame filter type 696 * 697 * Context: Can sleep. Takes and releases &priv->map_lock. 698 * Return: 0 on success, or a negative error code on failure. 699 */ 700 int 701 rtl8365mb_vlan_port_get_framefilter(struct realtek_priv *priv, 702 int port, 703 enum rtl8365mb_frame_ingress *frame_type) 704 { 705 u32 val; 706 int ret; 707 708 /* Even if ACCEPT_FRAME_TYPE_ANY, the switch will still check if the 709 * port is a member of vlan PVID 710 */ 711 712 ret = regmap_read(priv->map, RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_REG(port), 713 &val); 714 if (ret) 715 return ret; 716 717 *frame_type = field_get(RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_MASK(port), 718 val); 719 720 return 0; 721 } 722 723 /* 724 * rtl8365mb_vlan_port_set_framefilter() - Set the ingress frame filtering mode 725 * for a port 726 * @priv: realtek switch private structure 727 * @port: port index 728 * @frame_type: the ingress frame filter type to configure 729 * 730 * Context: Can sleep. Takes and releases &priv->map_lock. 731 * Return: 0 on success, or a negative error code on failure. 732 */ 733 int 734 rtl8365mb_vlan_port_set_framefilter(struct realtek_priv *priv, 735 int port, 736 enum rtl8365mb_frame_ingress frame_type) 737 { 738 u32 val; 739 740 /* Even if ACCEPT_FRAME_TYPE_ANY, the switch will still check if the 741 * port is a member of vlan PVID 742 */ 743 val = frame_type << RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_OFFSET(port); 744 745 return regmap_update_bits(priv->map, 746 RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_REG(port), 747 RTL8365MB_VLAN_ACCEPT_FRAME_TYPE_MASK(port), 748 val); 749 } 750 751 /* 752 * rtl8365mb_vlan_pvid_port_set() - Configure a port's PVID and associated 753 * VLANMC entry 754 * @ds: dsa switch instance 755 * @port: port index 756 * @vid: target VID 757 * @extack: netlink extended ACK for error reporting 758 * 759 * Allocates or reuses a hardware VLANMC entry to map the given port to its new 760 * PVID. Gracefully unwinds and restores previous configuration if a hardware 761 * write operation fails during execution. 762 * 763 * Context: Can sleep. Must be called with &priv->vlan_lock held. 764 * Takes and releases &priv->map_lock. 765 * Return: 0 on success, or a negative error code on failure. 766 */ 767 int rtl8365mb_vlan_pvid_port_set(struct dsa_switch *ds, int port, u16 vid, 768 struct netlink_ext_ack *extack) 769 { 770 enum rtl8365mb_frame_ingress accepted_frame, prev_accepted_frame; 771 struct realtek_priv *priv = ds->priv; 772 struct rtl8365mb_vlanmc prev_vlanmc = {0}; 773 u8 _unused_first_free_idx; 774 u8 prev_vlanmc_idx; 775 u8 vlanmc_idx; 776 int ret; 777 778 lockdep_assert_held(&priv->vlan_lock); 779 780 /* Read the old PVID exclusively to undo in case of error */ 781 ret = rtl8365mb_vlan_get_pvid_mc(priv, port, &prev_vlanmc_idx, 782 &prev_vlanmc); 783 if (ret) { 784 dev_err(priv->dev, "Failed to read current VLAN MC\n"); 785 return ret; 786 } 787 788 ret = rtl8365mb_vlan_port_get_framefilter(priv, port, 789 &prev_accepted_frame); 790 if (ret) { 791 dev_err(priv->dev, "Failed to get current framefilter\n"); 792 return ret; 793 } 794 795 /* Find or allocate a new vlan MC and add port to members, 796 * although members are not checked by the HW in vlan MC. 797 */ 798 ret = rtl8365mb_vlan_mc_port_set(ds, port, vid, true, extack, true); 799 if (ret) 800 return ret; 801 802 /* look for existing entry */ 803 ret = rtl8365mb_vlan_mc_find(priv, vid, &vlanmc_idx, 804 &_unused_first_free_idx); 805 if (ret) { 806 dev_err(priv->dev, "Failed to find a VLAN MC table index\n"); 807 goto undo_vlan_mc_port_set; 808 } 809 810 if (!vlanmc_idx) { 811 dev_err(priv->dev, "VLAN should already exist in VLAN MC\n"); 812 ret = -ENOENT; 813 goto undo_vlan_mc_port_set; 814 } 815 816 ret = rtl8365mb_vlan_port_set_pvid(priv, port, vlanmc_idx); 817 if (ret) { 818 dev_err(priv->dev, "Failed to set port PVID\n"); 819 goto undo_vlan_mc_port_set; 820 } 821 822 /* Changing accept frame is what enables PVID (if not enabled before) */ 823 accepted_frame = RTL8365MB_FRAME_TYPE_ANY_FRAME; 824 ret = rtl8365mb_vlan_port_set_framefilter(priv, port, accepted_frame); 825 if (ret) { 826 dev_err(priv->dev, "Failed to set port frame filter\n"); 827 goto undo_vlan_port_set_pvid; 828 } 829 830 /* A VLAN can be added with PVID without removing from the old 831 * PVID VLAN. Clear PVID from the old VLAN MC (if needed). 832 */ 833 if (prev_vlanmc_idx && (prev_vlanmc.evid != vid)) { 834 ret = rtl8365mb_vlan_mc_port_set(ds, port, prev_vlanmc.evid, 835 false, NULL, false); 836 if (ret) { 837 dev_err(priv->dev, "Failed to clear old VLAN MC\n"); 838 goto undo_set_framefilter; 839 } 840 } 841 842 return 0; 843 844 undo_set_framefilter: 845 (void)rtl8365mb_vlan_port_set_framefilter(priv, port, 846 prev_accepted_frame); 847 848 undo_vlan_port_set_pvid: 849 (void)rtl8365mb_vlan_port_set_pvid(priv, port, prev_vlanmc_idx); 850 851 undo_vlan_mc_port_set: 852 if (prev_vlanmc.evid != vid) 853 (void)rtl8365mb_vlan_mc_port_set(ds, port, vid, false, NULL, 854 false); 855 856 return ret; 857 } 858 859 /* 860 * rtl8365mb_vlan_pvid_port_clear() - Remove a port's PVID configuration 861 * @ds: dsa switch instance 862 * @port: port index 863 * @vid: VLAN VID for PVID 864 * 865 * Resets the target port's hardware PVID allocation to 0. Cleans up and frees 866 * the associated VLANMC entry if no other ports are referencing it. 867 * 868 * Context: Can sleep. Must be called with &priv->vlan_lock held. 869 * Takes and releases &priv->map_lock. 870 * Return: 0 on success, or a negative error code on failure. 871 */ 872 int rtl8365mb_vlan_pvid_port_clear(struct dsa_switch *ds, int port, u16 vid) 873 { 874 enum rtl8365mb_frame_ingress accepted_frame, prev_accepted_frame; 875 struct realtek_priv *priv = ds->priv; 876 struct rtl8365mb_vlanmc vlanmc = {0}; 877 u8 vlanmc_idx; 878 int ret; 879 880 lockdep_assert_held(&priv->vlan_lock); 881 882 ret = rtl8365mb_vlan_get_pvid_mc(priv, port, &vlanmc_idx, 883 &vlanmc); 884 if (ret) { 885 dev_err(priv->dev, "Failed to read current VLAN MC\n"); 886 return ret; 887 } 888 889 /* Port is not using PVID. Nothing to remove. */ 890 if (!vlanmc_idx) 891 return 0; 892 893 /* We are leaving a non PVID vlan, Nothing to remove. */ 894 if (vlanmc.evid != vid) 895 return 0; 896 897 ret = rtl8365mb_vlan_port_get_framefilter(priv, port, 898 &prev_accepted_frame); 899 if (ret) { 900 dev_err(priv->dev, "Failed to get current framefilter\n"); 901 return ret; 902 } 903 904 /* Changing accept frame is what really removes PVID. But only do 905 * that if we are filtering vlan 906 */ 907 if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) { 908 accepted_frame = RTL8365MB_FRAME_TYPE_TAGGED_ONLY; 909 910 ret = rtl8365mb_vlan_port_set_framefilter(priv, port, 911 accepted_frame); 912 if (ret) { 913 dev_err(priv->dev, "Failed to set port frame filter\n"); 914 return ret; 915 } 916 } else { 917 /* skip undo_set_framefilter */ 918 accepted_frame = prev_accepted_frame; 919 } 920 921 ret = rtl8365mb_vlan_port_set_pvid(priv, port, 0); 922 if (ret) { 923 dev_err(priv->dev, "Failed to set port PVID to 0\n"); 924 goto undo_set_framefilter; 925 } 926 927 /* Clears the VLAN MC membership and maybe VLAN MC entry if empty */ 928 ret = rtl8365mb_vlan_mc_port_set(ds, port, vlanmc.evid, 929 false, NULL, false); 930 if (ret) 931 goto undo_port_set_pvid; 932 933 return 0; 934 935 undo_port_set_pvid: 936 (void)rtl8365mb_vlan_port_set_pvid(priv, port, vlanmc_idx); 937 938 undo_set_framefilter: 939 if (prev_accepted_frame != accepted_frame) 940 (void)rtl8365mb_vlan_port_set_framefilter(priv, port, 941 prev_accepted_frame); 942 943 return ret; 944 } 945