16d2c186aSHoratiu Vultur // SPDX-License-Identifier: GPL-2.0+
26d2c186aSHoratiu Vultur
36d2c186aSHoratiu Vultur #include "lan966x_main.h"
46d2c186aSHoratiu Vultur
56d2c186aSHoratiu Vultur #define VLANACCESS_CMD_IDLE 0
66d2c186aSHoratiu Vultur #define VLANACCESS_CMD_READ 1
76d2c186aSHoratiu Vultur #define VLANACCESS_CMD_WRITE 2
86d2c186aSHoratiu Vultur #define VLANACCESS_CMD_INIT 3
96d2c186aSHoratiu Vultur
lan966x_vlan_get_status(struct lan966x * lan966x)106d2c186aSHoratiu Vultur static int lan966x_vlan_get_status(struct lan966x *lan966x)
116d2c186aSHoratiu Vultur {
126d2c186aSHoratiu Vultur return lan_rd(lan966x, ANA_VLANACCESS);
136d2c186aSHoratiu Vultur }
146d2c186aSHoratiu Vultur
lan966x_vlan_wait_for_completion(struct lan966x * lan966x)156d2c186aSHoratiu Vultur static int lan966x_vlan_wait_for_completion(struct lan966x *lan966x)
166d2c186aSHoratiu Vultur {
176d2c186aSHoratiu Vultur u32 val;
186d2c186aSHoratiu Vultur
196d2c186aSHoratiu Vultur return readx_poll_timeout(lan966x_vlan_get_status,
206d2c186aSHoratiu Vultur lan966x, val,
216d2c186aSHoratiu Vultur (val & ANA_VLANACCESS_VLAN_TBL_CMD) ==
226d2c186aSHoratiu Vultur VLANACCESS_CMD_IDLE,
236d2c186aSHoratiu Vultur TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US);
246d2c186aSHoratiu Vultur }
256d2c186aSHoratiu Vultur
lan966x_vlan_set_mask(struct lan966x * lan966x,u16 vid)266d2c186aSHoratiu Vultur static void lan966x_vlan_set_mask(struct lan966x *lan966x, u16 vid)
276d2c186aSHoratiu Vultur {
286d2c186aSHoratiu Vultur u16 mask = lan966x->vlan_mask[vid];
296d2c186aSHoratiu Vultur bool cpu_dis;
306d2c186aSHoratiu Vultur
316d2c186aSHoratiu Vultur cpu_dis = !(mask & BIT(CPU_PORT));
326d2c186aSHoratiu Vultur
336d2c186aSHoratiu Vultur /* Set flags and the VID to configure */
346d2c186aSHoratiu Vultur lan_rmw(ANA_VLANTIDX_VLAN_PGID_CPU_DIS_SET(cpu_dis) |
356d2c186aSHoratiu Vultur ANA_VLANTIDX_V_INDEX_SET(vid),
366d2c186aSHoratiu Vultur ANA_VLANTIDX_VLAN_PGID_CPU_DIS |
376d2c186aSHoratiu Vultur ANA_VLANTIDX_V_INDEX,
386d2c186aSHoratiu Vultur lan966x, ANA_VLANTIDX);
396d2c186aSHoratiu Vultur
406d2c186aSHoratiu Vultur /* Set the vlan port members mask */
416d2c186aSHoratiu Vultur lan_rmw(ANA_VLAN_PORT_MASK_VLAN_PORT_MASK_SET(mask),
426d2c186aSHoratiu Vultur ANA_VLAN_PORT_MASK_VLAN_PORT_MASK,
436d2c186aSHoratiu Vultur lan966x, ANA_VLAN_PORT_MASK);
446d2c186aSHoratiu Vultur
456d2c186aSHoratiu Vultur /* Issue a write command */
466d2c186aSHoratiu Vultur lan_rmw(ANA_VLANACCESS_VLAN_TBL_CMD_SET(VLANACCESS_CMD_WRITE),
476d2c186aSHoratiu Vultur ANA_VLANACCESS_VLAN_TBL_CMD,
486d2c186aSHoratiu Vultur lan966x, ANA_VLANACCESS);
496d2c186aSHoratiu Vultur
506d2c186aSHoratiu Vultur if (lan966x_vlan_wait_for_completion(lan966x))
516d2c186aSHoratiu Vultur dev_err(lan966x->dev, "Vlan set mask failed\n");
526d2c186aSHoratiu Vultur }
536d2c186aSHoratiu Vultur
lan966x_vlan_port_add_vlan_mask(struct lan966x_port * port,u16 vid)546d2c186aSHoratiu Vultur static void lan966x_vlan_port_add_vlan_mask(struct lan966x_port *port, u16 vid)
556d2c186aSHoratiu Vultur {
566d2c186aSHoratiu Vultur struct lan966x *lan966x = port->lan966x;
576d2c186aSHoratiu Vultur u8 p = port->chip_port;
586d2c186aSHoratiu Vultur
596d2c186aSHoratiu Vultur lan966x->vlan_mask[vid] |= BIT(p);
606d2c186aSHoratiu Vultur lan966x_vlan_set_mask(lan966x, vid);
616d2c186aSHoratiu Vultur }
626d2c186aSHoratiu Vultur
lan966x_vlan_port_del_vlan_mask(struct lan966x_port * port,u16 vid)636d2c186aSHoratiu Vultur static void lan966x_vlan_port_del_vlan_mask(struct lan966x_port *port, u16 vid)
646d2c186aSHoratiu Vultur {
656d2c186aSHoratiu Vultur struct lan966x *lan966x = port->lan966x;
666d2c186aSHoratiu Vultur u8 p = port->chip_port;
676d2c186aSHoratiu Vultur
686d2c186aSHoratiu Vultur lan966x->vlan_mask[vid] &= ~BIT(p);
696d2c186aSHoratiu Vultur lan966x_vlan_set_mask(lan966x, vid);
706d2c186aSHoratiu Vultur }
716d2c186aSHoratiu Vultur
lan966x_vlan_port_any_vlan_mask(struct lan966x * lan966x,u16 vid)726d2c186aSHoratiu Vultur static bool lan966x_vlan_port_any_vlan_mask(struct lan966x *lan966x, u16 vid)
736d2c186aSHoratiu Vultur {
746d2c186aSHoratiu Vultur return !!(lan966x->vlan_mask[vid] & ~BIT(CPU_PORT));
756d2c186aSHoratiu Vultur }
766d2c186aSHoratiu Vultur
lan966x_vlan_cpu_add_vlan_mask(struct lan966x * lan966x,u16 vid)776d2c186aSHoratiu Vultur static void lan966x_vlan_cpu_add_vlan_mask(struct lan966x *lan966x, u16 vid)
786d2c186aSHoratiu Vultur {
796d2c186aSHoratiu Vultur lan966x->vlan_mask[vid] |= BIT(CPU_PORT);
806d2c186aSHoratiu Vultur lan966x_vlan_set_mask(lan966x, vid);
816d2c186aSHoratiu Vultur }
826d2c186aSHoratiu Vultur
lan966x_vlan_cpu_del_vlan_mask(struct lan966x * lan966x,u16 vid)836d2c186aSHoratiu Vultur static void lan966x_vlan_cpu_del_vlan_mask(struct lan966x *lan966x, u16 vid)
846d2c186aSHoratiu Vultur {
856d2c186aSHoratiu Vultur lan966x->vlan_mask[vid] &= ~BIT(CPU_PORT);
866d2c186aSHoratiu Vultur lan966x_vlan_set_mask(lan966x, vid);
876d2c186aSHoratiu Vultur }
886d2c186aSHoratiu Vultur
lan966x_vlan_cpu_add_cpu_vlan_mask(struct lan966x * lan966x,u16 vid)896d2c186aSHoratiu Vultur static void lan966x_vlan_cpu_add_cpu_vlan_mask(struct lan966x *lan966x, u16 vid)
906d2c186aSHoratiu Vultur {
916d2c186aSHoratiu Vultur __set_bit(vid, lan966x->cpu_vlan_mask);
926d2c186aSHoratiu Vultur }
936d2c186aSHoratiu Vultur
lan966x_vlan_cpu_del_cpu_vlan_mask(struct lan966x * lan966x,u16 vid)946d2c186aSHoratiu Vultur static void lan966x_vlan_cpu_del_cpu_vlan_mask(struct lan966x *lan966x, u16 vid)
956d2c186aSHoratiu Vultur {
966d2c186aSHoratiu Vultur __clear_bit(vid, lan966x->cpu_vlan_mask);
976d2c186aSHoratiu Vultur }
986d2c186aSHoratiu Vultur
lan966x_vlan_cpu_member_cpu_vlan_mask(struct lan966x * lan966x,u16 vid)996d2c186aSHoratiu Vultur bool lan966x_vlan_cpu_member_cpu_vlan_mask(struct lan966x *lan966x, u16 vid)
1006d2c186aSHoratiu Vultur {
1016d2c186aSHoratiu Vultur return test_bit(vid, lan966x->cpu_vlan_mask);
1026d2c186aSHoratiu Vultur }
1036d2c186aSHoratiu Vultur
lan966x_vlan_port_get_pvid(struct lan966x_port * port)1046d2c186aSHoratiu Vultur static u16 lan966x_vlan_port_get_pvid(struct lan966x_port *port)
1056d2c186aSHoratiu Vultur {
1066d2c186aSHoratiu Vultur struct lan966x *lan966x = port->lan966x;
1076d2c186aSHoratiu Vultur
1086d2c186aSHoratiu Vultur if (!(lan966x->bridge_mask & BIT(port->chip_port)))
1096d2c186aSHoratiu Vultur return HOST_PVID;
1106d2c186aSHoratiu Vultur
1116d2c186aSHoratiu Vultur return port->vlan_aware ? port->pvid : UNAWARE_PVID;
1126d2c186aSHoratiu Vultur }
1136d2c186aSHoratiu Vultur
lan966x_vlan_port_set_vid(struct lan966x_port * port,u16 vid,bool pvid,bool untagged)1146d2c186aSHoratiu Vultur int lan966x_vlan_port_set_vid(struct lan966x_port *port, u16 vid,
1156d2c186aSHoratiu Vultur bool pvid, bool untagged)
1166d2c186aSHoratiu Vultur {
1176d2c186aSHoratiu Vultur struct lan966x *lan966x = port->lan966x;
1186d2c186aSHoratiu Vultur
1196d2c186aSHoratiu Vultur /* Egress vlan classification */
1206d2c186aSHoratiu Vultur if (untagged && port->vid != vid) {
1216d2c186aSHoratiu Vultur if (port->vid) {
1226d2c186aSHoratiu Vultur dev_err(lan966x->dev,
1236d2c186aSHoratiu Vultur "Port already has a native VLAN: %d\n",
1246d2c186aSHoratiu Vultur port->vid);
1256d2c186aSHoratiu Vultur return -EBUSY;
1266d2c186aSHoratiu Vultur }
1276d2c186aSHoratiu Vultur port->vid = vid;
1286d2c186aSHoratiu Vultur }
1296d2c186aSHoratiu Vultur
1306d2c186aSHoratiu Vultur /* Default ingress vlan classification */
1316d2c186aSHoratiu Vultur if (pvid)
1326d2c186aSHoratiu Vultur port->pvid = vid;
1336d2c186aSHoratiu Vultur
1346d2c186aSHoratiu Vultur return 0;
1356d2c186aSHoratiu Vultur }
1366d2c186aSHoratiu Vultur
lan966x_vlan_port_remove_vid(struct lan966x_port * port,u16 vid)1376d2c186aSHoratiu Vultur static void lan966x_vlan_port_remove_vid(struct lan966x_port *port, u16 vid)
1386d2c186aSHoratiu Vultur {
1396d2c186aSHoratiu Vultur if (port->pvid == vid)
1406d2c186aSHoratiu Vultur port->pvid = 0;
1416d2c186aSHoratiu Vultur
1426d2c186aSHoratiu Vultur if (port->vid == vid)
1436d2c186aSHoratiu Vultur port->vid = 0;
1446d2c186aSHoratiu Vultur }
1456d2c186aSHoratiu Vultur
lan966x_vlan_port_set_vlan_aware(struct lan966x_port * port,bool vlan_aware)1466d2c186aSHoratiu Vultur void lan966x_vlan_port_set_vlan_aware(struct lan966x_port *port,
1476d2c186aSHoratiu Vultur bool vlan_aware)
1486d2c186aSHoratiu Vultur {
1496d2c186aSHoratiu Vultur port->vlan_aware = vlan_aware;
1506d2c186aSHoratiu Vultur }
1516d2c186aSHoratiu Vultur
lan966x_vlan_port_apply(struct lan966x_port * port)1526d2c186aSHoratiu Vultur void lan966x_vlan_port_apply(struct lan966x_port *port)
1536d2c186aSHoratiu Vultur {
1546d2c186aSHoratiu Vultur struct lan966x *lan966x = port->lan966x;
1556d2c186aSHoratiu Vultur u16 pvid;
1566d2c186aSHoratiu Vultur u32 val;
1576d2c186aSHoratiu Vultur
1586d2c186aSHoratiu Vultur pvid = lan966x_vlan_port_get_pvid(port);
1596d2c186aSHoratiu Vultur
1606d2c186aSHoratiu Vultur /* Ingress clasification (ANA_PORT_VLAN_CFG) */
1616d2c186aSHoratiu Vultur /* Default vlan to classify for untagged frames (may be zero) */
1626d2c186aSHoratiu Vultur val = ANA_VLAN_CFG_VLAN_VID_SET(pvid);
1636d2c186aSHoratiu Vultur if (port->vlan_aware)
1646d2c186aSHoratiu Vultur val |= ANA_VLAN_CFG_VLAN_AWARE_ENA_SET(1) |
1656d2c186aSHoratiu Vultur ANA_VLAN_CFG_VLAN_POP_CNT_SET(1);
1666d2c186aSHoratiu Vultur
1676d2c186aSHoratiu Vultur lan_rmw(val,
1686d2c186aSHoratiu Vultur ANA_VLAN_CFG_VLAN_VID | ANA_VLAN_CFG_VLAN_AWARE_ENA |
1696d2c186aSHoratiu Vultur ANA_VLAN_CFG_VLAN_POP_CNT,
1706d2c186aSHoratiu Vultur lan966x, ANA_VLAN_CFG(port->chip_port));
1716d2c186aSHoratiu Vultur
172*25f28bb1SHoratiu Vultur lan_rmw(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(port->vlan_aware) |
173*25f28bb1SHoratiu Vultur DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(port->vlan_aware),
174*25f28bb1SHoratiu Vultur DEV_MAC_TAGS_CFG_VLAN_AWR_ENA |
175*25f28bb1SHoratiu Vultur DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA,
176*25f28bb1SHoratiu Vultur lan966x, DEV_MAC_TAGS_CFG(port->chip_port));
177*25f28bb1SHoratiu Vultur
1786d2c186aSHoratiu Vultur /* Drop frames with multicast source address */
1796d2c186aSHoratiu Vultur val = ANA_DROP_CFG_DROP_MC_SMAC_ENA_SET(1);
1806d2c186aSHoratiu Vultur if (port->vlan_aware && !pvid)
1816d2c186aSHoratiu Vultur /* If port is vlan-aware and tagged, drop untagged and priority
1826d2c186aSHoratiu Vultur * tagged frames.
1836d2c186aSHoratiu Vultur */
1846d2c186aSHoratiu Vultur val |= ANA_DROP_CFG_DROP_UNTAGGED_ENA_SET(1) |
1856d2c186aSHoratiu Vultur ANA_DROP_CFG_DROP_PRIO_S_TAGGED_ENA_SET(1) |
1866d2c186aSHoratiu Vultur ANA_DROP_CFG_DROP_PRIO_C_TAGGED_ENA_SET(1);
1876d2c186aSHoratiu Vultur
1886d2c186aSHoratiu Vultur lan_wr(val, lan966x, ANA_DROP_CFG(port->chip_port));
1896d2c186aSHoratiu Vultur
1906d2c186aSHoratiu Vultur /* Egress configuration (REW_TAG_CFG): VLAN tag type to 8021Q */
1916d2c186aSHoratiu Vultur val = REW_TAG_CFG_TAG_TPID_CFG_SET(0);
1926d2c186aSHoratiu Vultur if (port->vlan_aware) {
1936d2c186aSHoratiu Vultur if (port->vid)
1946d2c186aSHoratiu Vultur /* Tag all frames except when VID == DEFAULT_VLAN */
1956d2c186aSHoratiu Vultur val |= REW_TAG_CFG_TAG_CFG_SET(1);
1966d2c186aSHoratiu Vultur else
1976d2c186aSHoratiu Vultur val |= REW_TAG_CFG_TAG_CFG_SET(3);
1986d2c186aSHoratiu Vultur }
1996d2c186aSHoratiu Vultur
2006d2c186aSHoratiu Vultur /* Update only some bits in the register */
2016d2c186aSHoratiu Vultur lan_rmw(val,
2026d2c186aSHoratiu Vultur REW_TAG_CFG_TAG_TPID_CFG | REW_TAG_CFG_TAG_CFG,
2036d2c186aSHoratiu Vultur lan966x, REW_TAG_CFG(port->chip_port));
2046d2c186aSHoratiu Vultur
2056d2c186aSHoratiu Vultur /* Set default VLAN and tag type to 8021Q */
2066d2c186aSHoratiu Vultur lan_rmw(REW_PORT_VLAN_CFG_PORT_TPID_SET(ETH_P_8021Q) |
2076d2c186aSHoratiu Vultur REW_PORT_VLAN_CFG_PORT_VID_SET(port->vid),
2086d2c186aSHoratiu Vultur REW_PORT_VLAN_CFG_PORT_TPID |
2096d2c186aSHoratiu Vultur REW_PORT_VLAN_CFG_PORT_VID,
2106d2c186aSHoratiu Vultur lan966x, REW_PORT_VLAN_CFG(port->chip_port));
2116d2c186aSHoratiu Vultur }
2126d2c186aSHoratiu Vultur
lan966x_vlan_port_add_vlan(struct lan966x_port * port,u16 vid,bool pvid,bool untagged)2136d2c186aSHoratiu Vultur void lan966x_vlan_port_add_vlan(struct lan966x_port *port,
2146d2c186aSHoratiu Vultur u16 vid,
2156d2c186aSHoratiu Vultur bool pvid,
2166d2c186aSHoratiu Vultur bool untagged)
2176d2c186aSHoratiu Vultur {
2186d2c186aSHoratiu Vultur struct lan966x *lan966x = port->lan966x;
2196d2c186aSHoratiu Vultur
220811ba277SHoratiu Vultur /* If the CPU(br) is already part of the vlan then add the fdb
221811ba277SHoratiu Vultur * entries in MAC table to copy the frames to the CPU(br).
222811ba277SHoratiu Vultur * If the CPU(br) is not part of the vlan then it would
223811ba277SHoratiu Vultur * just drop the frames.
224811ba277SHoratiu Vultur */
225811ba277SHoratiu Vultur if (lan966x_vlan_cpu_member_cpu_vlan_mask(lan966x, vid)) {
2266d2c186aSHoratiu Vultur lan966x_vlan_cpu_add_vlan_mask(lan966x, vid);
227811ba277SHoratiu Vultur lan966x_fdb_write_entries(lan966x, vid);
2287aacb894SHoratiu Vultur lan966x_mdb_write_entries(lan966x, vid);
229811ba277SHoratiu Vultur }
2306d2c186aSHoratiu Vultur
2316d2c186aSHoratiu Vultur lan966x_vlan_port_set_vid(port, vid, pvid, untagged);
2326d2c186aSHoratiu Vultur lan966x_vlan_port_add_vlan_mask(port, vid);
2336d2c186aSHoratiu Vultur lan966x_vlan_port_apply(port);
2346d2c186aSHoratiu Vultur }
2356d2c186aSHoratiu Vultur
lan966x_vlan_port_del_vlan(struct lan966x_port * port,u16 vid)2366d2c186aSHoratiu Vultur void lan966x_vlan_port_del_vlan(struct lan966x_port *port, u16 vid)
2376d2c186aSHoratiu Vultur {
2386d2c186aSHoratiu Vultur struct lan966x *lan966x = port->lan966x;
2396d2c186aSHoratiu Vultur
2406d2c186aSHoratiu Vultur lan966x_vlan_port_remove_vid(port, vid);
2416d2c186aSHoratiu Vultur lan966x_vlan_port_del_vlan_mask(port, vid);
2426d2c186aSHoratiu Vultur lan966x_vlan_port_apply(port);
2436d2c186aSHoratiu Vultur
2446d2c186aSHoratiu Vultur /* In case there are no other ports in vlan then remove the CPU from
2456d2c186aSHoratiu Vultur * that vlan but still keep it in the mask because it may be needed
2466d2c186aSHoratiu Vultur * again then another port gets added in that vlan
2476d2c186aSHoratiu Vultur */
248811ba277SHoratiu Vultur if (!lan966x_vlan_port_any_vlan_mask(lan966x, vid)) {
2496d2c186aSHoratiu Vultur lan966x_vlan_cpu_del_vlan_mask(lan966x, vid);
250811ba277SHoratiu Vultur lan966x_fdb_erase_entries(lan966x, vid);
2517aacb894SHoratiu Vultur lan966x_mdb_erase_entries(lan966x, vid);
252811ba277SHoratiu Vultur }
2536d2c186aSHoratiu Vultur }
2546d2c186aSHoratiu Vultur
lan966x_vlan_cpu_add_vlan(struct lan966x * lan966x,u16 vid)2556d2c186aSHoratiu Vultur void lan966x_vlan_cpu_add_vlan(struct lan966x *lan966x, u16 vid)
2566d2c186aSHoratiu Vultur {
2576d2c186aSHoratiu Vultur /* Add an entry in the MAC table for the CPU
2586d2c186aSHoratiu Vultur * Add the CPU part of the vlan only if there is another port in that
2596d2c186aSHoratiu Vultur * vlan otherwise all the broadcast frames in that vlan will go to CPU
2606d2c186aSHoratiu Vultur * even if none of the ports are in the vlan and then the CPU will just
2616d2c186aSHoratiu Vultur * need to discard these frames. It is required to store this
2626d2c186aSHoratiu Vultur * information so when a front port is added then it would add also the
2636d2c186aSHoratiu Vultur * CPU port.
2646d2c186aSHoratiu Vultur */
2657aacb894SHoratiu Vultur if (lan966x_vlan_port_any_vlan_mask(lan966x, vid)) {
2666d2c186aSHoratiu Vultur lan966x_vlan_cpu_add_vlan_mask(lan966x, vid);
2677aacb894SHoratiu Vultur lan966x_mdb_write_entries(lan966x, vid);
2687aacb894SHoratiu Vultur }
2696d2c186aSHoratiu Vultur
2706d2c186aSHoratiu Vultur lan966x_vlan_cpu_add_cpu_vlan_mask(lan966x, vid);
271811ba277SHoratiu Vultur lan966x_fdb_write_entries(lan966x, vid);
2726d2c186aSHoratiu Vultur }
2736d2c186aSHoratiu Vultur
lan966x_vlan_cpu_del_vlan(struct lan966x * lan966x,u16 vid)2746d2c186aSHoratiu Vultur void lan966x_vlan_cpu_del_vlan(struct lan966x *lan966x, u16 vid)
2756d2c186aSHoratiu Vultur {
2766d2c186aSHoratiu Vultur /* Remove the CPU part of the vlan */
2776d2c186aSHoratiu Vultur lan966x_vlan_cpu_del_cpu_vlan_mask(lan966x, vid);
2786d2c186aSHoratiu Vultur lan966x_vlan_cpu_del_vlan_mask(lan966x, vid);
279811ba277SHoratiu Vultur lan966x_fdb_erase_entries(lan966x, vid);
2807aacb894SHoratiu Vultur lan966x_mdb_erase_entries(lan966x, vid);
2816d2c186aSHoratiu Vultur }
2826d2c186aSHoratiu Vultur
lan966x_vlan_init(struct lan966x * lan966x)2836d2c186aSHoratiu Vultur void lan966x_vlan_init(struct lan966x *lan966x)
2846d2c186aSHoratiu Vultur {
2856d2c186aSHoratiu Vultur u16 port, vid;
2866d2c186aSHoratiu Vultur
2876d2c186aSHoratiu Vultur /* Clear VLAN table, by default all ports are members of all VLANS */
2886d2c186aSHoratiu Vultur lan_rmw(ANA_VLANACCESS_VLAN_TBL_CMD_SET(VLANACCESS_CMD_INIT),
2896d2c186aSHoratiu Vultur ANA_VLANACCESS_VLAN_TBL_CMD,
2906d2c186aSHoratiu Vultur lan966x, ANA_VLANACCESS);
2916d2c186aSHoratiu Vultur lan966x_vlan_wait_for_completion(lan966x);
2926d2c186aSHoratiu Vultur
2936d2c186aSHoratiu Vultur for (vid = 1; vid < VLAN_N_VID; vid++) {
2946d2c186aSHoratiu Vultur lan966x->vlan_mask[vid] = 0;
2956d2c186aSHoratiu Vultur lan966x_vlan_set_mask(lan966x, vid);
2966d2c186aSHoratiu Vultur }
2976d2c186aSHoratiu Vultur
2986d2c186aSHoratiu Vultur /* Set all the ports + cpu to be part of HOST_PVID and UNAWARE_PVID */
2996d2c186aSHoratiu Vultur lan966x->vlan_mask[HOST_PVID] =
3006d2c186aSHoratiu Vultur GENMASK(lan966x->num_phys_ports - 1, 0) | BIT(CPU_PORT);
3016d2c186aSHoratiu Vultur lan966x_vlan_set_mask(lan966x, HOST_PVID);
3026d2c186aSHoratiu Vultur
3036d2c186aSHoratiu Vultur lan966x->vlan_mask[UNAWARE_PVID] =
3046d2c186aSHoratiu Vultur GENMASK(lan966x->num_phys_ports - 1, 0) | BIT(CPU_PORT);
3056d2c186aSHoratiu Vultur lan966x_vlan_set_mask(lan966x, UNAWARE_PVID);
3066d2c186aSHoratiu Vultur
3076d2c186aSHoratiu Vultur lan966x_vlan_cpu_add_cpu_vlan_mask(lan966x, UNAWARE_PVID);
3086d2c186aSHoratiu Vultur
3096d2c186aSHoratiu Vultur /* Configure the CPU port to be vlan aware */
3106d2c186aSHoratiu Vultur lan_wr(ANA_VLAN_CFG_VLAN_VID_SET(0) |
3116d2c186aSHoratiu Vultur ANA_VLAN_CFG_VLAN_AWARE_ENA_SET(1) |
3126d2c186aSHoratiu Vultur ANA_VLAN_CFG_VLAN_POP_CNT_SET(1),
3136d2c186aSHoratiu Vultur lan966x, ANA_VLAN_CFG(CPU_PORT));
3146d2c186aSHoratiu Vultur
3156d2c186aSHoratiu Vultur /* Set vlan ingress filter mask to all ports */
3166d2c186aSHoratiu Vultur lan_wr(GENMASK(lan966x->num_phys_ports, 0),
3176d2c186aSHoratiu Vultur lan966x, ANA_VLANMASK);
3186d2c186aSHoratiu Vultur
3196d2c186aSHoratiu Vultur for (port = 0; port < lan966x->num_phys_ports; port++) {
3206d2c186aSHoratiu Vultur lan_wr(0, lan966x, REW_PORT_VLAN_CFG(port));
3216d2c186aSHoratiu Vultur lan_wr(0, lan966x, REW_TAG_CFG(port));
3226d2c186aSHoratiu Vultur }
3236d2c186aSHoratiu Vultur }
324