1187fbae0SWei Fang // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2187fbae0SWei Fang /* 3187fbae0SWei Fang * NXP NETC switch driver 4187fbae0SWei Fang * Copyright 2025-2026 NXP 5187fbae0SWei Fang */ 6187fbae0SWei Fang 746d64076SWei Fang #include <linux/clk.h> 8187fbae0SWei Fang #include <linux/etherdevice.h> 9187fbae0SWei Fang #include <linux/fsl/enetc_mdio.h> 1046d64076SWei Fang #include <linux/if_bridge.h> 11187fbae0SWei Fang #include <linux/if_vlan.h> 12187fbae0SWei Fang #include <linux/of_mdio.h> 13187fbae0SWei Fang 14187fbae0SWei Fang #include "netc_switch.h" 15187fbae0SWei Fang 1646d64076SWei Fang static struct netc_fdb_entry * 1746d64076SWei Fang netc_lookup_fdb_entry(struct netc_switch *priv, 1846d64076SWei Fang const unsigned char *addr, 1946d64076SWei Fang u16 vid) 2046d64076SWei Fang { 2146d64076SWei Fang struct netc_fdb_entry *entry; 2246d64076SWei Fang 2346d64076SWei Fang hlist_for_each_entry(entry, &priv->fdb_list, node) 2446d64076SWei Fang if (ether_addr_equal(entry->keye.mac_addr, addr) && 2546d64076SWei Fang le16_to_cpu(entry->keye.fid) == vid) 2646d64076SWei Fang return entry; 2746d64076SWei Fang 2846d64076SWei Fang return NULL; 2946d64076SWei Fang } 3046d64076SWei Fang 3146d64076SWei Fang static void netc_destroy_fdb_list(struct netc_switch *priv) 3246d64076SWei Fang { 3346d64076SWei Fang struct netc_fdb_entry *entry; 3446d64076SWei Fang struct hlist_node *tmp; 3546d64076SWei Fang 3646d64076SWei Fang hlist_for_each_entry_safe(entry, tmp, &priv->fdb_list, node) 3746d64076SWei Fang netc_del_fdb_entry(entry); 3846d64076SWei Fang } 3946d64076SWei Fang 4084b4a3b3SWei Fang static struct netc_vlan_entry * 4184b4a3b3SWei Fang netc_lookup_vlan_entry(struct netc_switch *priv, u16 vid) 4284b4a3b3SWei Fang { 4384b4a3b3SWei Fang struct netc_vlan_entry *entry; 4484b4a3b3SWei Fang 4584b4a3b3SWei Fang hlist_for_each_entry(entry, &priv->vlan_list, node) 4684b4a3b3SWei Fang if (entry->vid == vid) 4784b4a3b3SWei Fang return entry; 4884b4a3b3SWei Fang 4984b4a3b3SWei Fang return NULL; 5084b4a3b3SWei Fang } 5184b4a3b3SWei Fang 5284b4a3b3SWei Fang static void netc_destroy_vlan_list(struct netc_switch *priv) 5384b4a3b3SWei Fang { 5484b4a3b3SWei Fang struct netc_vlan_entry *entry; 5584b4a3b3SWei Fang struct hlist_node *tmp; 5684b4a3b3SWei Fang 5784b4a3b3SWei Fang hlist_for_each_entry_safe(entry, tmp, &priv->vlan_list, node) 5884b4a3b3SWei Fang netc_del_vlan_entry(entry); 5984b4a3b3SWei Fang } 6084b4a3b3SWei Fang 61187fbae0SWei Fang static enum dsa_tag_protocol 62187fbae0SWei Fang netc_get_tag_protocol(struct dsa_switch *ds, int port, 63187fbae0SWei Fang enum dsa_tag_protocol mprot) 64187fbae0SWei Fang { 65187fbae0SWei Fang return DSA_TAG_PROTO_NETC; 66187fbae0SWei Fang } 67187fbae0SWei Fang 68187fbae0SWei Fang static void netc_port_rmw(struct netc_port *np, u32 reg, 69187fbae0SWei Fang u32 mask, u32 val) 70187fbae0SWei Fang { 71187fbae0SWei Fang u32 old, new; 72187fbae0SWei Fang 73187fbae0SWei Fang WARN_ON((mask | val) != mask); 74187fbae0SWei Fang 75187fbae0SWei Fang old = netc_port_rd(np, reg); 76187fbae0SWei Fang new = (old & ~mask) | val; 77187fbae0SWei Fang if (new == old) 78187fbae0SWei Fang return; 79187fbae0SWei Fang 80187fbae0SWei Fang netc_port_wr(np, reg, new); 81187fbae0SWei Fang } 82187fbae0SWei Fang 83187fbae0SWei Fang static void netc_mac_port_wr(struct netc_port *np, u32 reg, u32 val) 84187fbae0SWei Fang { 85187fbae0SWei Fang if (is_netc_pseudo_port(np)) 86187fbae0SWei Fang return; 87187fbae0SWei Fang 88187fbae0SWei Fang netc_port_wr(np, reg, val); 89187fbae0SWei Fang if (np->caps.pmac) 90187fbae0SWei Fang netc_port_wr(np, reg + NETC_PMAC_OFFSET, val); 91187fbae0SWei Fang } 92187fbae0SWei Fang 93bbe97e34SWei Fang /* netc_mac_port_rmw() is used to synchronize the configurations of eMAC 94bbe97e34SWei Fang * and pMAC to maintain consistency. This function should not be used if 95bbe97e34SWei Fang * differentiated settings are required. 96bbe97e34SWei Fang */ 97bbe97e34SWei Fang static void netc_mac_port_rmw(struct netc_port *np, u32 reg, 98bbe97e34SWei Fang u32 mask, u32 val) 99bbe97e34SWei Fang { 100bbe97e34SWei Fang u32 old, new; 101bbe97e34SWei Fang 102bbe97e34SWei Fang if (is_netc_pseudo_port(np)) 103bbe97e34SWei Fang return; 104bbe97e34SWei Fang 105bbe97e34SWei Fang WARN_ON((mask | val) != mask); 106bbe97e34SWei Fang 107bbe97e34SWei Fang old = netc_port_rd(np, reg); 108bbe97e34SWei Fang new = (old & ~mask) | val; 109bbe97e34SWei Fang if (new == old) 110bbe97e34SWei Fang return; 111bbe97e34SWei Fang 112bbe97e34SWei Fang netc_port_wr(np, reg, new); 113bbe97e34SWei Fang if (np->caps.pmac) 114bbe97e34SWei Fang netc_port_wr(np, reg + NETC_PMAC_OFFSET, new); 115bbe97e34SWei Fang } 116bbe97e34SWei Fang 117187fbae0SWei Fang static void netc_port_get_capability(struct netc_port *np) 118187fbae0SWei Fang { 119187fbae0SWei Fang u32 val; 120187fbae0SWei Fang 121187fbae0SWei Fang val = netc_port_rd(np, NETC_PMCAPR); 122187fbae0SWei Fang if (val & PMCAPR_HD) 123187fbae0SWei Fang np->caps.half_duplex = true; 124187fbae0SWei Fang 125187fbae0SWei Fang if (FIELD_GET(PMCAPR_FP, val) == FP_SUPPORT) 126187fbae0SWei Fang np->caps.pmac = true; 127187fbae0SWei Fang 128187fbae0SWei Fang val = netc_port_rd(np, NETC_PCAPR); 129187fbae0SWei Fang if (val & PCAPR_LINK_TYPE) 130187fbae0SWei Fang np->caps.pseudo_link = true; 131187fbae0SWei Fang } 132187fbae0SWei Fang 13346d64076SWei Fang static int netc_port_get_info_from_dt(struct netc_port *np, 13446d64076SWei Fang struct device_node *node, 13546d64076SWei Fang struct device *dev) 13646d64076SWei Fang { 13746d64076SWei Fang if (of_find_property(node, "clock-names", NULL)) { 13846d64076SWei Fang np->ref_clk = devm_get_clk_from_child(dev, node, "ref"); 13946d64076SWei Fang if (IS_ERR(np->ref_clk)) { 14046d64076SWei Fang dev_err(dev, "Port %d cannot get reference clock\n", 14146d64076SWei Fang np->dp->index); 14246d64076SWei Fang return PTR_ERR(np->ref_clk); 14346d64076SWei Fang } 14446d64076SWei Fang } 14546d64076SWei Fang 14646d64076SWei Fang return 0; 14746d64076SWei Fang } 14846d64076SWei Fang 149187fbae0SWei Fang static int netc_port_create_emdio_bus(struct netc_port *np, 150187fbae0SWei Fang struct device_node *node) 151187fbae0SWei Fang { 152187fbae0SWei Fang struct netc_switch *priv = np->switch_priv; 153187fbae0SWei Fang struct enetc_mdio_priv *mdio_priv; 154187fbae0SWei Fang struct device *dev = priv->dev; 155187fbae0SWei Fang struct enetc_hw *hw; 156187fbae0SWei Fang struct mii_bus *bus; 157187fbae0SWei Fang int err; 158187fbae0SWei Fang 159187fbae0SWei Fang hw = enetc_hw_alloc(dev, np->iobase); 160187fbae0SWei Fang if (IS_ERR(hw)) 161187fbae0SWei Fang return dev_err_probe(dev, PTR_ERR(hw), 162187fbae0SWei Fang "Failed to allocate enetc_hw\n"); 163187fbae0SWei Fang 164187fbae0SWei Fang bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); 165187fbae0SWei Fang if (!bus) 166187fbae0SWei Fang return -ENOMEM; 167187fbae0SWei Fang 168187fbae0SWei Fang bus->name = "NXP NETC switch external MDIO Bus"; 169187fbae0SWei Fang bus->read = enetc_mdio_read_c22; 170187fbae0SWei Fang bus->write = enetc_mdio_write_c22; 171187fbae0SWei Fang bus->read_c45 = enetc_mdio_read_c45; 172187fbae0SWei Fang bus->write_c45 = enetc_mdio_write_c45; 173187fbae0SWei Fang bus->parent = dev; 174187fbae0SWei Fang mdio_priv = bus->priv; 175187fbae0SWei Fang mdio_priv->hw = hw; 176187fbae0SWei Fang mdio_priv->mdio_base = NETC_EMDIO_BASE; 177187fbae0SWei Fang snprintf(bus->id, MII_BUS_ID_SIZE, "%s-p%d-emdio", 178187fbae0SWei Fang dev_name(dev), np->dp->index); 179187fbae0SWei Fang 180187fbae0SWei Fang err = devm_of_mdiobus_register(dev, bus, node); 181187fbae0SWei Fang if (err) 182187fbae0SWei Fang return dev_err_probe(dev, err, 183187fbae0SWei Fang "Cannot register EMDIO bus\n"); 184187fbae0SWei Fang 185187fbae0SWei Fang np->emdio = bus; 186187fbae0SWei Fang 187187fbae0SWei Fang return 0; 188187fbae0SWei Fang } 189187fbae0SWei Fang 190187fbae0SWei Fang static int netc_port_create_mdio_bus(struct netc_port *np, 191187fbae0SWei Fang struct device_node *node) 192187fbae0SWei Fang { 193187fbae0SWei Fang struct device_node *mdio_node; 194187fbae0SWei Fang int err; 195187fbae0SWei Fang 196187fbae0SWei Fang mdio_node = of_get_child_by_name(node, "mdio"); 197187fbae0SWei Fang if (mdio_node) { 198187fbae0SWei Fang err = netc_port_create_emdio_bus(np, mdio_node); 199187fbae0SWei Fang of_node_put(mdio_node); 200187fbae0SWei Fang if (err) 201187fbae0SWei Fang return err; 202187fbae0SWei Fang } 203187fbae0SWei Fang 204187fbae0SWei Fang return 0; 205187fbae0SWei Fang } 206187fbae0SWei Fang 207187fbae0SWei Fang static int netc_init_switch_id(struct netc_switch *priv) 208187fbae0SWei Fang { 209187fbae0SWei Fang struct netc_switch_regs *regs = &priv->regs; 210187fbae0SWei Fang struct dsa_switch *ds = priv->ds; 211187fbae0SWei Fang 212187fbae0SWei Fang /* The value of 0 is reserved for the VEPA switch and cannot 213187fbae0SWei Fang * be used. So 'dsa,member' is a required property for NETC 214187fbae0SWei Fang * switch, the member is used to specify the switch ID, which 215187fbae0SWei Fang * cannot be zero. This way, the hardware switch ID and the 216187fbae0SWei Fang * software switch ID are consistent. 217187fbae0SWei Fang */ 218187fbae0SWei Fang if (ds->index > FIELD_MAX(SWCR_SWID) || !ds->index) { 219187fbae0SWei Fang dev_err(priv->dev, "Switch index %d out of range\n", 220187fbae0SWei Fang ds->index); 221187fbae0SWei Fang return -ERANGE; 222187fbae0SWei Fang } 223187fbae0SWei Fang 224187fbae0SWei Fang netc_base_wr(regs, NETC_SWCR, ds->index); 225187fbae0SWei Fang 226187fbae0SWei Fang return 0; 227187fbae0SWei Fang } 228187fbae0SWei Fang 22946d64076SWei Fang static void netc_get_switch_capabilities(struct netc_switch *priv) 23046d64076SWei Fang { 23146d64076SWei Fang struct netc_switch_regs *regs = &priv->regs; 23246d64076SWei Fang u32 val; 23346d64076SWei Fang 23446d64076SWei Fang val = netc_base_rd(regs, NETC_HTMCAPR); 23546d64076SWei Fang priv->htmcapr_num_words = FIELD_GET(HTMCAPR_NUM_WORDS, val); 236a5ccb7f5SWei Fang 237a5ccb7f5SWei Fang val = netc_base_rd(regs, NETC_BPCAPR); 238a5ccb7f5SWei Fang priv->num_bp = FIELD_GET(BPCAPR_NUM_BP, val); 23946d64076SWei Fang } 24046d64076SWei Fang 241187fbae0SWei Fang static int netc_init_all_ports(struct netc_switch *priv) 242187fbae0SWei Fang { 243187fbae0SWei Fang struct device *dev = priv->dev; 244187fbae0SWei Fang struct netc_port *np; 245187fbae0SWei Fang struct dsa_port *dp; 24684b4a3b3SWei Fang int ett_offset = 0; 247187fbae0SWei Fang int err; 248187fbae0SWei Fang 249187fbae0SWei Fang priv->ports = devm_kcalloc(dev, priv->info->num_ports, 250187fbae0SWei Fang sizeof(struct netc_port *), 251187fbae0SWei Fang GFP_KERNEL); 252187fbae0SWei Fang if (!priv->ports) 253187fbae0SWei Fang return -ENOMEM; 254187fbae0SWei Fang 255187fbae0SWei Fang /* Some DSA interfaces may set the port even it is disabled, such 256187fbae0SWei Fang * as .port_disable(), .port_stp_state_set() and so on. To avoid 257187fbae0SWei Fang * crash caused by accessing NULL port pointer, each port is 258187fbae0SWei Fang * allocated its own memory. Otherwise, we need to check whether 259187fbae0SWei Fang * the port pointer is NULL in these interfaces. The latter is 260187fbae0SWei Fang * difficult for us to cover. 261187fbae0SWei Fang */ 262187fbae0SWei Fang for (int i = 0; i < priv->info->num_ports; i++) { 263187fbae0SWei Fang np = devm_kzalloc(dev, sizeof(*np), GFP_KERNEL); 264187fbae0SWei Fang if (!np) 265187fbae0SWei Fang return -ENOMEM; 266187fbae0SWei Fang 267187fbae0SWei Fang np->switch_priv = priv; 268187fbae0SWei Fang np->iobase = priv->regs.port + PORT_IOBASE(i); 269187fbae0SWei Fang netc_port_get_capability(np); 270187fbae0SWei Fang priv->ports[i] = np; 271187fbae0SWei Fang } 272187fbae0SWei Fang 273187fbae0SWei Fang dsa_switch_for_each_available_port(dp, priv->ds) { 274187fbae0SWei Fang np = priv->ports[dp->index]; 275187fbae0SWei Fang np->dp = dp; 27684b4a3b3SWei Fang np->ett_offset = ett_offset++; 27784b4a3b3SWei Fang priv->port_bitmap |= BIT(dp->index); 278187fbae0SWei Fang 27946d64076SWei Fang err = netc_port_get_info_from_dt(np, dp->dn, dev); 28046d64076SWei Fang if (err) 28146d64076SWei Fang return err; 28246d64076SWei Fang 283187fbae0SWei Fang if (dsa_port_is_user(dp)) { 284187fbae0SWei Fang err = netc_port_create_mdio_bus(np, dp->dn); 285187fbae0SWei Fang if (err) { 286187fbae0SWei Fang dev_err(dev, "Failed to create MDIO bus\n"); 287187fbae0SWei Fang return err; 288187fbae0SWei Fang } 289187fbae0SWei Fang } 290187fbae0SWei Fang } 291187fbae0SWei Fang 292187fbae0SWei Fang return 0; 293187fbae0SWei Fang } 294187fbae0SWei Fang 295187fbae0SWei Fang static void netc_init_ntmp_tbl_versions(struct netc_switch *priv) 296187fbae0SWei Fang { 297187fbae0SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 298187fbae0SWei Fang 299187fbae0SWei Fang /* All tables default to version 0 */ 300187fbae0SWei Fang memset(&ntmp->tbl, 0, sizeof(ntmp->tbl)); 301187fbae0SWei Fang } 302187fbae0SWei Fang 303187fbae0SWei Fang static int netc_init_all_cbdrs(struct netc_switch *priv) 304187fbae0SWei Fang { 305187fbae0SWei Fang struct netc_switch_regs *regs = &priv->regs; 306187fbae0SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 307187fbae0SWei Fang int i, err; 308187fbae0SWei Fang 309187fbae0SWei Fang ntmp->cbdr_num = NETC_CBDR_NUM; 310187fbae0SWei Fang ntmp->dev = priv->dev; 311187fbae0SWei Fang ntmp->ring = devm_kcalloc(ntmp->dev, ntmp->cbdr_num, 312187fbae0SWei Fang sizeof(struct netc_cbdr), 313187fbae0SWei Fang GFP_KERNEL); 314187fbae0SWei Fang if (!ntmp->ring) 315187fbae0SWei Fang return -ENOMEM; 316187fbae0SWei Fang 317187fbae0SWei Fang for (i = 0; i < ntmp->cbdr_num; i++) { 318187fbae0SWei Fang struct netc_cbdr *cbdr = &ntmp->ring[i]; 319187fbae0SWei Fang struct netc_cbdr_regs cbdr_regs; 320187fbae0SWei Fang 321187fbae0SWei Fang cbdr_regs.pir = regs->base + NETC_CBDRPIR(i); 322187fbae0SWei Fang cbdr_regs.cir = regs->base + NETC_CBDRCIR(i); 323187fbae0SWei Fang cbdr_regs.mr = regs->base + NETC_CBDRMR(i); 324187fbae0SWei Fang cbdr_regs.bar0 = regs->base + NETC_CBDRBAR0(i); 325187fbae0SWei Fang cbdr_regs.bar1 = regs->base + NETC_CBDRBAR1(i); 326187fbae0SWei Fang cbdr_regs.lenr = regs->base + NETC_CBDRLENR(i); 327187fbae0SWei Fang 328187fbae0SWei Fang err = ntmp_init_cbdr(cbdr, ntmp->dev, &cbdr_regs); 329187fbae0SWei Fang if (err) 330187fbae0SWei Fang goto free_cbdrs; 331187fbae0SWei Fang } 332187fbae0SWei Fang 333187fbae0SWei Fang return 0; 334187fbae0SWei Fang 335187fbae0SWei Fang free_cbdrs: 336187fbae0SWei Fang for (i--; i >= 0; i--) 337187fbae0SWei Fang ntmp_free_cbdr(&ntmp->ring[i]); 338187fbae0SWei Fang 339187fbae0SWei Fang return err; 340187fbae0SWei Fang } 341187fbae0SWei Fang 342187fbae0SWei Fang static void netc_remove_all_cbdrs(struct netc_switch *priv) 343187fbae0SWei Fang { 344187fbae0SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 345187fbae0SWei Fang 346187fbae0SWei Fang for (int i = 0; i < NETC_CBDR_NUM; i++) 347187fbae0SWei Fang ntmp_free_cbdr(&ntmp->ring[i]); 348187fbae0SWei Fang } 349187fbae0SWei Fang 3501a58ae73SWei Fang static u32 netc_num_available_ports(struct netc_switch *priv) 3511a58ae73SWei Fang { 3521a58ae73SWei Fang struct dsa_port *dp; 3531a58ae73SWei Fang u32 num_ports = 0; 3541a58ae73SWei Fang 3551a58ae73SWei Fang dsa_switch_for_each_available_port(dp, priv->ds) 3561a58ae73SWei Fang num_ports++; 3571a58ae73SWei Fang 3581a58ae73SWei Fang return num_ports; 3591a58ae73SWei Fang } 3601a58ae73SWei Fang 3611a58ae73SWei Fang static int netc_init_ntmp_bitmap_sizes(struct netc_switch *priv) 3621a58ae73SWei Fang { 3631a58ae73SWei Fang u32 num_ports = netc_num_available_ports(priv); 3641a58ae73SWei Fang struct netc_switch_regs *regs = &priv->regs; 3651a58ae73SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 3661a58ae73SWei Fang u32 val; 3671a58ae73SWei Fang 3681a58ae73SWei Fang if (!num_ports) 3691a58ae73SWei Fang return -EINVAL; 3701a58ae73SWei Fang 3711a58ae73SWei Fang val = netc_base_rd(regs, NETC_ETTCAPR); 3721a58ae73SWei Fang ntmp->ett_bitmap_size = NETC_GET_NUM_ENTRIES(val) / num_ports; 3731a58ae73SWei Fang if (!ntmp->ett_bitmap_size) 3741a58ae73SWei Fang return -EINVAL; 3751a58ae73SWei Fang 3761a58ae73SWei Fang val = netc_base_rd(regs, NETC_ECTCAPR); 3771a58ae73SWei Fang ntmp->ect_bitmap_size = NETC_GET_NUM_ENTRIES(val) / num_ports; 3781a58ae73SWei Fang if (!ntmp->ect_bitmap_size) 3791a58ae73SWei Fang return -EINVAL; 3801a58ae73SWei Fang 3811a58ae73SWei Fang return 0; 3821a58ae73SWei Fang } 3831a58ae73SWei Fang 3841a58ae73SWei Fang static int netc_init_ntmp_bitmaps(struct netc_switch *priv) 3851a58ae73SWei Fang { 3861a58ae73SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 3871a58ae73SWei Fang 3881a58ae73SWei Fang ntmp->ett_gid_bitmap = bitmap_zalloc(ntmp->ett_bitmap_size, 3891a58ae73SWei Fang GFP_KERNEL); 3901a58ae73SWei Fang if (!ntmp->ett_gid_bitmap) 3911a58ae73SWei Fang return -ENOMEM; 3921a58ae73SWei Fang 3931a58ae73SWei Fang ntmp->ect_gid_bitmap = bitmap_zalloc(ntmp->ect_bitmap_size, 3941a58ae73SWei Fang GFP_KERNEL); 3951a58ae73SWei Fang if (!ntmp->ect_gid_bitmap) 3961a58ae73SWei Fang goto free_ett_gid_bitmap; 3971a58ae73SWei Fang 3981a58ae73SWei Fang return 0; 3991a58ae73SWei Fang 4001a58ae73SWei Fang free_ett_gid_bitmap: 4011a58ae73SWei Fang bitmap_free(ntmp->ett_gid_bitmap); 4021a58ae73SWei Fang ntmp->ett_gid_bitmap = NULL; 4031a58ae73SWei Fang 4041a58ae73SWei Fang return -ENOMEM; 4051a58ae73SWei Fang } 4061a58ae73SWei Fang 4071a58ae73SWei Fang static void netc_free_ntmp_bitmaps(struct netc_switch *priv) 4081a58ae73SWei Fang { 4091a58ae73SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 4101a58ae73SWei Fang 4111a58ae73SWei Fang bitmap_free(ntmp->ect_gid_bitmap); 4121a58ae73SWei Fang ntmp->ect_gid_bitmap = NULL; 4131a58ae73SWei Fang 4141a58ae73SWei Fang bitmap_free(ntmp->ett_gid_bitmap); 4151a58ae73SWei Fang ntmp->ett_gid_bitmap = NULL; 4161a58ae73SWei Fang } 4171a58ae73SWei Fang 418187fbae0SWei Fang static int netc_init_ntmp_user(struct netc_switch *priv) 419187fbae0SWei Fang { 4201a58ae73SWei Fang int err; 4211a58ae73SWei Fang 422187fbae0SWei Fang netc_init_ntmp_tbl_versions(priv); 423187fbae0SWei Fang 4241a58ae73SWei Fang err = netc_init_ntmp_bitmap_sizes(priv); 4251a58ae73SWei Fang if (err) 4261a58ae73SWei Fang return err; 4271a58ae73SWei Fang 4281a58ae73SWei Fang err = netc_init_ntmp_bitmaps(priv); 4291a58ae73SWei Fang if (err) 4301a58ae73SWei Fang return err; 4311a58ae73SWei Fang 4321a58ae73SWei Fang err = netc_init_all_cbdrs(priv); 4331a58ae73SWei Fang if (err) 4341a58ae73SWei Fang goto free_ntmp_bitmaps; 4351a58ae73SWei Fang 4361a58ae73SWei Fang return 0; 4371a58ae73SWei Fang 4381a58ae73SWei Fang free_ntmp_bitmaps: 4391a58ae73SWei Fang netc_free_ntmp_bitmaps(priv); 4401a58ae73SWei Fang 4411a58ae73SWei Fang return err; 442187fbae0SWei Fang } 443187fbae0SWei Fang 444187fbae0SWei Fang static void netc_free_ntmp_user(struct netc_switch *priv) 445187fbae0SWei Fang { 446187fbae0SWei Fang netc_remove_all_cbdrs(priv); 4471a58ae73SWei Fang netc_free_ntmp_bitmaps(priv); 448187fbae0SWei Fang } 449187fbae0SWei Fang 450*05b5ee61SWei Fang static void netc_clean_fdbt_ageing_entries(struct work_struct *work) 451*05b5ee61SWei Fang { 452*05b5ee61SWei Fang struct delayed_work *dwork = to_delayed_work(work); 453*05b5ee61SWei Fang struct netc_switch *priv; 454*05b5ee61SWei Fang 455*05b5ee61SWei Fang priv = container_of(dwork, struct netc_switch, fdbt_ageing_work); 456*05b5ee61SWei Fang 457*05b5ee61SWei Fang /* Update the activity element in FDB table */ 458*05b5ee61SWei Fang mutex_lock(&priv->fdbt_lock); 459*05b5ee61SWei Fang ntmp_fdbt_update_activity_element(&priv->ntmp); 460*05b5ee61SWei Fang /* Delete the ageing entries after the activity element is updated */ 461*05b5ee61SWei Fang ntmp_fdbt_delete_ageing_entries(&priv->ntmp, NETC_FDBT_AGEING_THRESH); 462*05b5ee61SWei Fang mutex_unlock(&priv->fdbt_lock); 463*05b5ee61SWei Fang 464*05b5ee61SWei Fang if (atomic_read(&priv->br_cnt)) 465*05b5ee61SWei Fang schedule_delayed_work(&priv->fdbt_ageing_work, 466*05b5ee61SWei Fang READ_ONCE(priv->fdbt_ageing_delay)); 467*05b5ee61SWei Fang } 468*05b5ee61SWei Fang 469187fbae0SWei Fang static void netc_switch_dos_default_config(struct netc_switch *priv) 470187fbae0SWei Fang { 471187fbae0SWei Fang struct netc_switch_regs *regs = &priv->regs; 472187fbae0SWei Fang u32 val; 473187fbae0SWei Fang 474187fbae0SWei Fang val = DOSL2CR_SAMEADDR | DOSL2CR_MSAMCC; 475187fbae0SWei Fang netc_base_wr(regs, NETC_DOSL2CR, val); 476187fbae0SWei Fang 477187fbae0SWei Fang val = DOSL3CR_SAMEADDR | DOSL3CR_IPSAMCC; 478187fbae0SWei Fang netc_base_wr(regs, NETC_DOSL3CR, val); 479187fbae0SWei Fang } 480187fbae0SWei Fang 481187fbae0SWei Fang static void netc_switch_vfht_default_config(struct netc_switch *priv) 482187fbae0SWei Fang { 483187fbae0SWei Fang struct netc_switch_regs *regs = &priv->regs; 484187fbae0SWei Fang u32 val; 485187fbae0SWei Fang 486187fbae0SWei Fang val = netc_base_rd(regs, NETC_VFHTDECR2); 487187fbae0SWei Fang 488187fbae0SWei Fang /* If no match is found in the VLAN Filter table, then VFHTDECR2[MLO] 489187fbae0SWei Fang * will take effect. VFHTDECR2[MLO] is set to "Software MAC learning 490187fbae0SWei Fang * secure" by default. Notice BPCR[MLO] will override VFHTDECR2[MLO] 491187fbae0SWei Fang * if its value is not zero. 492187fbae0SWei Fang */ 493187fbae0SWei Fang val = u32_replace_bits(val, MLO_SW_SEC, VFHTDECR2_MLO); 494187fbae0SWei Fang val = u32_replace_bits(val, MFO_NO_MATCH_DISCARD, VFHTDECR2_MFO); 495187fbae0SWei Fang netc_base_wr(regs, NETC_VFHTDECR2, val); 496187fbae0SWei Fang } 497187fbae0SWei Fang 498187fbae0SWei Fang static void netc_port_set_max_frame_size(struct netc_port *np, 499187fbae0SWei Fang u32 max_frame_size) 500187fbae0SWei Fang { 501187fbae0SWei Fang netc_mac_port_wr(np, NETC_PM_MAXFRM(0), 502187fbae0SWei Fang max_frame_size & PM_MAXFRAM); 503187fbae0SWei Fang } 504187fbae0SWei Fang 505187fbae0SWei Fang static void netc_switch_fixed_config(struct netc_switch *priv) 506187fbae0SWei Fang { 507187fbae0SWei Fang netc_switch_dos_default_config(priv); 508187fbae0SWei Fang netc_switch_vfht_default_config(priv); 509187fbae0SWei Fang } 510187fbae0SWei Fang 511187fbae0SWei Fang static void netc_port_set_tc_max_sdu(struct netc_port *np, 512187fbae0SWei Fang int tc, u32 max_sdu) 513187fbae0SWei Fang { 514187fbae0SWei Fang u32 val = FIELD_PREP(PTCTMSDUR_MAXSDU, max_sdu) | 515187fbae0SWei Fang FIELD_PREP(PTCTMSDUR_SDU_TYPE, SDU_TYPE_MPDU); 516187fbae0SWei Fang 517187fbae0SWei Fang netc_port_wr(np, NETC_PTCTMSDUR(tc), val); 518187fbae0SWei Fang } 519187fbae0SWei Fang 520187fbae0SWei Fang static void netc_port_set_all_tc_msdu(struct netc_port *np) 521187fbae0SWei Fang { 522187fbae0SWei Fang for (int tc = 0; tc < NETC_TC_NUM; tc++) 523187fbae0SWei Fang netc_port_set_tc_max_sdu(np, tc, NETC_MAX_FRAME_LEN); 524187fbae0SWei Fang } 525187fbae0SWei Fang 526187fbae0SWei Fang static void netc_port_set_mlo(struct netc_port *np, enum netc_mlo mlo) 527187fbae0SWei Fang { 528187fbae0SWei Fang netc_port_rmw(np, NETC_BPCR, BPCR_MLO, FIELD_PREP(BPCR_MLO, mlo)); 529187fbae0SWei Fang } 530187fbae0SWei Fang 531751aa5a5SWei Fang static void netc_port_set_pvid(struct netc_port *np, u16 pvid) 532751aa5a5SWei Fang { 533751aa5a5SWei Fang netc_port_rmw(np, NETC_BPDVR, BPDVR_VID, pvid); 534751aa5a5SWei Fang } 535751aa5a5SWei Fang 536751aa5a5SWei Fang static void netc_port_set_vlan_aware(struct netc_port *np, bool aware) 537751aa5a5SWei Fang { 538751aa5a5SWei Fang netc_port_rmw(np, NETC_BPDVR, BPDVR_RXVAM, 539751aa5a5SWei Fang aware ? 0 : BPDVR_RXVAM); 540751aa5a5SWei Fang } 541751aa5a5SWei Fang 542187fbae0SWei Fang static void netc_port_fixed_config(struct netc_port *np) 543187fbae0SWei Fang { 544187fbae0SWei Fang /* Default IPV and DR setting */ 545187fbae0SWei Fang netc_port_rmw(np, NETC_PQOSMR, PQOSMR_VS | PQOSMR_VE, 546187fbae0SWei Fang PQOSMR_VS | PQOSMR_VE); 547187fbae0SWei Fang 548187fbae0SWei Fang /* Enable L2 and L3 DOS */ 549187fbae0SWei Fang netc_port_rmw(np, NETC_PCR, PCR_L2DOSE | PCR_L3DOSE, 550187fbae0SWei Fang PCR_L2DOSE | PCR_L3DOSE); 551a5ccb7f5SWei Fang 552a5ccb7f5SWei Fang /* Set the quanta value of TX PAUSE frame */ 553a5ccb7f5SWei Fang netc_mac_port_wr(np, NETC_PM_PAUSE_QUANTA(0), NETC_PAUSE_QUANTA); 554a5ccb7f5SWei Fang 555a5ccb7f5SWei Fang /* When a quanta timer counts down and reaches this value, 556a5ccb7f5SWei Fang * the MAC sends a refresh PAUSE frame with the programmed 557a5ccb7f5SWei Fang * full quanta value if a pause condition still exists. 558a5ccb7f5SWei Fang */ 559a5ccb7f5SWei Fang netc_mac_port_wr(np, NETC_PM_PAUSE_THRESH(0), NETC_PAUSE_THRESH); 560187fbae0SWei Fang } 561187fbae0SWei Fang 562187fbae0SWei Fang static void netc_port_default_config(struct netc_port *np) 563187fbae0SWei Fang { 564187fbae0SWei Fang netc_port_fixed_config(np); 565187fbae0SWei Fang 566187fbae0SWei Fang /* Default VLAN unaware */ 567751aa5a5SWei Fang netc_port_set_vlan_aware(np, false); 568187fbae0SWei Fang 569187fbae0SWei Fang if (dsa_port_is_cpu(np->dp)) 570187fbae0SWei Fang /* For CPU port, source port pruning is disabled */ 571187fbae0SWei Fang netc_port_rmw(np, NETC_BPCR, BPCR_SRCPRND, BPCR_SRCPRND); 572187fbae0SWei Fang else 573187fbae0SWei Fang netc_port_set_mlo(np, MLO_DISABLE); 574187fbae0SWei Fang 575187fbae0SWei Fang netc_port_set_max_frame_size(np, NETC_MAX_FRAME_LEN); 576187fbae0SWei Fang netc_port_set_all_tc_msdu(np); 577187fbae0SWei Fang } 578187fbae0SWei Fang 57946d64076SWei Fang static u32 netc_available_port_bitmap(struct netc_switch *priv) 58046d64076SWei Fang { 58146d64076SWei Fang struct dsa_port *dp; 58246d64076SWei Fang u32 bitmap = 0; 58346d64076SWei Fang 58446d64076SWei Fang dsa_switch_for_each_available_port(dp, priv->ds) 58546d64076SWei Fang bitmap |= BIT(dp->index); 58646d64076SWei Fang 58746d64076SWei Fang return bitmap; 58846d64076SWei Fang } 58946d64076SWei Fang 59046d64076SWei Fang static int netc_add_standalone_vlan_entry(struct netc_switch *priv) 59146d64076SWei Fang { 59246d64076SWei Fang u32 bitmap_stg = VFT_STG_ID(0) | netc_available_port_bitmap(priv); 59346d64076SWei Fang struct vft_cfge_data *cfge; 59446d64076SWei Fang u16 cfg; 59546d64076SWei Fang int err; 59646d64076SWei Fang 59746d64076SWei Fang cfge = kzalloc_obj(*cfge); 59846d64076SWei Fang if (!cfge) 59946d64076SWei Fang return -ENOMEM; 60046d64076SWei Fang 60146d64076SWei Fang cfge->bitmap_stg = cpu_to_le32(bitmap_stg); 60246d64076SWei Fang cfge->et_eid = cpu_to_le32(NTMP_NULL_ENTRY_ID); 60346d64076SWei Fang cfge->fid = cpu_to_le16(NETC_STANDALONE_PVID); 60446d64076SWei Fang 60546d64076SWei Fang /* For standalone ports, MAC learning needs to be disabled, so frames 60646d64076SWei Fang * from other user ports will not be forwarded to the standalone ports, 60746d64076SWei Fang * because there are no FDB entries on the standalone ports. Also, the 60846d64076SWei Fang * frames received by the standalone ports cannot be flooded to other 60946d64076SWei Fang * ports, so MAC forwarding option needs to be set to 61046d64076SWei Fang * MFO_NO_MATCH_DISCARD, so the frames will be discarded rather than 61146d64076SWei Fang * flooding to other ports. 61246d64076SWei Fang */ 61346d64076SWei Fang cfg = FIELD_PREP(VFT_MLO, MLO_DISABLE) | 61446d64076SWei Fang FIELD_PREP(VFT_MFO, MFO_NO_MATCH_DISCARD); 61546d64076SWei Fang cfge->cfg = cpu_to_le16(cfg); 61646d64076SWei Fang 61746d64076SWei Fang err = ntmp_vft_add_entry(&priv->ntmp, NETC_STANDALONE_PVID, cfge); 61846d64076SWei Fang if (err) 61946d64076SWei Fang dev_err(priv->dev, 62046d64076SWei Fang "Failed to add standalone VLAN entry\n"); 62146d64076SWei Fang 62246d64076SWei Fang kfree(cfge); 62346d64076SWei Fang 62446d64076SWei Fang return err; 62546d64076SWei Fang } 62646d64076SWei Fang 62746d64076SWei Fang static int netc_port_add_fdb_entry(struct netc_port *np, 62846d64076SWei Fang const unsigned char *addr, u16 vid) 62946d64076SWei Fang { 63046d64076SWei Fang struct netc_switch *priv = np->switch_priv; 63146d64076SWei Fang struct netc_fdb_entry *entry; 63246d64076SWei Fang struct fdbt_keye_data *keye; 63346d64076SWei Fang struct fdbt_cfge_data *cfge; 63446d64076SWei Fang int port = np->dp->index; 63546d64076SWei Fang u32 cfg = 0; 63646d64076SWei Fang int err; 63746d64076SWei Fang 63846d64076SWei Fang entry = kzalloc_obj(*entry); 63946d64076SWei Fang if (!entry) 64046d64076SWei Fang return -ENOMEM; 64146d64076SWei Fang 64246d64076SWei Fang keye = &entry->keye; 64346d64076SWei Fang cfge = &entry->cfge; 64446d64076SWei Fang ether_addr_copy(keye->mac_addr, addr); 64546d64076SWei Fang keye->fid = cpu_to_le16(vid); 64646d64076SWei Fang 64746d64076SWei Fang cfge->port_bitmap = cpu_to_le32(BIT(port)); 64846d64076SWei Fang cfge->cfg = cpu_to_le32(cfg); 64946d64076SWei Fang cfge->et_eid = cpu_to_le32(NTMP_NULL_ENTRY_ID); 65046d64076SWei Fang 65146d64076SWei Fang err = ntmp_fdbt_add_entry(&priv->ntmp, &entry->entry_id, keye, cfge); 65246d64076SWei Fang if (err) { 65346d64076SWei Fang kfree(entry); 65446d64076SWei Fang 65546d64076SWei Fang return err; 65646d64076SWei Fang } 65746d64076SWei Fang 65846d64076SWei Fang netc_add_fdb_entry(priv, entry); 65946d64076SWei Fang 66046d64076SWei Fang return 0; 66146d64076SWei Fang } 66246d64076SWei Fang 66346d64076SWei Fang static int netc_port_set_fdb_entry(struct netc_port *np, 66446d64076SWei Fang const unsigned char *addr, u16 vid) 66546d64076SWei Fang { 66646d64076SWei Fang struct netc_switch *priv = np->switch_priv; 66746d64076SWei Fang struct netc_fdb_entry *entry; 66846d64076SWei Fang struct fdbt_cfge_data *cfge; 66946d64076SWei Fang int port = np->dp->index; 67046d64076SWei Fang __le32 old_port_bitmap; 67146d64076SWei Fang int err = 0; 67246d64076SWei Fang 67346d64076SWei Fang mutex_lock(&priv->fdbt_lock); 67446d64076SWei Fang 67546d64076SWei Fang entry = netc_lookup_fdb_entry(priv, addr, vid); 67646d64076SWei Fang if (!entry) { 67746d64076SWei Fang err = netc_port_add_fdb_entry(np, addr, vid); 67846d64076SWei Fang if (err) 67946d64076SWei Fang dev_err(priv->dev, 68046d64076SWei Fang "Failed to add FDB entry on port %d\n", 68146d64076SWei Fang port); 68246d64076SWei Fang 68346d64076SWei Fang goto unlock_fdbt; 68446d64076SWei Fang } 68546d64076SWei Fang 68646d64076SWei Fang cfge = &entry->cfge; 68746d64076SWei Fang /* If the entry already exists on the port, return 0 directly */ 68846d64076SWei Fang if (unlikely(cfge->port_bitmap & cpu_to_le32(BIT(port)))) 68946d64076SWei Fang goto unlock_fdbt; 69046d64076SWei Fang 69146d64076SWei Fang /* If the entry already exists, but not on this port, we need to 69246d64076SWei Fang * update the port bitmap. In general, it should only be valid 69346d64076SWei Fang * for multicast or broadcast address. 69446d64076SWei Fang */ 69546d64076SWei Fang old_port_bitmap = cfge->port_bitmap; 69646d64076SWei Fang if (is_multicast_ether_addr(addr)) 69746d64076SWei Fang cfge->port_bitmap |= cpu_to_le32(BIT(port)); 69846d64076SWei Fang else 69946d64076SWei Fang cfge->port_bitmap = cpu_to_le32(BIT(port)); 70046d64076SWei Fang 70146d64076SWei Fang err = ntmp_fdbt_update_entry(&priv->ntmp, entry->entry_id, cfge); 70246d64076SWei Fang if (err) { 70346d64076SWei Fang cfge->port_bitmap = old_port_bitmap; 70446d64076SWei Fang dev_err(priv->dev, "Failed to set FDB entry on port %d\n", 70546d64076SWei Fang port); 70646d64076SWei Fang } 70746d64076SWei Fang 70846d64076SWei Fang unlock_fdbt: 70946d64076SWei Fang mutex_unlock(&priv->fdbt_lock); 71046d64076SWei Fang 71146d64076SWei Fang return err; 71246d64076SWei Fang } 71346d64076SWei Fang 71446d64076SWei Fang static int netc_port_del_fdb_entry(struct netc_port *np, 71546d64076SWei Fang const unsigned char *addr, u16 vid) 71646d64076SWei Fang { 71746d64076SWei Fang struct netc_switch *priv = np->switch_priv; 71846d64076SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 71946d64076SWei Fang struct netc_fdb_entry *entry; 72046d64076SWei Fang struct fdbt_cfge_data *cfge; 72146d64076SWei Fang int port = np->dp->index; 72246d64076SWei Fang int err = 0; 72346d64076SWei Fang 72446d64076SWei Fang mutex_lock(&priv->fdbt_lock); 72546d64076SWei Fang 72646d64076SWei Fang entry = netc_lookup_fdb_entry(priv, addr, vid); 72746d64076SWei Fang if (unlikely(!entry)) 728751aa5a5SWei Fang /* The hardware-learned dynamic FDB entries cannot be deleted 729751aa5a5SWei Fang * through .port_fdb_del() interface. 730751aa5a5SWei Fang * For NTF_MASTER path: Since hardware-learned dynamic FDB 731751aa5a5SWei Fang * entries are never synchronized back to the bridge software 732751aa5a5SWei Fang * database. br_fdb_delete() -> br_fdb_find() cannot find the 733751aa5a5SWei Fang * FDB entry, so .port_fdb_del() will not be called. 734751aa5a5SWei Fang * For NTF_SELF path: dsa_user_netdev_ops does not implement 735751aa5a5SWei Fang * ndo_fdb_del(), so rtnl_fdb_del() falls back to 736751aa5a5SWei Fang * ndo_dflt_fdb_del(), which only supports NUD_PERMANENT static 737751aa5a5SWei Fang * entries and rejects all others with -EINVAL. 73846d64076SWei Fang */ 73946d64076SWei Fang goto unlock_fdbt; 74046d64076SWei Fang 74146d64076SWei Fang cfge = &entry->cfge; 74246d64076SWei Fang if (unlikely(!(cfge->port_bitmap & cpu_to_le32(BIT(port))))) 74346d64076SWei Fang goto unlock_fdbt; 74446d64076SWei Fang 74546d64076SWei Fang if (cfge->port_bitmap != cpu_to_le32(BIT(port))) { 74646d64076SWei Fang /* If the entry also exists on other ports, we need to 74746d64076SWei Fang * update the entry in the FDB table. 74846d64076SWei Fang */ 74946d64076SWei Fang cfge->port_bitmap &= cpu_to_le32(~BIT(port)); 75046d64076SWei Fang err = ntmp_fdbt_update_entry(ntmp, entry->entry_id, cfge); 75146d64076SWei Fang if (err) { 75246d64076SWei Fang cfge->port_bitmap |= cpu_to_le32(BIT(port)); 75346d64076SWei Fang goto unlock_fdbt; 75446d64076SWei Fang } 75546d64076SWei Fang } else { 75646d64076SWei Fang /* If the entry only exists on this port, just delete 75746d64076SWei Fang * it from the FDB table. 75846d64076SWei Fang */ 75946d64076SWei Fang err = ntmp_fdbt_delete_entry(ntmp, entry->entry_id); 76046d64076SWei Fang if (err) 76146d64076SWei Fang goto unlock_fdbt; 76246d64076SWei Fang 76346d64076SWei Fang netc_del_fdb_entry(entry); 76446d64076SWei Fang } 76546d64076SWei Fang 76646d64076SWei Fang unlock_fdbt: 76746d64076SWei Fang mutex_unlock(&priv->fdbt_lock); 76846d64076SWei Fang 76946d64076SWei Fang return err; 77046d64076SWei Fang } 77146d64076SWei Fang 77246d64076SWei Fang static int netc_add_standalone_fdb_bcast_entry(struct netc_switch *priv) 77346d64076SWei Fang { 77446d64076SWei Fang const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 77546d64076SWei Fang struct dsa_port *dp, *cpu_dp = NULL; 77646d64076SWei Fang 77746d64076SWei Fang dsa_switch_for_each_cpu_port(dp, priv->ds) { 77846d64076SWei Fang /* The switch has only one CPU port, so only need to find 77946d64076SWei Fang * the first CPU port to break out of the loop. 78046d64076SWei Fang */ 78146d64076SWei Fang cpu_dp = dp; 78246d64076SWei Fang break; 78346d64076SWei Fang } 78446d64076SWei Fang 78546d64076SWei Fang if (!cpu_dp) 78646d64076SWei Fang return -ENODEV; 78746d64076SWei Fang 78846d64076SWei Fang /* If the user port acts as a standalone port, then its PVID is 0, 78946d64076SWei Fang * MLO is set to "disable MAC learning" and MFO is set to "discard 79046d64076SWei Fang * frames if no matching entry found in FDB table". Therefore, we 79146d64076SWei Fang * need to add a broadcast FDB entry on the CPU port so that the 79246d64076SWei Fang * broadcast frames received on the user port can be forwarded to 79346d64076SWei Fang * the CPU port. 79446d64076SWei Fang */ 79546d64076SWei Fang return netc_port_set_fdb_entry(NETC_PORT(priv->ds, cpu_dp->index), 79646d64076SWei Fang bcast, NETC_STANDALONE_PVID); 79746d64076SWei Fang } 79846d64076SWei Fang 799a5ccb7f5SWei Fang static void netc_port_set_pbpmcr(struct netc_port *np, u64 mapping) 800a5ccb7f5SWei Fang { 801a5ccb7f5SWei Fang u32 pbpmcr0 = lower_32_bits(mapping); 802a5ccb7f5SWei Fang u32 pbpmcr1 = upper_32_bits(mapping); 803a5ccb7f5SWei Fang 804a5ccb7f5SWei Fang netc_port_wr(np, NETC_PBPMCR0, pbpmcr0); 805a5ccb7f5SWei Fang netc_port_wr(np, NETC_PBPMCR1, pbpmcr1); 806a5ccb7f5SWei Fang } 807a5ccb7f5SWei Fang 808a5ccb7f5SWei Fang static void netc_ipv_to_buffer_pool_mapping(struct netc_switch *priv) 809a5ccb7f5SWei Fang { 810a5ccb7f5SWei Fang int bp_per_port = priv->num_bp / priv->info->num_ports; 811a5ccb7f5SWei Fang int q = NETC_IPV_NUM / bp_per_port; 812a5ccb7f5SWei Fang int r = NETC_IPV_NUM % bp_per_port; 813a5ccb7f5SWei Fang int num = q + r; 814a5ccb7f5SWei Fang 815a5ccb7f5SWei Fang /* IPV-to-buffer-pool mapping per port: 816a5ccb7f5SWei Fang * Each port is allocated 'bp_per_port' buffer pools and supports 8 817a5ccb7f5SWei Fang * IPVs, where a higher IPV indicates a higher frame priority. Each 818a5ccb7f5SWei Fang * IPV can be mapped to only one buffer pool, from hardware design 819a5ccb7f5SWei Fang * perspective, bp_per_port will not be greater than 8. So 'q' will 820a5ccb7f5SWei Fang * not be 0. 821a5ccb7f5SWei Fang * 822a5ccb7f5SWei Fang * The mapping rule is as follows: 823a5ccb7f5SWei Fang * - The first 'num' IPVs share the port's first buffer pool (index 824a5ccb7f5SWei Fang * 'base_id'). 825a5ccb7f5SWei Fang * - After that, every 'q' IPVs share one buffer pool, with pool 826a5ccb7f5SWei Fang * indices increasing sequentially. 827a5ccb7f5SWei Fang */ 828a5ccb7f5SWei Fang for (int i = 0; i < priv->info->num_ports; i++) { 829a5ccb7f5SWei Fang u32 base_id = i * bp_per_port; 830a5ccb7f5SWei Fang u32 bp_id = base_id; 831a5ccb7f5SWei Fang u64 mapping = 0; 832a5ccb7f5SWei Fang 833a5ccb7f5SWei Fang for (int ipv = 0; ipv < NETC_IPV_NUM; ipv++) { 834a5ccb7f5SWei Fang /* Update the buffer pool index */ 835a5ccb7f5SWei Fang if (ipv >= num) 836a5ccb7f5SWei Fang bp_id = base_id + ((ipv - num) / q) + 1; 837a5ccb7f5SWei Fang 838a5ccb7f5SWei Fang mapping |= (u64)bp_id << (ipv * 8); 839a5ccb7f5SWei Fang } 840a5ccb7f5SWei Fang 841a5ccb7f5SWei Fang netc_port_set_pbpmcr(priv->ports[i], mapping); 842a5ccb7f5SWei Fang } 843a5ccb7f5SWei Fang } 844a5ccb7f5SWei Fang 845a5ccb7f5SWei Fang static int netc_switch_bpt_default_config(struct netc_switch *priv) 846a5ccb7f5SWei Fang { 847a5ccb7f5SWei Fang if (priv->num_bp < priv->info->num_ports) 848a5ccb7f5SWei Fang return -EINVAL; 849a5ccb7f5SWei Fang 850a5ccb7f5SWei Fang priv->bpt_list = devm_kcalloc(priv->dev, priv->num_bp, 851a5ccb7f5SWei Fang sizeof(struct bpt_cfge_data), 852a5ccb7f5SWei Fang GFP_KERNEL); 853a5ccb7f5SWei Fang if (!priv->bpt_list) 854a5ccb7f5SWei Fang return -ENOMEM; 855a5ccb7f5SWei Fang 856a5ccb7f5SWei Fang /* Initialize the maximum threshold of each buffer pool entry */ 857a5ccb7f5SWei Fang for (int i = 0; i < priv->num_bp; i++) { 858a5ccb7f5SWei Fang struct bpt_cfge_data *cfge = &priv->bpt_list[i]; 859a5ccb7f5SWei Fang int err; 860a5ccb7f5SWei Fang 861a5ccb7f5SWei Fang cfge->max_thresh = cpu_to_le16(NETC_BP_THRESH); 862a5ccb7f5SWei Fang err = ntmp_bpt_update_entry(&priv->ntmp, i, cfge); 863a5ccb7f5SWei Fang if (err) 864a5ccb7f5SWei Fang return err; 865a5ccb7f5SWei Fang } 866a5ccb7f5SWei Fang 867a5ccb7f5SWei Fang netc_ipv_to_buffer_pool_mapping(priv); 868a5ccb7f5SWei Fang 869a5ccb7f5SWei Fang return 0; 870a5ccb7f5SWei Fang } 871a5ccb7f5SWei Fang 872187fbae0SWei Fang static int netc_setup(struct dsa_switch *ds) 873187fbae0SWei Fang { 874187fbae0SWei Fang struct netc_switch *priv = ds->priv; 875187fbae0SWei Fang struct dsa_port *dp; 876187fbae0SWei Fang int err; 877187fbae0SWei Fang 878187fbae0SWei Fang err = netc_init_switch_id(priv); 879187fbae0SWei Fang if (err) 880187fbae0SWei Fang return err; 881187fbae0SWei Fang 88246d64076SWei Fang netc_get_switch_capabilities(priv); 88346d64076SWei Fang 884187fbae0SWei Fang err = netc_init_all_ports(priv); 885187fbae0SWei Fang if (err) 886187fbae0SWei Fang return err; 887187fbae0SWei Fang 888187fbae0SWei Fang err = netc_init_ntmp_user(priv); 889187fbae0SWei Fang if (err) 890187fbae0SWei Fang return err; 891187fbae0SWei Fang 89246d64076SWei Fang INIT_HLIST_HEAD(&priv->fdb_list); 89346d64076SWei Fang mutex_init(&priv->fdbt_lock); 894*05b5ee61SWei Fang priv->fdbt_ageing_delay = NETC_FDBT_AGEING_DELAY; 895*05b5ee61SWei Fang atomic_set(&priv->br_cnt, 0); 896*05b5ee61SWei Fang INIT_DELAYED_WORK(&priv->fdbt_ageing_work, 897*05b5ee61SWei Fang netc_clean_fdbt_ageing_entries); 89884b4a3b3SWei Fang INIT_HLIST_HEAD(&priv->vlan_list); 89984b4a3b3SWei Fang mutex_init(&priv->vft_lock); 90046d64076SWei Fang 901187fbae0SWei Fang netc_switch_fixed_config(priv); 902187fbae0SWei Fang 903187fbae0SWei Fang /* default setting for ports */ 904187fbae0SWei Fang dsa_switch_for_each_available_port(dp, ds) 905187fbae0SWei Fang netc_port_default_config(priv->ports[dp->index]); 906187fbae0SWei Fang 907a5ccb7f5SWei Fang err = netc_switch_bpt_default_config(priv); 908a5ccb7f5SWei Fang if (err) 909a5ccb7f5SWei Fang goto free_lock_and_ntmp_user; 910a5ccb7f5SWei Fang 91146d64076SWei Fang err = netc_add_standalone_vlan_entry(priv); 91246d64076SWei Fang if (err) 91346d64076SWei Fang goto free_lock_and_ntmp_user; 91446d64076SWei Fang 91546d64076SWei Fang err = netc_add_standalone_fdb_bcast_entry(priv); 91646d64076SWei Fang if (err) 91746d64076SWei Fang goto free_lock_and_ntmp_user; 91846d64076SWei Fang 919187fbae0SWei Fang return 0; 92046d64076SWei Fang 92146d64076SWei Fang free_lock_and_ntmp_user: 92246d64076SWei Fang /* No need to clear the hardware state, netc_setup() is only called 92346d64076SWei Fang * when the driver is bound, and FLR will be performed to reset the 92446d64076SWei Fang * hardware state. 92546d64076SWei Fang */ 92646d64076SWei Fang mutex_destroy(&priv->fdbt_lock); 92784b4a3b3SWei Fang mutex_destroy(&priv->vft_lock); 92846d64076SWei Fang netc_free_ntmp_user(priv); 92946d64076SWei Fang 93046d64076SWei Fang return err; 93146d64076SWei Fang } 93246d64076SWei Fang 93346d64076SWei Fang static void netc_destroy_all_lists(struct netc_switch *priv) 93446d64076SWei Fang { 93546d64076SWei Fang netc_destroy_fdb_list(priv); 93646d64076SWei Fang mutex_destroy(&priv->fdbt_lock); 93784b4a3b3SWei Fang netc_destroy_vlan_list(priv); 93884b4a3b3SWei Fang mutex_destroy(&priv->vft_lock); 93946d64076SWei Fang } 94046d64076SWei Fang 94146d64076SWei Fang static void netc_free_host_flood_rules(struct netc_switch *priv) 94246d64076SWei Fang { 94346d64076SWei Fang struct dsa_port *dp; 94446d64076SWei Fang 94546d64076SWei Fang dsa_switch_for_each_user_port(dp, priv->ds) { 94646d64076SWei Fang struct netc_port *np = priv->ports[dp->index]; 94746d64076SWei Fang 94846d64076SWei Fang /* No need to clear the hardware IPFT entry. Because PCIe 94946d64076SWei Fang * FLR will be performed when the switch is re-registered, 95046d64076SWei Fang * it will reset hardware state. So only need to free the 95146d64076SWei Fang * memory to avoid memory leak. 95246d64076SWei Fang */ 95346d64076SWei Fang kfree(np->host_flood); 95446d64076SWei Fang np->host_flood = NULL; 95546d64076SWei Fang } 956187fbae0SWei Fang } 957187fbae0SWei Fang 958187fbae0SWei Fang static void netc_teardown(struct dsa_switch *ds) 959187fbae0SWei Fang { 960187fbae0SWei Fang struct netc_switch *priv = ds->priv; 961187fbae0SWei Fang 962*05b5ee61SWei Fang disable_delayed_work_sync(&priv->fdbt_ageing_work); 96346d64076SWei Fang netc_destroy_all_lists(priv); 96446d64076SWei Fang netc_free_host_flood_rules(priv); 965187fbae0SWei Fang netc_free_ntmp_user(priv); 966187fbae0SWei Fang } 967187fbae0SWei Fang 968187fbae0SWei Fang static bool netc_port_is_emdio_consumer(struct device_node *node) 969187fbae0SWei Fang { 970187fbae0SWei Fang struct device_node *mdio_node; 971187fbae0SWei Fang 972187fbae0SWei Fang /* If the port node has phy-handle property and it does 973187fbae0SWei Fang * not contain a mdio child node, then the port is the 974187fbae0SWei Fang * EMDIO consumer. 975187fbae0SWei Fang */ 976187fbae0SWei Fang mdio_node = of_get_child_by_name(node, "mdio"); 977187fbae0SWei Fang if (!mdio_node) 978187fbae0SWei Fang return true; 979187fbae0SWei Fang 980187fbae0SWei Fang of_node_put(mdio_node); 981187fbae0SWei Fang 982187fbae0SWei Fang return false; 983187fbae0SWei Fang } 984187fbae0SWei Fang 985187fbae0SWei Fang /* Currently, phylink_of_phy_connect() is called by dsa_user_create(), 986187fbae0SWei Fang * so if the switch uses the external MDIO controller (like the EMDIO 987187fbae0SWei Fang * function) to manage the external PHYs. The MDIO bus may not be 988187fbae0SWei Fang * created when phylink_of_phy_connect() is called, so it will return 989187fbae0SWei Fang * an error and cause the switch driver to fail to probe. 990187fbae0SWei Fang * This workaround can be removed when DSA phylink_of_phy_connect() 991187fbae0SWei Fang * calls are moved from probe() to ndo_open(). 992187fbae0SWei Fang */ 993187fbae0SWei Fang static int netc_switch_check_emdio_is_ready(struct device *dev) 994187fbae0SWei Fang { 995187fbae0SWei Fang struct device_node *ports, *phy_node; 996187fbae0SWei Fang struct phy_device *phydev; 997187fbae0SWei Fang int err = 0; 998187fbae0SWei Fang 999187fbae0SWei Fang ports = of_get_child_by_name(dev->of_node, "ethernet-ports"); 1000187fbae0SWei Fang if (!ports) { 1001187fbae0SWei Fang dev_err(dev, "Cannot find the ethernet-ports node\n"); 1002187fbae0SWei Fang return -EINVAL; 1003187fbae0SWei Fang } 1004187fbae0SWei Fang 1005187fbae0SWei Fang for_each_available_child_of_node_scoped(ports, child) { 1006187fbae0SWei Fang /* If the node does not have phy-handle property, then the 1007187fbae0SWei Fang * port does not connect to a PHY, so the port is not the 1008187fbae0SWei Fang * EMDIO consumer. 1009187fbae0SWei Fang */ 1010187fbae0SWei Fang phy_node = of_parse_phandle(child, "phy-handle", 0); 1011187fbae0SWei Fang if (!phy_node) 1012187fbae0SWei Fang continue; 1013187fbae0SWei Fang 1014187fbae0SWei Fang /* Note that from the hardware perspective, the switch ports 1015187fbae0SWei Fang * do not support sharing the MDIO bus defined under one port. 1016187fbae0SWei Fang * Each port can only access its own external PHY through its 1017187fbae0SWei Fang * port MDIO bus. 1018187fbae0SWei Fang */ 1019187fbae0SWei Fang if (!netc_port_is_emdio_consumer(child)) { 1020187fbae0SWei Fang of_node_put(phy_node); 1021187fbae0SWei Fang continue; 1022187fbae0SWei Fang } 1023187fbae0SWei Fang 1024187fbae0SWei Fang phydev = of_phy_find_device(phy_node); 1025187fbae0SWei Fang of_node_put(phy_node); 1026187fbae0SWei Fang if (!phydev) { 1027187fbae0SWei Fang err = -EPROBE_DEFER; 1028187fbae0SWei Fang goto out; 1029187fbae0SWei Fang } 1030187fbae0SWei Fang 1031187fbae0SWei Fang put_device(&phydev->mdio.dev); 1032187fbae0SWei Fang } 1033187fbae0SWei Fang 1034187fbae0SWei Fang out: 1035187fbae0SWei Fang of_node_put(ports); 1036187fbae0SWei Fang 1037187fbae0SWei Fang return err; 1038187fbae0SWei Fang } 1039187fbae0SWei Fang 1040187fbae0SWei Fang static int netc_switch_pci_init(struct pci_dev *pdev) 1041187fbae0SWei Fang { 1042187fbae0SWei Fang struct device *dev = &pdev->dev; 1043187fbae0SWei Fang struct netc_switch_regs *regs; 1044187fbae0SWei Fang struct netc_switch *priv; 1045187fbae0SWei Fang void __iomem *base; 1046187fbae0SWei Fang int err; 1047187fbae0SWei Fang 1048187fbae0SWei Fang pcie_flr(pdev); 1049187fbae0SWei Fang err = pcim_enable_device(pdev); 1050187fbae0SWei Fang if (err) 1051187fbae0SWei Fang return dev_err_probe(dev, err, "Failed to enable device\n"); 1052187fbae0SWei Fang 1053187fbae0SWei Fang err = pcim_request_all_regions(pdev, KBUILD_MODNAME); 1054187fbae0SWei Fang if (err) 1055187fbae0SWei Fang return dev_err_probe(dev, err, "Failed to request regions\n"); 1056187fbae0SWei Fang 1057187fbae0SWei Fang /* The command BD rings and NTMP tables need DMA. No need to check 1058187fbae0SWei Fang * the return value, because it never returns fail when the mask is 1059187fbae0SWei Fang * DMA_BIT_MASK(64), see dma-api-howto.rst. 1060187fbae0SWei Fang */ 1061187fbae0SWei Fang dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); 1062187fbae0SWei Fang 1063187fbae0SWei Fang if (pci_resource_len(pdev, NETC_REGS_BAR) < NETC_REGS_SIZE) { 1064187fbae0SWei Fang return dev_err_probe(dev, -EINVAL, 1065187fbae0SWei Fang "Invalid register space size\n"); 1066187fbae0SWei Fang } 1067187fbae0SWei Fang 1068187fbae0SWei Fang base = pcim_iomap(pdev, NETC_REGS_BAR, 0); 1069187fbae0SWei Fang if (!base) 1070187fbae0SWei Fang return dev_err_probe(dev, -ENXIO, "pcim_iomap() failed\n"); 1071187fbae0SWei Fang 1072187fbae0SWei Fang pci_set_master(pdev); 1073187fbae0SWei Fang 1074187fbae0SWei Fang priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 1075187fbae0SWei Fang if (!priv) 1076187fbae0SWei Fang return -ENOMEM; 1077187fbae0SWei Fang 1078187fbae0SWei Fang priv->pdev = pdev; 1079187fbae0SWei Fang priv->dev = dev; 1080187fbae0SWei Fang 1081187fbae0SWei Fang regs = &priv->regs; 1082187fbae0SWei Fang regs->base = base; 1083187fbae0SWei Fang regs->port = regs->base + NETC_REGS_PORT_BASE; 1084187fbae0SWei Fang regs->global = regs->base + NETC_REGS_GLOBAL_BASE; 1085187fbae0SWei Fang pci_set_drvdata(pdev, priv); 1086187fbae0SWei Fang 1087187fbae0SWei Fang return 0; 1088187fbae0SWei Fang } 1089187fbae0SWei Fang 1090187fbae0SWei Fang static void netc_switch_get_ip_revision(struct netc_switch *priv) 1091187fbae0SWei Fang { 1092187fbae0SWei Fang struct netc_switch_regs *regs = &priv->regs; 1093187fbae0SWei Fang u32 val = netc_glb_rd(regs, NETC_IPBRR0); 1094187fbae0SWei Fang 1095187fbae0SWei Fang priv->revision = FIELD_GET(IPBRR0_IP_REV, val); 1096187fbae0SWei Fang } 1097187fbae0SWei Fang 109884b4a3b3SWei Fang static void netc_init_ett_cfge(struct ett_cfge_data *cfge, 109984b4a3b3SWei Fang bool untagged, u32 ect_eid) 110084b4a3b3SWei Fang { 110184b4a3b3SWei Fang u32 vuda_sqta = FMTEID_VUDA_SQTA; 110284b4a3b3SWei Fang u16 efm_cfg = 0; 110384b4a3b3SWei Fang 110484b4a3b3SWei Fang if (ect_eid != NTMP_NULL_ENTRY_ID) { 110584b4a3b3SWei Fang /* Increase egress frame counter */ 110684b4a3b3SWei Fang efm_cfg |= FIELD_PREP(ETT_ECA, ETT_ECA_INC); 110784b4a3b3SWei Fang cfge->ec_eid = cpu_to_le32(ect_eid); 110884b4a3b3SWei Fang } 110984b4a3b3SWei Fang 111084b4a3b3SWei Fang /* If egress rule is VLAN untagged */ 111184b4a3b3SWei Fang if (untagged) { 111284b4a3b3SWei Fang /* delete outer VLAN tag */ 111384b4a3b3SWei Fang vuda_sqta |= FIELD_PREP(FMTEID_VUDA, FMTEID_VUDA_DEL_OTAG); 111484b4a3b3SWei Fang /* length change: twos-complement notation */ 111584b4a3b3SWei Fang efm_cfg |= FIELD_PREP(ETT_EFM_LEN_CHANGE, 111684b4a3b3SWei Fang ETT_FRM_LEN_DEL_VLAN); 111784b4a3b3SWei Fang } 111884b4a3b3SWei Fang 111984b4a3b3SWei Fang cfge->efm_eid = cpu_to_le32(vuda_sqta); 112084b4a3b3SWei Fang cfge->efm_cfg = cpu_to_le16(efm_cfg); 112184b4a3b3SWei Fang } 112284b4a3b3SWei Fang 112384b4a3b3SWei Fang static int netc_add_ett_entry(struct netc_switch *priv, bool untagged, 112484b4a3b3SWei Fang u32 ett_eid, u32 ect_eid) 112584b4a3b3SWei Fang { 112684b4a3b3SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 112784b4a3b3SWei Fang struct ett_cfge_data cfge = {}; 112884b4a3b3SWei Fang 112984b4a3b3SWei Fang netc_init_ett_cfge(&cfge, untagged, ect_eid); 113084b4a3b3SWei Fang 113184b4a3b3SWei Fang return ntmp_ett_add_entry(ntmp, ett_eid, &cfge); 113284b4a3b3SWei Fang } 113384b4a3b3SWei Fang 113484b4a3b3SWei Fang static int netc_update_ett_entry(struct netc_switch *priv, bool untagged, 113584b4a3b3SWei Fang u32 ett_eid, u32 ect_eid) 113684b4a3b3SWei Fang { 113784b4a3b3SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 113884b4a3b3SWei Fang struct ett_cfge_data cfge = {}; 113984b4a3b3SWei Fang 114084b4a3b3SWei Fang netc_init_ett_cfge(&cfge, untagged, ect_eid); 114184b4a3b3SWei Fang 114284b4a3b3SWei Fang return ntmp_ett_update_entry(ntmp, ett_eid, &cfge); 114384b4a3b3SWei Fang } 114484b4a3b3SWei Fang 114584b4a3b3SWei Fang static int netc_add_ett_group_entries(struct netc_switch *priv, 114684b4a3b3SWei Fang u32 untagged_port_bitmap, 114784b4a3b3SWei Fang u32 ett_base_eid, 114884b4a3b3SWei Fang u32 ect_base_eid) 114984b4a3b3SWei Fang { 115084b4a3b3SWei Fang struct netc_port **ports = priv->ports; 115184b4a3b3SWei Fang u32 ett_eid, ect_eid; 115284b4a3b3SWei Fang bool untagged; 115384b4a3b3SWei Fang int i, err; 115484b4a3b3SWei Fang 115584b4a3b3SWei Fang for (i = 0; i < priv->info->num_ports; i++) { 115684b4a3b3SWei Fang if (!ports[i]->dp) 115784b4a3b3SWei Fang continue; 115884b4a3b3SWei Fang 115984b4a3b3SWei Fang untagged = !!(untagged_port_bitmap & BIT(i)); 116084b4a3b3SWei Fang ett_eid = ett_base_eid + ports[i]->ett_offset; 116184b4a3b3SWei Fang ect_eid = NTMP_NULL_ENTRY_ID; 116284b4a3b3SWei Fang if (ect_base_eid != NTMP_NULL_ENTRY_ID) 116384b4a3b3SWei Fang ect_eid = ect_base_eid + ports[i]->ett_offset; 116484b4a3b3SWei Fang 116584b4a3b3SWei Fang err = netc_add_ett_entry(priv, untagged, ett_eid, ect_eid); 116684b4a3b3SWei Fang if (err) 116784b4a3b3SWei Fang goto clear_ett_entries; 116884b4a3b3SWei Fang } 116984b4a3b3SWei Fang 117084b4a3b3SWei Fang return 0; 117184b4a3b3SWei Fang 117284b4a3b3SWei Fang clear_ett_entries: 117384b4a3b3SWei Fang while (--i >= 0) { 117484b4a3b3SWei Fang if (!ports[i]->dp) 117584b4a3b3SWei Fang continue; 117684b4a3b3SWei Fang 117784b4a3b3SWei Fang ett_eid = ett_base_eid + ports[i]->ett_offset; 117884b4a3b3SWei Fang ntmp_ett_delete_entry(&priv->ntmp, ett_eid); 117984b4a3b3SWei Fang } 118084b4a3b3SWei Fang 118184b4a3b3SWei Fang return err; 118284b4a3b3SWei Fang } 118384b4a3b3SWei Fang 118484b4a3b3SWei Fang static int netc_add_vlan_egress_rule(struct netc_switch *priv, 118584b4a3b3SWei Fang struct netc_vlan_entry *entry) 118684b4a3b3SWei Fang { 118784b4a3b3SWei Fang u32 num_ports = netc_num_available_ports(priv); 118884b4a3b3SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 118984b4a3b3SWei Fang u32 ect_eid = NTMP_NULL_ENTRY_ID; 119084b4a3b3SWei Fang u32 ett_eid, ett_gid, ect_gid; 119184b4a3b3SWei Fang int err; 119284b4a3b3SWei Fang 119384b4a3b3SWei Fang /* Step 1: Find available egress counter table entries and update 119484b4a3b3SWei Fang * these entries. 119584b4a3b3SWei Fang */ 119684b4a3b3SWei Fang ect_gid = ntmp_lookup_free_eid(ntmp->ect_gid_bitmap, 119784b4a3b3SWei Fang ntmp->ect_bitmap_size); 119884b4a3b3SWei Fang if (ect_gid == NTMP_NULL_ENTRY_ID) { 119984b4a3b3SWei Fang dev_info(priv->dev, 120084b4a3b3SWei Fang "No egress counter table entries available\n"); 120184b4a3b3SWei Fang } else { 120284b4a3b3SWei Fang ect_eid = ect_gid * num_ports; 120384b4a3b3SWei Fang for (int i = 0; i < num_ports; i++) 120484b4a3b3SWei Fang /* There is no need to check the return value, the only 120584b4a3b3SWei Fang * issue is that the entry's counter might be inaccurate, 120684b4a3b3SWei Fang * but it will not affect the functionality, it is only 120784b4a3b3SWei Fang * for future debugging. 120884b4a3b3SWei Fang */ 120984b4a3b3SWei Fang ntmp_ect_update_entry(ntmp, ect_eid + i); 121084b4a3b3SWei Fang } 121184b4a3b3SWei Fang 121284b4a3b3SWei Fang /* Step 2: Find available egress treatment table entries and add 121384b4a3b3SWei Fang * these entries. 121484b4a3b3SWei Fang */ 121584b4a3b3SWei Fang ett_gid = ntmp_lookup_free_eid(ntmp->ett_gid_bitmap, 121684b4a3b3SWei Fang ntmp->ett_bitmap_size); 121784b4a3b3SWei Fang if (ett_gid == NTMP_NULL_ENTRY_ID) { 121884b4a3b3SWei Fang dev_err(priv->dev, 121984b4a3b3SWei Fang "No egress treatment table entries available\n"); 122084b4a3b3SWei Fang err = -ENOSPC; 122184b4a3b3SWei Fang goto clear_ect_gid; 122284b4a3b3SWei Fang } 122384b4a3b3SWei Fang 122484b4a3b3SWei Fang ett_eid = ett_gid * num_ports; 122584b4a3b3SWei Fang err = netc_add_ett_group_entries(priv, entry->untagged_port_bitmap, 122684b4a3b3SWei Fang ett_eid, ect_eid); 122784b4a3b3SWei Fang if (err) 122884b4a3b3SWei Fang goto clear_ett_gid; 122984b4a3b3SWei Fang 123084b4a3b3SWei Fang entry->cfge.et_eid = cpu_to_le32(ett_eid); 123184b4a3b3SWei Fang entry->ect_gid = ect_gid; 123284b4a3b3SWei Fang 123384b4a3b3SWei Fang return 0; 123484b4a3b3SWei Fang 123584b4a3b3SWei Fang clear_ett_gid: 123684b4a3b3SWei Fang ntmp_clear_eid_bitmap(ntmp->ett_gid_bitmap, ett_gid); 123784b4a3b3SWei Fang 123884b4a3b3SWei Fang clear_ect_gid: 123984b4a3b3SWei Fang if (ect_gid != NTMP_NULL_ENTRY_ID) 124084b4a3b3SWei Fang ntmp_clear_eid_bitmap(ntmp->ect_gid_bitmap, ect_gid); 124184b4a3b3SWei Fang 124284b4a3b3SWei Fang return err; 124384b4a3b3SWei Fang } 124484b4a3b3SWei Fang 124584b4a3b3SWei Fang static void netc_delete_vlan_egress_rule(struct netc_switch *priv, 124684b4a3b3SWei Fang struct netc_vlan_entry *entry) 124784b4a3b3SWei Fang { 124884b4a3b3SWei Fang u32 num_ports = netc_num_available_ports(priv); 124984b4a3b3SWei Fang struct ntmp_user *ntmp = &priv->ntmp; 125084b4a3b3SWei Fang u32 ett_eid, ett_gid; 125184b4a3b3SWei Fang 125284b4a3b3SWei Fang ett_eid = le32_to_cpu(entry->cfge.et_eid); 125384b4a3b3SWei Fang if (ett_eid == NTMP_NULL_ENTRY_ID) 125484b4a3b3SWei Fang return; 125584b4a3b3SWei Fang 125684b4a3b3SWei Fang ett_gid = ett_eid / num_ports; 125784b4a3b3SWei Fang ntmp_clear_eid_bitmap(ntmp->ett_gid_bitmap, ett_gid); 125884b4a3b3SWei Fang for (int i = 0; i < num_ports; i++) 125984b4a3b3SWei Fang ntmp_ett_delete_entry(ntmp, ett_eid + i); 126084b4a3b3SWei Fang 126184b4a3b3SWei Fang if (entry->ect_gid == NTMP_NULL_ENTRY_ID) 126284b4a3b3SWei Fang return; 126384b4a3b3SWei Fang 126484b4a3b3SWei Fang ntmp_clear_eid_bitmap(ntmp->ect_gid_bitmap, entry->ect_gid); 126584b4a3b3SWei Fang } 126684b4a3b3SWei Fang 126784b4a3b3SWei Fang static int netc_port_update_vlan_egress_rule(struct netc_port *np, 126884b4a3b3SWei Fang struct netc_vlan_entry *entry) 126984b4a3b3SWei Fang { 127084b4a3b3SWei Fang bool untagged = !!(entry->untagged_port_bitmap & BIT(np->dp->index)); 127184b4a3b3SWei Fang u32 num_ports = netc_num_available_ports(np->switch_priv); 127284b4a3b3SWei Fang u32 ett_eid = le32_to_cpu(entry->cfge.et_eid); 127384b4a3b3SWei Fang struct netc_switch *priv = np->switch_priv; 127484b4a3b3SWei Fang u32 ect_eid = NTMP_NULL_ENTRY_ID; 127584b4a3b3SWei Fang int err; 127684b4a3b3SWei Fang 127784b4a3b3SWei Fang if (ett_eid == NTMP_NULL_ENTRY_ID) 127884b4a3b3SWei Fang return 0; 127984b4a3b3SWei Fang 128084b4a3b3SWei Fang if (entry->ect_gid != NTMP_NULL_ENTRY_ID) 128184b4a3b3SWei Fang /* Each ETT entry maps to an ECT entry if ect_gid is not NULL 128284b4a3b3SWei Fang * entry ID. The offset of the ECT entry corresponding to the 128384b4a3b3SWei Fang * port in the group is equal to ett_offset. 128484b4a3b3SWei Fang */ 128584b4a3b3SWei Fang ect_eid = entry->ect_gid * num_ports + np->ett_offset; 128684b4a3b3SWei Fang 128784b4a3b3SWei Fang ett_eid += np->ett_offset; 128884b4a3b3SWei Fang err = netc_update_ett_entry(priv, untagged, ett_eid, ect_eid); 128984b4a3b3SWei Fang if (err) { 129084b4a3b3SWei Fang dev_err(priv->dev, 129184b4a3b3SWei Fang "Failed to update VLAN %u egress rule on port %d\n", 129284b4a3b3SWei Fang entry->vid, np->dp->index); 129384b4a3b3SWei Fang return err; 129484b4a3b3SWei Fang } 129584b4a3b3SWei Fang 129684b4a3b3SWei Fang if (ect_eid != NTMP_NULL_ENTRY_ID) 129784b4a3b3SWei Fang ntmp_ect_update_entry(&priv->ntmp, ect_eid); 129884b4a3b3SWei Fang 129984b4a3b3SWei Fang return 0; 130084b4a3b3SWei Fang } 130184b4a3b3SWei Fang 130284b4a3b3SWei Fang static int netc_port_add_vlan_entry(struct netc_port *np, u16 vid, 130384b4a3b3SWei Fang bool untagged) 130484b4a3b3SWei Fang { 130584b4a3b3SWei Fang struct netc_switch *priv = np->switch_priv; 130684b4a3b3SWei Fang struct netc_vlan_entry *entry; 130784b4a3b3SWei Fang struct vft_cfge_data *cfge; 130884b4a3b3SWei Fang u32 index = np->dp->index; 130984b4a3b3SWei Fang u32 bitmap_stg; 131084b4a3b3SWei Fang int err; 131184b4a3b3SWei Fang u16 cfg; 131284b4a3b3SWei Fang 131384b4a3b3SWei Fang entry = kzalloc_obj(*entry); 131484b4a3b3SWei Fang if (!entry) 131584b4a3b3SWei Fang return -ENOMEM; 131684b4a3b3SWei Fang 131784b4a3b3SWei Fang entry->vid = vid; 131884b4a3b3SWei Fang entry->ect_gid = NTMP_NULL_ENTRY_ID; 131984b4a3b3SWei Fang 132084b4a3b3SWei Fang bitmap_stg = BIT(index) | VFT_STG_ID(0); 1321751aa5a5SWei Fang /* If the VID is a VLAN-unaware PVID, the CPU port needs to be 1322751aa5a5SWei Fang * a member of this VLAN. 1323751aa5a5SWei Fang */ 1324751aa5a5SWei Fang if (dsa_port_is_user(np->dp) && 1325751aa5a5SWei Fang vid >= NETC_VLAN_UNAWARE_PVID(priv->ds->max_num_bridges)) { 1326751aa5a5SWei Fang struct dsa_port *cpu_dp = np->dp->cpu_dp; 1327751aa5a5SWei Fang 1328751aa5a5SWei Fang bitmap_stg |= BIT(cpu_dp->index); 1329751aa5a5SWei Fang } 1330751aa5a5SWei Fang 133184b4a3b3SWei Fang cfg = FIELD_PREP(VFT_MLO, MLO_HW) | 133284b4a3b3SWei Fang FIELD_PREP(VFT_MFO, MFO_NO_MATCH_FLOOD); 133384b4a3b3SWei Fang 133484b4a3b3SWei Fang cfge = &entry->cfge; 133584b4a3b3SWei Fang cfge->et_eid = cpu_to_le32(NTMP_NULL_ENTRY_ID); 133684b4a3b3SWei Fang cfge->bitmap_stg = cpu_to_le32(bitmap_stg); 133784b4a3b3SWei Fang cfge->fid = cpu_to_le16(vid); 133884b4a3b3SWei Fang cfge->cfg = cpu_to_le16(cfg); 133984b4a3b3SWei Fang cfge->eta_port_bitmap = cpu_to_le32(priv->port_bitmap); 134084b4a3b3SWei Fang 134184b4a3b3SWei Fang if (untagged) 134284b4a3b3SWei Fang entry->untagged_port_bitmap = BIT(index); 134384b4a3b3SWei Fang 134484b4a3b3SWei Fang err = netc_add_vlan_egress_rule(priv, entry); 134584b4a3b3SWei Fang if (err) 134684b4a3b3SWei Fang goto free_vlan_entry; 134784b4a3b3SWei Fang 134884b4a3b3SWei Fang err = ntmp_vft_add_entry(&priv->ntmp, vid, cfge); 134984b4a3b3SWei Fang if (err) { 135084b4a3b3SWei Fang dev_err(priv->dev, 135184b4a3b3SWei Fang "Failed to add VLAN %u entry on port %d\n", 135284b4a3b3SWei Fang vid, index); 135384b4a3b3SWei Fang goto delete_vlan_egress_rule; 135484b4a3b3SWei Fang } 135584b4a3b3SWei Fang 135684b4a3b3SWei Fang netc_add_vlan_entry(priv, entry); 135784b4a3b3SWei Fang 135884b4a3b3SWei Fang return 0; 135984b4a3b3SWei Fang 136084b4a3b3SWei Fang delete_vlan_egress_rule: 136184b4a3b3SWei Fang netc_delete_vlan_egress_rule(priv, entry); 136284b4a3b3SWei Fang free_vlan_entry: 136384b4a3b3SWei Fang kfree(entry); 136484b4a3b3SWei Fang 136584b4a3b3SWei Fang return err; 136684b4a3b3SWei Fang } 136784b4a3b3SWei Fang 1368751aa5a5SWei Fang static bool netc_port_vlan_egress_rule_changed(struct netc_switch *priv, 1369751aa5a5SWei Fang struct netc_vlan_entry *entry, 137084b4a3b3SWei Fang int port, bool untagged) 137184b4a3b3SWei Fang { 137284b4a3b3SWei Fang bool old_untagged = !!(entry->untagged_port_bitmap & BIT(port)); 137384b4a3b3SWei Fang 1374751aa5a5SWei Fang /* VLAN-unaware VIDs have no egress rules, so return 'false' */ 1375751aa5a5SWei Fang if (entry->vid >= NETC_VLAN_UNAWARE_PVID(priv->ds->max_num_bridges)) 1376751aa5a5SWei Fang return false; 1377751aa5a5SWei Fang 137884b4a3b3SWei Fang return old_untagged != untagged; 137984b4a3b3SWei Fang } 138084b4a3b3SWei Fang 138184b4a3b3SWei Fang static int netc_port_set_vlan_entry(struct netc_port *np, u16 vid, 138284b4a3b3SWei Fang bool untagged) 138384b4a3b3SWei Fang { 138484b4a3b3SWei Fang struct netc_switch *priv = np->switch_priv; 138584b4a3b3SWei Fang struct netc_vlan_entry *entry; 138684b4a3b3SWei Fang struct vft_cfge_data *cfge; 138784b4a3b3SWei Fang int port = np->dp->index; 138884b4a3b3SWei Fang bool changed; 138984b4a3b3SWei Fang int err = 0; 139084b4a3b3SWei Fang 139184b4a3b3SWei Fang mutex_lock(&priv->vft_lock); 139284b4a3b3SWei Fang 139384b4a3b3SWei Fang entry = netc_lookup_vlan_entry(priv, vid); 139484b4a3b3SWei Fang if (!entry) { 139584b4a3b3SWei Fang err = netc_port_add_vlan_entry(np, vid, untagged); 139684b4a3b3SWei Fang goto unlock_vft; 139784b4a3b3SWei Fang } 139884b4a3b3SWei Fang 139984b4a3b3SWei Fang /* Check whether the egress VLAN rule is changed */ 1400751aa5a5SWei Fang changed = netc_port_vlan_egress_rule_changed(priv, entry, port, 1401751aa5a5SWei Fang untagged); 140284b4a3b3SWei Fang if (changed) { 140384b4a3b3SWei Fang entry->untagged_port_bitmap ^= BIT(port); 140484b4a3b3SWei Fang err = netc_port_update_vlan_egress_rule(np, entry); 140584b4a3b3SWei Fang if (err) { 140684b4a3b3SWei Fang entry->untagged_port_bitmap ^= BIT(port); 140784b4a3b3SWei Fang goto unlock_vft; 140884b4a3b3SWei Fang } 140984b4a3b3SWei Fang } 141084b4a3b3SWei Fang 141184b4a3b3SWei Fang cfge = &entry->cfge; 141284b4a3b3SWei Fang if (cfge->bitmap_stg & cpu_to_le32(BIT(port))) 141384b4a3b3SWei Fang goto unlock_vft; 141484b4a3b3SWei Fang 141584b4a3b3SWei Fang cfge->bitmap_stg |= cpu_to_le32(BIT(port)); 141684b4a3b3SWei Fang err = ntmp_vft_update_entry(&priv->ntmp, vid, cfge); 141784b4a3b3SWei Fang if (err) { 141884b4a3b3SWei Fang dev_err(priv->dev, 141984b4a3b3SWei Fang "Failed to update VLAN %u entry on port %d\n", 142084b4a3b3SWei Fang vid, port); 142184b4a3b3SWei Fang 142284b4a3b3SWei Fang goto restore_bitmap_stg; 142384b4a3b3SWei Fang } 142484b4a3b3SWei Fang 142584b4a3b3SWei Fang mutex_unlock(&priv->vft_lock); 142684b4a3b3SWei Fang 142784b4a3b3SWei Fang return 0; 142884b4a3b3SWei Fang 142984b4a3b3SWei Fang restore_bitmap_stg: 143084b4a3b3SWei Fang cfge->bitmap_stg &= cpu_to_le32(~BIT(port)); 143184b4a3b3SWei Fang if (changed) { 143284b4a3b3SWei Fang entry->untagged_port_bitmap ^= BIT(port); 143384b4a3b3SWei Fang /* Recover the corresponding ETT entry. It doesn't matter 143484b4a3b3SWei Fang * if it fails because the bit corresponding to the port 143584b4a3b3SWei Fang * in the port bitmap of the VFT entry is not set. so the 143684b4a3b3SWei Fang * frame will not match that ETT entry. 143784b4a3b3SWei Fang */ 143884b4a3b3SWei Fang if (netc_port_update_vlan_egress_rule(np, entry)) 143984b4a3b3SWei Fang entry->untagged_port_bitmap ^= BIT(port); 144084b4a3b3SWei Fang } 144184b4a3b3SWei Fang unlock_vft: 144284b4a3b3SWei Fang mutex_unlock(&priv->vft_lock); 144384b4a3b3SWei Fang 144484b4a3b3SWei Fang return err; 144584b4a3b3SWei Fang } 144684b4a3b3SWei Fang 144784b4a3b3SWei Fang static int netc_port_del_vlan_entry(struct netc_port *np, u16 vid) 144884b4a3b3SWei Fang { 144984b4a3b3SWei Fang struct netc_switch *priv = np->switch_priv; 145084b4a3b3SWei Fang struct netc_vlan_entry *entry; 145184b4a3b3SWei Fang struct vft_cfge_data *cfge; 145284b4a3b3SWei Fang int port = np->dp->index; 145384b4a3b3SWei Fang u32 vlan_port_bitmap; 145484b4a3b3SWei Fang int err = 0; 145584b4a3b3SWei Fang 145684b4a3b3SWei Fang mutex_lock(&priv->vft_lock); 145784b4a3b3SWei Fang 145884b4a3b3SWei Fang entry = netc_lookup_vlan_entry(priv, vid); 145984b4a3b3SWei Fang if (!entry) 146084b4a3b3SWei Fang goto unlock_vft; 146184b4a3b3SWei Fang 146284b4a3b3SWei Fang cfge = &entry->cfge; 146384b4a3b3SWei Fang vlan_port_bitmap = FIELD_GET(VFT_PORT_MEMBERSHIP, 146484b4a3b3SWei Fang le32_to_cpu(cfge->bitmap_stg)); 1465751aa5a5SWei Fang /* If the VID is a VLAN-unaware PVID, we need to clear the CPU 1466751aa5a5SWei Fang * port bit of vlan_port_bitmap, so that the VLAN entry can be 1467751aa5a5SWei Fang * deleted if no user ports use this VLAN. 1468751aa5a5SWei Fang */ 1469751aa5a5SWei Fang if (dsa_port_is_user(np->dp) && 1470751aa5a5SWei Fang vid >= NETC_VLAN_UNAWARE_PVID(priv->ds->max_num_bridges)) { 1471751aa5a5SWei Fang struct dsa_port *cpu_dp = np->dp->cpu_dp; 1472751aa5a5SWei Fang 1473751aa5a5SWei Fang vlan_port_bitmap &= ~BIT(cpu_dp->index); 1474751aa5a5SWei Fang } 1475751aa5a5SWei Fang 147684b4a3b3SWei Fang /* If the VLAN only belongs to the current port */ 147784b4a3b3SWei Fang if (vlan_port_bitmap == BIT(port)) { 147884b4a3b3SWei Fang err = ntmp_vft_delete_entry(&priv->ntmp, vid); 147984b4a3b3SWei Fang if (err) 148084b4a3b3SWei Fang goto unlock_vft; 148184b4a3b3SWei Fang 148284b4a3b3SWei Fang netc_delete_vlan_egress_rule(priv, entry); 148384b4a3b3SWei Fang netc_del_vlan_entry(entry); 148484b4a3b3SWei Fang 148584b4a3b3SWei Fang goto unlock_vft; 148684b4a3b3SWei Fang } 148784b4a3b3SWei Fang 148884b4a3b3SWei Fang if (!(vlan_port_bitmap & BIT(port))) 148984b4a3b3SWei Fang goto unlock_vft; 149084b4a3b3SWei Fang 149184b4a3b3SWei Fang cfge->bitmap_stg &= cpu_to_le32(~BIT(port)); 149284b4a3b3SWei Fang err = ntmp_vft_update_entry(&priv->ntmp, vid, cfge); 149384b4a3b3SWei Fang if (err) { 149484b4a3b3SWei Fang cfge->bitmap_stg |= cpu_to_le32(BIT(port)); 149584b4a3b3SWei Fang goto unlock_vft; 149684b4a3b3SWei Fang } 149784b4a3b3SWei Fang 149884b4a3b3SWei Fang unlock_vft: 149984b4a3b3SWei Fang mutex_unlock(&priv->vft_lock); 150084b4a3b3SWei Fang 150184b4a3b3SWei Fang return err; 150284b4a3b3SWei Fang } 150384b4a3b3SWei Fang 150446d64076SWei Fang static int netc_port_enable(struct dsa_switch *ds, int port, 150546d64076SWei Fang struct phy_device *phy) 150646d64076SWei Fang { 150746d64076SWei Fang struct netc_port *np = NETC_PORT(ds, port); 150846d64076SWei Fang int err; 150946d64076SWei Fang 151046d64076SWei Fang if (np->enable) 151146d64076SWei Fang return 0; 151246d64076SWei Fang 151346d64076SWei Fang err = clk_prepare_enable(np->ref_clk); 151446d64076SWei Fang if (err) { 151546d64076SWei Fang dev_err(ds->dev, 151646d64076SWei Fang "Failed to enable enet_ref_clk of port %d\n", port); 151746d64076SWei Fang return err; 151846d64076SWei Fang } 151946d64076SWei Fang 152046d64076SWei Fang np->enable = true; 152146d64076SWei Fang 152246d64076SWei Fang return 0; 152346d64076SWei Fang } 152446d64076SWei Fang 152546d64076SWei Fang static void netc_port_disable(struct dsa_switch *ds, int port) 152646d64076SWei Fang { 152746d64076SWei Fang struct netc_port *np = NETC_PORT(ds, port); 152846d64076SWei Fang 152946d64076SWei Fang /* When .port_disable() is called, .port_enable() may not have been 153046d64076SWei Fang * called. In this case, both the prepare_count and enable_count of 153146d64076SWei Fang * clock are 0. Calling clk_disable_unprepare() at this time will 153246d64076SWei Fang * cause warnings. 153346d64076SWei Fang */ 153446d64076SWei Fang if (!np->enable) 153546d64076SWei Fang return; 153646d64076SWei Fang 153746d64076SWei Fang clk_disable_unprepare(np->ref_clk); 153846d64076SWei Fang np->enable = false; 153946d64076SWei Fang } 154046d64076SWei Fang 154146d64076SWei Fang static void netc_port_stp_state_set(struct dsa_switch *ds, 154246d64076SWei Fang int port, u8 state) 154346d64076SWei Fang { 154446d64076SWei Fang struct netc_port *np = NETC_PORT(ds, port); 154546d64076SWei Fang u32 val; 154646d64076SWei Fang 154746d64076SWei Fang switch (state) { 154846d64076SWei Fang case BR_STATE_DISABLED: 154946d64076SWei Fang case BR_STATE_LISTENING: 155046d64076SWei Fang case BR_STATE_BLOCKING: 155146d64076SWei Fang val = NETC_STG_STATE_DISABLED; 155246d64076SWei Fang break; 155346d64076SWei Fang case BR_STATE_LEARNING: 155446d64076SWei Fang val = NETC_STG_STATE_LEARNING; 155546d64076SWei Fang break; 155646d64076SWei Fang case BR_STATE_FORWARDING: 155746d64076SWei Fang val = NETC_STG_STATE_FORWARDING; 155846d64076SWei Fang break; 155946d64076SWei Fang default: 156046d64076SWei Fang return; 156146d64076SWei Fang } 156246d64076SWei Fang 156346d64076SWei Fang netc_port_wr(np, NETC_BPSTGSR, val); 156446d64076SWei Fang } 156546d64076SWei Fang 156646d64076SWei Fang static int netc_port_change_mtu(struct dsa_switch *ds, 156746d64076SWei Fang int port, int mtu) 156846d64076SWei Fang { 156946d64076SWei Fang u32 max_frame_size = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; 157046d64076SWei Fang 157146d64076SWei Fang netc_port_set_max_frame_size(NETC_PORT(ds, port), max_frame_size); 157246d64076SWei Fang 157346d64076SWei Fang return 0; 157446d64076SWei Fang } 157546d64076SWei Fang 157646d64076SWei Fang static int netc_port_max_mtu(struct dsa_switch *ds, int port) 157746d64076SWei Fang { 157846d64076SWei Fang return NETC_MAX_FRAME_LEN - VLAN_ETH_HLEN - ETH_FCS_LEN; 157946d64076SWei Fang } 158046d64076SWei Fang 1581751aa5a5SWei Fang static struct net_device *netc_classify_db(struct dsa_db db) 1582751aa5a5SWei Fang { 1583751aa5a5SWei Fang switch (db.type) { 1584751aa5a5SWei Fang case DSA_DB_PORT: 1585751aa5a5SWei Fang return NULL; 1586751aa5a5SWei Fang case DSA_DB_BRIDGE: 1587751aa5a5SWei Fang return db.bridge.dev; 1588751aa5a5SWei Fang default: 1589751aa5a5SWei Fang return ERR_PTR(-EOPNOTSUPP); 1590751aa5a5SWei Fang } 1591751aa5a5SWei Fang } 1592751aa5a5SWei Fang 1593751aa5a5SWei Fang static u16 netc_vlan_unaware_pvid(struct dsa_bridge *bridge) 1594751aa5a5SWei Fang { 1595751aa5a5SWei Fang u32 br_num; 1596751aa5a5SWei Fang 1597751aa5a5SWei Fang if (!bridge) 1598751aa5a5SWei Fang return NETC_STANDALONE_PVID; 1599751aa5a5SWei Fang 1600751aa5a5SWei Fang br_num = bridge->num; 1601751aa5a5SWei Fang 1602751aa5a5SWei Fang /* The br_num is supposed to be 1 ~ ds->max_num_bridges, see 1603751aa5a5SWei Fang * dsa_bridge_num_get(). Since max_num_bridges is non-zero, 1604751aa5a5SWei Fang * so dsa_port_bridge_create() will return an error if 1605751aa5a5SWei Fang * dsa_bridge_num_get() returns 0. 1606751aa5a5SWei Fang */ 1607751aa5a5SWei Fang if (WARN_ON(!br_num)) 1608751aa5a5SWei Fang return NETC_STANDALONE_PVID; 1609751aa5a5SWei Fang 1610751aa5a5SWei Fang return NETC_VLAN_UNAWARE_PVID(br_num); 1611751aa5a5SWei Fang } 1612751aa5a5SWei Fang 161346d64076SWei Fang static int netc_port_fdb_add(struct dsa_switch *ds, int port, 161446d64076SWei Fang const unsigned char *addr, u16 vid, 161546d64076SWei Fang struct dsa_db db) 161646d64076SWei Fang { 1617751aa5a5SWei Fang struct net_device *br_ndev = netc_classify_db(db); 161846d64076SWei Fang struct netc_port *np = NETC_PORT(ds, port); 161946d64076SWei Fang 1620751aa5a5SWei Fang if (IS_ERR(br_ndev)) 1621751aa5a5SWei Fang return PTR_ERR(br_ndev); 1622751aa5a5SWei Fang 1623751aa5a5SWei Fang if (!vid) 1624751aa5a5SWei Fang vid = netc_vlan_unaware_pvid(br_ndev ? &db.bridge : NULL); 162546d64076SWei Fang 162646d64076SWei Fang return netc_port_set_fdb_entry(np, addr, vid); 162746d64076SWei Fang } 162846d64076SWei Fang 162946d64076SWei Fang static int netc_port_fdb_del(struct dsa_switch *ds, int port, 163046d64076SWei Fang const unsigned char *addr, u16 vid, 163146d64076SWei Fang struct dsa_db db) 163246d64076SWei Fang { 1633751aa5a5SWei Fang struct net_device *br_ndev = netc_classify_db(db); 163446d64076SWei Fang struct netc_port *np = NETC_PORT(ds, port); 163546d64076SWei Fang 1636751aa5a5SWei Fang if (IS_ERR(br_ndev)) 1637751aa5a5SWei Fang return PTR_ERR(br_ndev); 1638751aa5a5SWei Fang 1639751aa5a5SWei Fang if (!vid) 1640751aa5a5SWei Fang vid = netc_vlan_unaware_pvid(br_ndev ? &db.bridge : NULL); 164146d64076SWei Fang 164246d64076SWei Fang return netc_port_del_fdb_entry(np, addr, vid); 164346d64076SWei Fang } 164446d64076SWei Fang 164546d64076SWei Fang static int netc_port_fdb_dump(struct dsa_switch *ds, int port, 164646d64076SWei Fang dsa_fdb_dump_cb_t *cb, void *data) 164746d64076SWei Fang { 164846d64076SWei Fang struct netc_switch *priv = ds->priv; 164946d64076SWei Fang u32 resume_eid = NTMP_NULL_ENTRY_ID; 165046d64076SWei Fang struct fdbt_entry_data *entry; 165146d64076SWei Fang struct fdbt_keye_data *keye; 165246d64076SWei Fang struct fdbt_cfge_data *cfge; 165346d64076SWei Fang u32 cfg, cnt = 0; 165446d64076SWei Fang bool is_static; 165546d64076SWei Fang int err; 165646d64076SWei Fang u16 vid; 165746d64076SWei Fang 165846d64076SWei Fang entry = kmalloc_obj(*entry); 165946d64076SWei Fang if (!entry) 166046d64076SWei Fang return -ENOMEM; 166146d64076SWei Fang 166246d64076SWei Fang keye = &entry->keye; 166346d64076SWei Fang cfge = &entry->cfge; 166446d64076SWei Fang mutex_lock(&priv->fdbt_lock); 166546d64076SWei Fang 166646d64076SWei Fang do { 166746d64076SWei Fang memset(entry, 0, sizeof(*entry)); 166846d64076SWei Fang err = ntmp_fdbt_search_port_entry(&priv->ntmp, port, 166946d64076SWei Fang &resume_eid, entry); 167046d64076SWei Fang if (err || entry->entry_id == NTMP_NULL_ENTRY_ID) 167146d64076SWei Fang break; 167246d64076SWei Fang 167346d64076SWei Fang cfg = le32_to_cpu(cfge->cfg); 167446d64076SWei Fang is_static = (cfg & FDBT_DYNAMIC) ? false : true; 167546d64076SWei Fang vid = le16_to_cpu(keye->fid); 1676751aa5a5SWei Fang if (vid >= NETC_VLAN_UNAWARE_PVID(ds->max_num_bridges)) 1677751aa5a5SWei Fang vid = 0; 167846d64076SWei Fang 167946d64076SWei Fang err = cb(keye->mac_addr, vid, is_static, data); 168046d64076SWei Fang if (err) 168146d64076SWei Fang break; 168246d64076SWei Fang 168346d64076SWei Fang /* To prevent hardware malfunctions from causing an 168446d64076SWei Fang * infinite loop. 168546d64076SWei Fang */ 168646d64076SWei Fang if (++cnt >= priv->htmcapr_num_words) 168746d64076SWei Fang break; 168846d64076SWei Fang } while (resume_eid != NTMP_NULL_ENTRY_ID); 168946d64076SWei Fang 169046d64076SWei Fang mutex_unlock(&priv->fdbt_lock); 169146d64076SWei Fang kfree(entry); 169246d64076SWei Fang 169346d64076SWei Fang return err; 169446d64076SWei Fang } 169546d64076SWei Fang 169646d64076SWei Fang static int netc_port_mdb_add(struct dsa_switch *ds, int port, 169746d64076SWei Fang const struct switchdev_obj_port_mdb *mdb, 169846d64076SWei Fang struct dsa_db db) 169946d64076SWei Fang { 170046d64076SWei Fang return netc_port_fdb_add(ds, port, mdb->addr, mdb->vid, db); 170146d64076SWei Fang } 170246d64076SWei Fang 170346d64076SWei Fang static int netc_port_mdb_del(struct dsa_switch *ds, int port, 170446d64076SWei Fang const struct switchdev_obj_port_mdb *mdb, 170546d64076SWei Fang struct dsa_db db) 170646d64076SWei Fang { 170746d64076SWei Fang return netc_port_fdb_del(ds, port, mdb->addr, mdb->vid, db); 170846d64076SWei Fang } 170946d64076SWei Fang 171046d64076SWei Fang static int netc_port_add_host_flood_rule(struct netc_port *np, 171146d64076SWei Fang bool uc, bool mc) 171246d64076SWei Fang { 171346d64076SWei Fang const u8 dmac_mask[ETH_ALEN] = {0x1, 0, 0, 0, 0, 0}; 171446d64076SWei Fang struct netc_switch *priv = np->switch_priv; 171546d64076SWei Fang struct ipft_entry_data *host_flood; 171646d64076SWei Fang struct ipft_keye_data *keye; 171746d64076SWei Fang struct ipft_cfge_data *cfge; 171846d64076SWei Fang u16 src_port; 171946d64076SWei Fang u32 cfg; 172046d64076SWei Fang int err; 172146d64076SWei Fang 172246d64076SWei Fang if (!uc && !mc) { 172346d64076SWei Fang /* Disable ingress port filter table lookup */ 172446d64076SWei Fang netc_port_wr(np, NETC_PIPFCR, 0); 172546d64076SWei Fang np->uc = false; 172646d64076SWei Fang np->mc = false; 172746d64076SWei Fang 172846d64076SWei Fang return 0; 172946d64076SWei Fang } 173046d64076SWei Fang 173146d64076SWei Fang host_flood = kzalloc_obj(*host_flood); 173246d64076SWei Fang if (!host_flood) 173346d64076SWei Fang return -ENOMEM; 173446d64076SWei Fang 173546d64076SWei Fang keye = &host_flood->keye; 173646d64076SWei Fang cfge = &host_flood->cfge; 173746d64076SWei Fang 173846d64076SWei Fang src_port = FIELD_PREP(IPFT_SRC_PORT, np->dp->index); 173946d64076SWei Fang src_port |= IPFT_SRC_PORT_MASK; 174046d64076SWei Fang keye->src_port = cpu_to_le16(src_port); 174146d64076SWei Fang 174246d64076SWei Fang /* If either only unicast or only multicast need to be flooded 174346d64076SWei Fang * to the host, we always set the mask that tests the first MAC 174446d64076SWei Fang * DA octet. The value should be 0 for the first bit (if unicast 174546d64076SWei Fang * has to be flooded) or 1 (if multicast). If both unicast and 174646d64076SWei Fang * multicast have to be flooded, we leave the key mask empty, so 174746d64076SWei Fang * it matches everything. 174846d64076SWei Fang */ 174946d64076SWei Fang if (uc && !mc) 175046d64076SWei Fang ether_addr_copy(keye->dmac_mask, dmac_mask); 175146d64076SWei Fang 175246d64076SWei Fang if (!uc && mc) { 175346d64076SWei Fang ether_addr_copy(keye->dmac, dmac_mask); 175446d64076SWei Fang ether_addr_copy(keye->dmac_mask, dmac_mask); 175546d64076SWei Fang } 175646d64076SWei Fang 175746d64076SWei Fang cfg = FIELD_PREP(IPFT_FLTFA, IPFT_FLTFA_REDIRECT); 175846d64076SWei Fang cfg |= FIELD_PREP(IPFT_HR, NETC_HR_HOST_FLOOD); 175946d64076SWei Fang cfge->cfg = cpu_to_le32(cfg); 176046d64076SWei Fang 176146d64076SWei Fang err = ntmp_ipft_add_entry(&priv->ntmp, host_flood); 176246d64076SWei Fang if (err) { 176346d64076SWei Fang kfree(host_flood); 176446d64076SWei Fang return err; 176546d64076SWei Fang } 176646d64076SWei Fang 176746d64076SWei Fang np->uc = uc; 176846d64076SWei Fang np->mc = mc; 176946d64076SWei Fang np->host_flood = host_flood; 177046d64076SWei Fang /* Enable ingress port filter table lookup */ 177146d64076SWei Fang netc_port_wr(np, NETC_PIPFCR, PIPFCR_EN); 177246d64076SWei Fang 177346d64076SWei Fang return 0; 177446d64076SWei Fang } 177546d64076SWei Fang 177646d64076SWei Fang static void netc_port_remove_host_flood(struct netc_port *np, 177746d64076SWei Fang struct ipft_entry_data *host_flood) 177846d64076SWei Fang { 177946d64076SWei Fang struct netc_switch *priv = np->switch_priv; 1780751aa5a5SWei Fang bool disable_host_flood = false; 178146d64076SWei Fang 178246d64076SWei Fang if (!host_flood) 178346d64076SWei Fang return; 178446d64076SWei Fang 1785751aa5a5SWei Fang if (np->host_flood == host_flood) 1786751aa5a5SWei Fang disable_host_flood = true; 1787751aa5a5SWei Fang 178846d64076SWei Fang ntmp_ipft_delete_entry(&priv->ntmp, host_flood->entry_id); 178946d64076SWei Fang kfree(host_flood); 1790751aa5a5SWei Fang 1791751aa5a5SWei Fang if (disable_host_flood) { 1792751aa5a5SWei Fang np->host_flood = NULL; 1793751aa5a5SWei Fang np->uc = false; 1794751aa5a5SWei Fang np->mc = false; 1795751aa5a5SWei Fang netc_port_wr(np, NETC_PIPFCR, 0); 1796751aa5a5SWei Fang } 179746d64076SWei Fang } 179846d64076SWei Fang 179946d64076SWei Fang static void netc_port_set_host_flood(struct dsa_switch *ds, int port, 180046d64076SWei Fang bool uc, bool mc) 180146d64076SWei Fang { 180246d64076SWei Fang struct netc_port *np = NETC_PORT(ds, port); 180346d64076SWei Fang struct ipft_entry_data *old_host_flood; 180446d64076SWei Fang 1805751aa5a5SWei Fang /* Do not add host flood rule to ingress port filter table when 1806751aa5a5SWei Fang * the port has joined a bridge. Otherwise, the ingress frames 1807751aa5a5SWei Fang * will bypass FDB table lookup and MAC learning, so the frames 1808751aa5a5SWei Fang * will be redirected directly to the CPU port. 1809751aa5a5SWei Fang */ 1810751aa5a5SWei Fang if (dsa_port_bridge_dev_get(np->dp)) { 1811751aa5a5SWei Fang netc_port_remove_host_flood(np, np->host_flood); 1812751aa5a5SWei Fang 1813751aa5a5SWei Fang return; 1814751aa5a5SWei Fang } 1815751aa5a5SWei Fang 181646d64076SWei Fang if (np->uc == uc && np->mc == mc) 181746d64076SWei Fang return; 181846d64076SWei Fang 181946d64076SWei Fang /* IPFT does not support in-place updates to the KEYE element, 182046d64076SWei Fang * we need to add a new entry and then delete the old one. So 182146d64076SWei Fang * save the old entry first. 182246d64076SWei Fang */ 182346d64076SWei Fang old_host_flood = np->host_flood; 182446d64076SWei Fang np->host_flood = NULL; 182546d64076SWei Fang 182646d64076SWei Fang if (netc_port_add_host_flood_rule(np, uc, mc)) { 182746d64076SWei Fang np->host_flood = old_host_flood; 182846d64076SWei Fang dev_err(ds->dev, "Failed to add host flood rule on port %d\n", 182946d64076SWei Fang port); 183046d64076SWei Fang return; 183146d64076SWei Fang } 183246d64076SWei Fang 183346d64076SWei Fang /* Remove the old host flood entry */ 183446d64076SWei Fang netc_port_remove_host_flood(np, old_host_flood); 183546d64076SWei Fang } 183646d64076SWei Fang 1837751aa5a5SWei Fang static int netc_single_vlan_aware_bridge(struct dsa_switch *ds, 1838751aa5a5SWei Fang struct netlink_ext_ack *extack) 1839751aa5a5SWei Fang { 1840751aa5a5SWei Fang struct net_device *br_ndev = NULL; 1841751aa5a5SWei Fang struct dsa_port *dp; 1842751aa5a5SWei Fang 1843751aa5a5SWei Fang dsa_switch_for_each_available_port(dp, ds) { 1844751aa5a5SWei Fang struct net_device *port_br = dsa_port_bridge_dev_get(dp); 1845751aa5a5SWei Fang 1846751aa5a5SWei Fang if (!port_br || !br_vlan_enabled(port_br)) 1847751aa5a5SWei Fang continue; 1848751aa5a5SWei Fang 1849751aa5a5SWei Fang if (!br_ndev) { 1850751aa5a5SWei Fang br_ndev = port_br; 1851751aa5a5SWei Fang continue; 1852751aa5a5SWei Fang } 1853751aa5a5SWei Fang 1854751aa5a5SWei Fang if (br_ndev == port_br) 1855751aa5a5SWei Fang continue; 1856751aa5a5SWei Fang 1857751aa5a5SWei Fang NL_SET_ERR_MSG_MOD(extack, 1858751aa5a5SWei Fang "Only one VLAN-aware bridge is supported"); 1859751aa5a5SWei Fang 1860751aa5a5SWei Fang return -EBUSY; 1861751aa5a5SWei Fang } 1862751aa5a5SWei Fang 1863751aa5a5SWei Fang return 0; 1864751aa5a5SWei Fang } 1865751aa5a5SWei Fang 1866751aa5a5SWei Fang static int netc_port_vlan_filtering(struct dsa_switch *ds, 1867751aa5a5SWei Fang int port, bool vlan_aware, 1868751aa5a5SWei Fang struct netlink_ext_ack *extack) 1869751aa5a5SWei Fang { 1870751aa5a5SWei Fang struct netc_port *np = NETC_PORT(ds, port); 1871751aa5a5SWei Fang u16 pvid; 1872751aa5a5SWei Fang int err; 1873751aa5a5SWei Fang 1874751aa5a5SWei Fang /* Before calling port_vlan_filtering(), br_vlan_filter_toggle() has 1875751aa5a5SWei Fang * already updated the BROPT_VLAN_ENABLED bit of br->options. So the 1876751aa5a5SWei Fang * VLAN filtering status of the switch ports can be checked by the 1877751aa5a5SWei Fang * br_vlan_enabled() function. 1878751aa5a5SWei Fang */ 1879751aa5a5SWei Fang err = netc_single_vlan_aware_bridge(ds, extack); 1880751aa5a5SWei Fang if (err) 1881751aa5a5SWei Fang return err; 1882751aa5a5SWei Fang 1883751aa5a5SWei Fang pvid = netc_vlan_unaware_pvid(np->dp->bridge); 1884751aa5a5SWei Fang if (pvid == NETC_STANDALONE_PVID) { 1885751aa5a5SWei Fang vlan_aware = false; 1886751aa5a5SWei Fang goto bpdvr_config; 1887751aa5a5SWei Fang } 1888751aa5a5SWei Fang 1889751aa5a5SWei Fang if (vlan_aware) { 1890751aa5a5SWei Fang /* The FDB entries associated with unaware_pvid do not need 1891751aa5a5SWei Fang * to be deleted, so that when switching from VLAN-aware to 1892751aa5a5SWei Fang * VLAN-unaware mode, these FDB entries do not need to be 1893751aa5a5SWei Fang * re-added. 1894751aa5a5SWei Fang */ 1895751aa5a5SWei Fang err = netc_port_del_vlan_entry(np, pvid); 1896751aa5a5SWei Fang if (err) 1897751aa5a5SWei Fang return err; 1898751aa5a5SWei Fang 1899751aa5a5SWei Fang pvid = np->pvid; 1900751aa5a5SWei Fang } else { 1901751aa5a5SWei Fang err = netc_port_set_vlan_entry(np, pvid, false); 1902751aa5a5SWei Fang if (err) 1903751aa5a5SWei Fang return err; 1904751aa5a5SWei Fang } 1905751aa5a5SWei Fang 1906751aa5a5SWei Fang bpdvr_config: 1907751aa5a5SWei Fang netc_port_set_vlan_aware(np, vlan_aware); 1908751aa5a5SWei Fang netc_port_set_pvid(np, pvid); 1909751aa5a5SWei Fang 1910751aa5a5SWei Fang return 0; 1911751aa5a5SWei Fang } 1912751aa5a5SWei Fang 191384b4a3b3SWei Fang static int netc_port_vlan_add(struct dsa_switch *ds, int port, 191484b4a3b3SWei Fang const struct switchdev_obj_port_vlan *vlan, 191584b4a3b3SWei Fang struct netlink_ext_ack *extack) 191684b4a3b3SWei Fang { 191784b4a3b3SWei Fang struct netc_port *np = NETC_PORT(ds, port); 1918751aa5a5SWei Fang struct dsa_port *dp = np->dp; 191984b4a3b3SWei Fang bool untagged; 1920751aa5a5SWei Fang int err; 192184b4a3b3SWei Fang 192284b4a3b3SWei Fang /* The 8021q layer may attempt to change NETC_STANDALONE_PVID 192384b4a3b3SWei Fang * (VID 0), so we need to ignore it. 192484b4a3b3SWei Fang */ 192584b4a3b3SWei Fang if (vlan->vid == NETC_STANDALONE_PVID) 192684b4a3b3SWei Fang return 0; 192784b4a3b3SWei Fang 1928751aa5a5SWei Fang if (vlan->vid >= NETC_VLAN_UNAWARE_PVID(ds->max_num_bridges)) { 1929751aa5a5SWei Fang NL_SET_ERR_MSG_FMT_MOD(extack, 1930751aa5a5SWei Fang "VID %d~4095 reserved for VLAN-unaware bridge", 1931751aa5a5SWei Fang NETC_VLAN_UNAWARE_PVID(ds->max_num_bridges)); 1932751aa5a5SWei Fang return -EINVAL; 1933751aa5a5SWei Fang } 193484b4a3b3SWei Fang 1935751aa5a5SWei Fang untagged = !!(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED); 1936751aa5a5SWei Fang err = netc_port_set_vlan_entry(np, vlan->vid, untagged); 1937751aa5a5SWei Fang if (err) 1938751aa5a5SWei Fang return err; 1939751aa5a5SWei Fang 1940751aa5a5SWei Fang if (vlan->flags & BRIDGE_VLAN_INFO_PVID) { 1941751aa5a5SWei Fang np->pvid = vlan->vid; 1942751aa5a5SWei Fang if (dsa_port_is_vlan_filtering(dp)) 1943751aa5a5SWei Fang netc_port_set_pvid(np, vlan->vid); 1944751aa5a5SWei Fang 1945751aa5a5SWei Fang return 0; 1946751aa5a5SWei Fang } 1947751aa5a5SWei Fang 1948751aa5a5SWei Fang if (np->pvid != vlan->vid) 1949751aa5a5SWei Fang return 0; 1950751aa5a5SWei Fang 1951751aa5a5SWei Fang /* Delete PVID */ 1952751aa5a5SWei Fang np->pvid = NETC_STANDALONE_PVID; 1953751aa5a5SWei Fang if (dsa_port_is_vlan_filtering(dp)) 1954751aa5a5SWei Fang netc_port_set_pvid(np, NETC_STANDALONE_PVID); 1955751aa5a5SWei Fang 1956751aa5a5SWei Fang return 0; 195784b4a3b3SWei Fang } 195884b4a3b3SWei Fang 195984b4a3b3SWei Fang static int netc_port_vlan_del(struct dsa_switch *ds, int port, 196084b4a3b3SWei Fang const struct switchdev_obj_port_vlan *vlan) 196184b4a3b3SWei Fang { 196284b4a3b3SWei Fang struct netc_port *np = NETC_PORT(ds, port); 1963751aa5a5SWei Fang int err; 196484b4a3b3SWei Fang 196584b4a3b3SWei Fang if (vlan->vid == NETC_STANDALONE_PVID) 196684b4a3b3SWei Fang return 0; 196784b4a3b3SWei Fang 1968751aa5a5SWei Fang if (vlan->vid >= NETC_VLAN_UNAWARE_PVID(ds->max_num_bridges)) 1969751aa5a5SWei Fang return -EINVAL; 1970751aa5a5SWei Fang 1971751aa5a5SWei Fang err = netc_port_del_vlan_entry(np, vlan->vid); 1972751aa5a5SWei Fang if (err) 1973751aa5a5SWei Fang return err; 1974751aa5a5SWei Fang 1975751aa5a5SWei Fang if (np->pvid == vlan->vid) { 1976751aa5a5SWei Fang np->pvid = NETC_STANDALONE_PVID; 1977751aa5a5SWei Fang 1978751aa5a5SWei Fang /* Set the port PVID to NETC_STANDALONE_PVID if the VLAN-aware 1979751aa5a5SWei Fang * bridge port has no PVID. The untagged frames will not be 1980751aa5a5SWei Fang * forwarded to other user ports, as NETC_STANDALONE_PVID VLAN 1981751aa5a5SWei Fang * entry has disabled MAC learning and flooding, and other user 1982751aa5a5SWei Fang * ports do not have FDB entries with NETC_STANDALONE_PVID. 1983751aa5a5SWei Fang */ 1984751aa5a5SWei Fang if (dsa_port_is_vlan_filtering(np->dp)) 1985751aa5a5SWei Fang netc_port_set_pvid(np, NETC_STANDALONE_PVID); 1986751aa5a5SWei Fang } 1987751aa5a5SWei Fang 1988751aa5a5SWei Fang return 0; 1989751aa5a5SWei Fang } 1990751aa5a5SWei Fang 1991751aa5a5SWei Fang static int netc_port_bridge_join(struct dsa_switch *ds, int port, 1992751aa5a5SWei Fang struct dsa_bridge bridge, 1993751aa5a5SWei Fang bool *tx_fwd_offload, 1994751aa5a5SWei Fang struct netlink_ext_ack *extack) 1995751aa5a5SWei Fang { 1996751aa5a5SWei Fang struct netc_port *np = NETC_PORT(ds, port); 1997*05b5ee61SWei Fang struct netc_switch *priv = ds->priv; 1998751aa5a5SWei Fang u16 vlan_unaware_pvid; 1999751aa5a5SWei Fang int err; 2000751aa5a5SWei Fang 2001751aa5a5SWei Fang if (!bridge.num) { 2002751aa5a5SWei Fang NL_SET_ERR_MSG_MOD(extack, "Bridge number 0 is unsupported"); 2003751aa5a5SWei Fang return -EINVAL; 2004751aa5a5SWei Fang } 2005751aa5a5SWei Fang 2006751aa5a5SWei Fang err = netc_single_vlan_aware_bridge(ds, extack); 2007751aa5a5SWei Fang if (err) 2008751aa5a5SWei Fang return err; 2009751aa5a5SWei Fang 2010751aa5a5SWei Fang netc_port_set_mlo(np, MLO_NOT_OVERRIDE); 2011751aa5a5SWei Fang 2012751aa5a5SWei Fang if (br_vlan_enabled(bridge.dev)) 2013751aa5a5SWei Fang goto out; 2014751aa5a5SWei Fang 2015751aa5a5SWei Fang vlan_unaware_pvid = NETC_VLAN_UNAWARE_PVID(bridge.num); 2016751aa5a5SWei Fang err = netc_port_set_vlan_entry(np, vlan_unaware_pvid, false); 2017751aa5a5SWei Fang if (err) 2018751aa5a5SWei Fang goto disable_mlo; 2019751aa5a5SWei Fang 2020751aa5a5SWei Fang netc_port_set_pvid(np, vlan_unaware_pvid); 2021751aa5a5SWei Fang 2022751aa5a5SWei Fang out: 2023751aa5a5SWei Fang netc_port_remove_host_flood(np, np->host_flood); 2024751aa5a5SWei Fang 2025*05b5ee61SWei Fang if (atomic_inc_return(&priv->br_cnt) == 1) 2026*05b5ee61SWei Fang schedule_delayed_work(&priv->fdbt_ageing_work, 2027*05b5ee61SWei Fang READ_ONCE(priv->fdbt_ageing_delay)); 2028*05b5ee61SWei Fang 2029751aa5a5SWei Fang return 0; 2030751aa5a5SWei Fang 2031751aa5a5SWei Fang disable_mlo: 2032751aa5a5SWei Fang netc_port_set_mlo(np, MLO_DISABLE); 2033751aa5a5SWei Fang 2034751aa5a5SWei Fang return err; 2035751aa5a5SWei Fang } 2036751aa5a5SWei Fang 2037751aa5a5SWei Fang static void netc_port_remove_dynamic_entries(struct netc_port *np) 2038751aa5a5SWei Fang { 2039751aa5a5SWei Fang struct netc_switch *priv = np->switch_priv; 2040751aa5a5SWei Fang 2041751aa5a5SWei Fang /* Return if the port is not available */ 2042751aa5a5SWei Fang if (!np->dp) 2043751aa5a5SWei Fang return; 2044751aa5a5SWei Fang 2045751aa5a5SWei Fang mutex_lock(&priv->fdbt_lock); 2046751aa5a5SWei Fang ntmp_fdbt_delete_port_dynamic_entries(&priv->ntmp, np->dp->index); 2047751aa5a5SWei Fang mutex_unlock(&priv->fdbt_lock); 2048751aa5a5SWei Fang } 2049751aa5a5SWei Fang 2050751aa5a5SWei Fang static void netc_port_bridge_leave(struct dsa_switch *ds, int port, 2051751aa5a5SWei Fang struct dsa_bridge bridge) 2052751aa5a5SWei Fang { 2053751aa5a5SWei Fang struct netc_port *np = NETC_PORT(ds, port); 2054751aa5a5SWei Fang struct net_device *ndev = np->dp->user; 2055*05b5ee61SWei Fang struct netc_switch *priv = ds->priv; 2056751aa5a5SWei Fang u16 vlan_unaware_pvid; 2057751aa5a5SWei Fang bool mc, uc; 2058751aa5a5SWei Fang 2059751aa5a5SWei Fang netc_port_set_mlo(np, MLO_DISABLE); 2060751aa5a5SWei Fang netc_port_set_pvid(np, NETC_STANDALONE_PVID); 2061751aa5a5SWei Fang np->pvid = NETC_STANDALONE_PVID; 2062751aa5a5SWei Fang 2063*05b5ee61SWei Fang if (atomic_dec_and_test(&priv->br_cnt)) 2064*05b5ee61SWei Fang cancel_delayed_work_sync(&priv->fdbt_ageing_work); 2065*05b5ee61SWei Fang 2066751aa5a5SWei Fang netc_port_remove_dynamic_entries(np); 2067751aa5a5SWei Fang uc = ndev->flags & IFF_PROMISC; 2068751aa5a5SWei Fang mc = ndev->flags & (IFF_PROMISC | IFF_ALLMULTI); 2069751aa5a5SWei Fang 2070751aa5a5SWei Fang if (netc_port_add_host_flood_rule(np, uc, mc)) 2071751aa5a5SWei Fang dev_warn(ds->dev, 2072751aa5a5SWei Fang "Failed to restore host flood rule on port %d\n", 2073751aa5a5SWei Fang port); 2074751aa5a5SWei Fang 2075751aa5a5SWei Fang /* When a port leaves a VLAN-aware bridge, dsa_port_bridge_leave() 2076751aa5a5SWei Fang * follows the sequence below: 2077751aa5a5SWei Fang * 2078751aa5a5SWei Fang * 1. dsa_port_bridge_destroy() is called to set dp->bridge to NULL. 2079751aa5a5SWei Fang * 2. dsa_broadcast() is called, which eventually invokes 2080751aa5a5SWei Fang * ds->ops->port_bridge_leave() 2081751aa5a5SWei Fang * 3. dsa_port_switchdev_unsync_attrs() is called, which triggers 2082751aa5a5SWei Fang * dsa_port_reset_vlan_filtering() and ultimately calls 2083751aa5a5SWei Fang * ds->ops->port_vlan_filtering() to transition the port from 2084751aa5a5SWei Fang * VLAN-aware mode to VLAN-unaware mode. 2085751aa5a5SWei Fang * 2086751aa5a5SWei Fang * At step 3, since dp->bridge has already been set to NULL in step 1, 2087751aa5a5SWei Fang * netc_port_vlan_filtering() will detect this and skip the creation 2088751aa5a5SWei Fang * of an unaware PVID entry in the VLAN filter table. Therefore, it is 2089751aa5a5SWei Fang * safe to return directly here. 2090751aa5a5SWei Fang */ 2091751aa5a5SWei Fang if (br_vlan_enabled(bridge.dev)) 2092751aa5a5SWei Fang return; 2093751aa5a5SWei Fang 2094751aa5a5SWei Fang vlan_unaware_pvid = NETC_VLAN_UNAWARE_PVID(bridge.num); 2095751aa5a5SWei Fang /* There is no need to check the return value even if it fails. 2096751aa5a5SWei Fang * Because the PVID has been set to NETC_STANDALONE_PVID, the 2097751aa5a5SWei Fang * frames will not match this VLAN entry. 2098751aa5a5SWei Fang */ 2099751aa5a5SWei Fang netc_port_del_vlan_entry(np, vlan_unaware_pvid); 2100751aa5a5SWei Fang } 2101751aa5a5SWei Fang 2102*05b5ee61SWei Fang static int netc_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) 2103*05b5ee61SWei Fang { 2104*05b5ee61SWei Fang struct netc_switch *priv = ds->priv; 2105*05b5ee61SWei Fang unsigned long delay_jiffies; 2106*05b5ee61SWei Fang 2107*05b5ee61SWei Fang /* The dynamic FDB entry is deleted when its activity counter reaches 2108*05b5ee61SWei Fang * NETC_FDBT_AGEING_THRESH (100). Each delayed_work tick increments 2109*05b5ee61SWei Fang * the counter by 1 if the entry is inactive. 2110*05b5ee61SWei Fang * 2111*05b5ee61SWei Fang * Therefore: 2112*05b5ee61SWei Fang * msecs (ms) = NETC_FDBT_AGEING_THRESH * delay_ms (ms) 2113*05b5ee61SWei Fang * delay_ms = msecs / NETC_FDBT_AGEING_THRESH 2114*05b5ee61SWei Fang * delay_jiffies = (delay_ms / 1000) * HZ 2115*05b5ee61SWei Fang * = (msecs * HZ) / (1000 * NETC_FDBT_AGEING_THRESH) 2116*05b5ee61SWei Fang * 2117*05b5ee61SWei Fang * Use DIV_ROUND_CLOSEST_ULL to perform a single nearest-jiffy 2118*05b5ee61SWei Fang * rounding, avoiding the two-step rounding error of the intermediate 2119*05b5ee61SWei Fang * delay_ms approach. 2120*05b5ee61SWei Fang * Maximum error = +/-0.5 jiffy * 100 = +/-50000/HZ ms. 2121*05b5ee61SWei Fang */ 2122*05b5ee61SWei Fang delay_jiffies = DIV_ROUND_CLOSEST_ULL((u64)msecs * HZ, 2123*05b5ee61SWei Fang 1000 * NETC_FDBT_AGEING_THRESH); 2124*05b5ee61SWei Fang WRITE_ONCE(priv->fdbt_ageing_delay, delay_jiffies); 2125*05b5ee61SWei Fang 2126*05b5ee61SWei Fang if (atomic_read(&priv->br_cnt)) 2127*05b5ee61SWei Fang mod_delayed_work(system_percpu_wq, &priv->fdbt_ageing_work, 2128*05b5ee61SWei Fang READ_ONCE(priv->fdbt_ageing_delay)); 2129*05b5ee61SWei Fang 2130*05b5ee61SWei Fang return 0; 2131*05b5ee61SWei Fang } 2132*05b5ee61SWei Fang 2133751aa5a5SWei Fang static void netc_port_fast_age(struct dsa_switch *ds, int port) 2134751aa5a5SWei Fang { 2135751aa5a5SWei Fang struct netc_port *np = NETC_PORT(ds, port); 2136751aa5a5SWei Fang 2137751aa5a5SWei Fang netc_port_remove_dynamic_entries(np); 213884b4a3b3SWei Fang } 213984b4a3b3SWei Fang 2140bbe97e34SWei Fang static void netc_phylink_get_caps(struct dsa_switch *ds, int port, 2141bbe97e34SWei Fang struct phylink_config *config) 2142bbe97e34SWei Fang { 2143bbe97e34SWei Fang struct netc_switch *priv = ds->priv; 2144bbe97e34SWei Fang 2145bbe97e34SWei Fang priv->info->phylink_get_caps(port, config); 2146bbe97e34SWei Fang } 2147bbe97e34SWei Fang 2148bbe97e34SWei Fang static void netc_port_set_mac_mode(struct netc_port *np, 2149bbe97e34SWei Fang unsigned int mode, 2150bbe97e34SWei Fang phy_interface_t phy_mode) 2151bbe97e34SWei Fang { 2152bbe97e34SWei Fang u32 mask = PM_IF_MODE_IFMODE | PM_IF_MODE_REVMII; 2153bbe97e34SWei Fang u32 val = 0; 2154bbe97e34SWei Fang 2155bbe97e34SWei Fang switch (phy_mode) { 2156bbe97e34SWei Fang case PHY_INTERFACE_MODE_RGMII: 2157bbe97e34SWei Fang case PHY_INTERFACE_MODE_RGMII_ID: 2158bbe97e34SWei Fang case PHY_INTERFACE_MODE_RGMII_RXID: 2159bbe97e34SWei Fang case PHY_INTERFACE_MODE_RGMII_TXID: 2160bbe97e34SWei Fang val |= IFMODE_RGMII; 2161bbe97e34SWei Fang break; 2162bbe97e34SWei Fang case PHY_INTERFACE_MODE_RMII: 2163bbe97e34SWei Fang val |= IFMODE_RMII; 2164bbe97e34SWei Fang break; 2165bbe97e34SWei Fang case PHY_INTERFACE_MODE_REVMII: 2166bbe97e34SWei Fang val |= PM_IF_MODE_REVMII; 2167bbe97e34SWei Fang fallthrough; 2168bbe97e34SWei Fang case PHY_INTERFACE_MODE_MII: 2169bbe97e34SWei Fang val |= IFMODE_MII; 2170bbe97e34SWei Fang break; 2171bbe97e34SWei Fang case PHY_INTERFACE_MODE_SGMII: 2172bbe97e34SWei Fang case PHY_INTERFACE_MODE_2500BASEX: 2173bbe97e34SWei Fang val |= IFMODE_SGMII; 2174bbe97e34SWei Fang break; 2175bbe97e34SWei Fang default: 2176bbe97e34SWei Fang break; 2177bbe97e34SWei Fang } 2178bbe97e34SWei Fang 2179bbe97e34SWei Fang netc_mac_port_rmw(np, NETC_PM_IF_MODE(0), mask, val); 2180bbe97e34SWei Fang } 2181bbe97e34SWei Fang 2182bbe97e34SWei Fang static void netc_mac_config(struct phylink_config *config, unsigned int mode, 2183bbe97e34SWei Fang const struct phylink_link_state *state) 2184bbe97e34SWei Fang { 2185bbe97e34SWei Fang struct dsa_port *dp = dsa_phylink_to_port(config); 2186bbe97e34SWei Fang 2187bbe97e34SWei Fang netc_port_set_mac_mode(NETC_PORT(dp->ds, dp->index), mode, 2188bbe97e34SWei Fang state->interface); 2189bbe97e34SWei Fang } 2190bbe97e34SWei Fang 2191bbe97e34SWei Fang static void netc_port_set_speed(struct netc_port *np, int speed) 2192bbe97e34SWei Fang { 2193bbe97e34SWei Fang netc_port_rmw(np, NETC_PCR, PCR_PSPEED, PSPEED_SET_VAL(speed)); 2194bbe97e34SWei Fang } 2195bbe97e34SWei Fang 2196bbe97e34SWei Fang static void netc_port_set_rgmii_mac(struct netc_port *np, 2197bbe97e34SWei Fang int speed, int duplex) 2198bbe97e34SWei Fang { 2199bbe97e34SWei Fang u32 mask, val; 2200bbe97e34SWei Fang 2201bbe97e34SWei Fang mask = PM_IF_MODE_SSP | PM_IF_MODE_HD | PM_IF_MODE_M10; 2202bbe97e34SWei Fang 2203bbe97e34SWei Fang switch (speed) { 2204bbe97e34SWei Fang default: 2205bbe97e34SWei Fang case SPEED_1000: 2206bbe97e34SWei Fang val = FIELD_PREP(PM_IF_MODE_SSP, SSP_1G); 2207bbe97e34SWei Fang break; 2208bbe97e34SWei Fang case SPEED_100: 2209bbe97e34SWei Fang val = FIELD_PREP(PM_IF_MODE_SSP, SSP_100M); 2210bbe97e34SWei Fang break; 2211bbe97e34SWei Fang case SPEED_10: 2212bbe97e34SWei Fang val = FIELD_PREP(PM_IF_MODE_SSP, SSP_10M); 2213bbe97e34SWei Fang break; 2214bbe97e34SWei Fang } 2215bbe97e34SWei Fang 2216bbe97e34SWei Fang if (duplex != DUPLEX_FULL) 2217bbe97e34SWei Fang val |= PM_IF_MODE_HD; 2218bbe97e34SWei Fang 2219bbe97e34SWei Fang netc_mac_port_rmw(np, NETC_PM_IF_MODE(0), mask, val); 2220bbe97e34SWei Fang } 2221bbe97e34SWei Fang 2222bbe97e34SWei Fang static void netc_port_set_rmii_mii_mac(struct netc_port *np, 2223bbe97e34SWei Fang int speed, int duplex) 2224bbe97e34SWei Fang { 2225bbe97e34SWei Fang u32 mask, val = 0; 2226bbe97e34SWei Fang 2227bbe97e34SWei Fang mask = PM_IF_MODE_SSP | PM_IF_MODE_HD | PM_IF_MODE_M10; 2228bbe97e34SWei Fang 2229bbe97e34SWei Fang if (speed == SPEED_10) 2230bbe97e34SWei Fang val |= PM_IF_MODE_M10; 2231bbe97e34SWei Fang 2232bbe97e34SWei Fang if (duplex != DUPLEX_FULL) 2233bbe97e34SWei Fang val |= PM_IF_MODE_HD; 2234bbe97e34SWei Fang 2235bbe97e34SWei Fang netc_mac_port_rmw(np, NETC_PM_IF_MODE(0), mask, val); 2236bbe97e34SWei Fang } 2237bbe97e34SWei Fang 2238a5ccb7f5SWei Fang static void netc_port_set_tx_pause(struct netc_port *np, bool tx_pause) 2239a5ccb7f5SWei Fang { 2240a5ccb7f5SWei Fang struct netc_switch *priv = np->switch_priv; 2241a5ccb7f5SWei Fang int port = np->dp->index; 2242a5ccb7f5SWei Fang int i, j, num_bp; 2243a5ccb7f5SWei Fang 2244a5ccb7f5SWei Fang num_bp = priv->num_bp / priv->info->num_ports; 2245a5ccb7f5SWei Fang for (i = 0, j = port * num_bp; i < num_bp; i++, j++) { 2246a5ccb7f5SWei Fang struct bpt_cfge_data *cfge = &priv->bpt_list[j]; 2247a5ccb7f5SWei Fang struct bpt_cfge_data old_cfge = *cfge; 2248a5ccb7f5SWei Fang 2249a5ccb7f5SWei Fang if (tx_pause) { 2250a5ccb7f5SWei Fang cfge->fc_on_thresh = cpu_to_le16(NETC_FC_THRESH_ON); 2251a5ccb7f5SWei Fang cfge->fc_off_thresh = cpu_to_le16(NETC_FC_THRESH_OFF); 2252a5ccb7f5SWei Fang cfge->fccfg_sbpen = FIELD_PREP(BPT_FC_CFG, 2253a5ccb7f5SWei Fang BPT_FC_CFG_EN_BPFC); 2254a5ccb7f5SWei Fang cfge->fc_ports = cpu_to_le32(BIT(port)); 2255a5ccb7f5SWei Fang } else { 2256a5ccb7f5SWei Fang cfge->fc_on_thresh = cpu_to_le16(0); 2257a5ccb7f5SWei Fang cfge->fc_off_thresh = cpu_to_le16(0); 2258a5ccb7f5SWei Fang cfge->fccfg_sbpen = 0; 2259a5ccb7f5SWei Fang cfge->fc_ports = cpu_to_le32(0); 2260a5ccb7f5SWei Fang } 2261a5ccb7f5SWei Fang 2262a5ccb7f5SWei Fang if (ntmp_bpt_update_entry(&priv->ntmp, j, cfge)) { 2263a5ccb7f5SWei Fang *cfge = old_cfge; 2264a5ccb7f5SWei Fang dev_warn(priv->dev, 2265a5ccb7f5SWei Fang "Failed to %s TX pause of buffer pool %d (swp%d)\n", 2266a5ccb7f5SWei Fang tx_pause ? "enable" : "disable", j, port); 2267a5ccb7f5SWei Fang } 2268a5ccb7f5SWei Fang } 2269a5ccb7f5SWei Fang } 2270a5ccb7f5SWei Fang 2271a5ccb7f5SWei Fang static void netc_port_set_rx_pause(struct netc_port *np, bool rx_pause) 2272a5ccb7f5SWei Fang { 2273a5ccb7f5SWei Fang netc_mac_port_rmw(np, NETC_PM_CMD_CFG(0), PM_CMD_CFG_PAUSE_IGN, 2274a5ccb7f5SWei Fang rx_pause ? 0 : PM_CMD_CFG_PAUSE_IGN); 2275a5ccb7f5SWei Fang } 2276a5ccb7f5SWei Fang 2277bbe97e34SWei Fang static void netc_port_mac_rx_enable(struct netc_port *np) 2278bbe97e34SWei Fang { 2279bbe97e34SWei Fang netc_port_rmw(np, NETC_POR, POR_RXDIS, 0); 2280bbe97e34SWei Fang netc_mac_port_rmw(np, NETC_PM_CMD_CFG(0), PM_CMD_CFG_RX_EN, 2281bbe97e34SWei Fang PM_CMD_CFG_RX_EN); 2282bbe97e34SWei Fang } 2283bbe97e34SWei Fang 2284bbe97e34SWei Fang static void netc_port_wait_rx_empty(struct netc_port *np, int mac) 2285bbe97e34SWei Fang { 2286bbe97e34SWei Fang u32 val; 2287bbe97e34SWei Fang 2288bbe97e34SWei Fang /* PM_IEVENT_RX_EMPTY is a read-only bit, it is automatically set by 2289bbe97e34SWei Fang * hardware if RX FIFO is empty and no RX packet receive in process. 2290bbe97e34SWei Fang * And it is automatically cleared if RX FIFO is not empty or RX 2291bbe97e34SWei Fang * packet receive in process. 2292bbe97e34SWei Fang */ 2293bbe97e34SWei Fang if (read_poll_timeout(netc_port_rd, val, val & PM_IEVENT_RX_EMPTY, 2294bbe97e34SWei Fang 100, 10000, false, np, NETC_PM_IEVENT(mac))) 2295bbe97e34SWei Fang dev_warn(np->switch_priv->dev, 2296bbe97e34SWei Fang "swp%d MAC%d: RX is not idle\n", np->dp->index, mac); 2297bbe97e34SWei Fang } 2298bbe97e34SWei Fang 2299bbe97e34SWei Fang static void netc_port_mac_rx_graceful_stop(struct netc_port *np) 2300bbe97e34SWei Fang { 2301bbe97e34SWei Fang u32 val; 2302bbe97e34SWei Fang 2303bbe97e34SWei Fang if (is_netc_pseudo_port(np)) 2304bbe97e34SWei Fang goto rx_disable; 2305bbe97e34SWei Fang 2306bbe97e34SWei Fang if (np->caps.pmac) { 2307bbe97e34SWei Fang netc_port_rmw(np, NETC_PM_CMD_CFG(1), PM_CMD_CFG_RX_EN, 0); 2308bbe97e34SWei Fang netc_port_wait_rx_empty(np, 1); 2309bbe97e34SWei Fang } 2310bbe97e34SWei Fang 2311bbe97e34SWei Fang netc_port_rmw(np, NETC_PM_CMD_CFG(0), PM_CMD_CFG_RX_EN, 0); 2312bbe97e34SWei Fang netc_port_wait_rx_empty(np, 0); 2313bbe97e34SWei Fang 2314bbe97e34SWei Fang if (read_poll_timeout(netc_port_rd, val, !(val & PSR_RX_BUSY), 2315bbe97e34SWei Fang 100, 10000, false, np, NETC_PSR)) 2316bbe97e34SWei Fang dev_warn(np->switch_priv->dev, "swp%d RX is busy\n", 2317bbe97e34SWei Fang np->dp->index); 2318bbe97e34SWei Fang 2319bbe97e34SWei Fang rx_disable: 2320bbe97e34SWei Fang netc_port_rmw(np, NETC_POR, POR_RXDIS, POR_RXDIS); 2321bbe97e34SWei Fang } 2322bbe97e34SWei Fang 2323bbe97e34SWei Fang static void netc_port_mac_tx_enable(struct netc_port *np) 2324bbe97e34SWei Fang { 2325bbe97e34SWei Fang netc_mac_port_rmw(np, NETC_PM_CMD_CFG(0), PM_CMD_CFG_TX_EN, 2326bbe97e34SWei Fang PM_CMD_CFG_TX_EN); 2327bbe97e34SWei Fang netc_port_rmw(np, NETC_POR, POR_TXDIS, 0); 2328bbe97e34SWei Fang } 2329bbe97e34SWei Fang 2330bbe97e34SWei Fang static void netc_port_wait_tx_empty(struct netc_port *np, int mac) 2331bbe97e34SWei Fang { 2332bbe97e34SWei Fang u32 val; 2333bbe97e34SWei Fang 2334bbe97e34SWei Fang /* PM_IEVENT_TX_EMPTY is a read-only bit, it is automatically set by 2335bbe97e34SWei Fang * hardware if TX FIFO is empty. And it is automatically cleared if 2336bbe97e34SWei Fang * TX FIFO is not empty. 2337bbe97e34SWei Fang */ 2338bbe97e34SWei Fang if (read_poll_timeout(netc_port_rd, val, val & PM_IEVENT_TX_EMPTY, 2339bbe97e34SWei Fang 100, 10000, false, np, NETC_PM_IEVENT(mac))) 2340bbe97e34SWei Fang dev_warn(np->switch_priv->dev, 2341bbe97e34SWei Fang "swp%d MAC%d: TX FIFO is not empty\n", 2342bbe97e34SWei Fang np->dp->index, mac); 2343bbe97e34SWei Fang } 2344bbe97e34SWei Fang 2345bbe97e34SWei Fang static void netc_port_mac_tx_graceful_stop(struct netc_port *np) 2346bbe97e34SWei Fang { 2347bbe97e34SWei Fang netc_port_rmw(np, NETC_POR, POR_TXDIS, POR_TXDIS); 2348bbe97e34SWei Fang 2349bbe97e34SWei Fang if (is_netc_pseudo_port(np)) 2350bbe97e34SWei Fang return; 2351bbe97e34SWei Fang 2352bbe97e34SWei Fang netc_port_wait_tx_empty(np, 0); 2353bbe97e34SWei Fang if (np->caps.pmac) 2354bbe97e34SWei Fang netc_port_wait_tx_empty(np, 1); 2355bbe97e34SWei Fang 2356bbe97e34SWei Fang netc_mac_port_rmw(np, NETC_PM_CMD_CFG(0), PM_CMD_CFG_TX_EN, 0); 2357bbe97e34SWei Fang } 2358bbe97e34SWei Fang 2359bbe97e34SWei Fang static void netc_mac_link_up(struct phylink_config *config, 2360bbe97e34SWei Fang struct phy_device *phy, unsigned int mode, 2361bbe97e34SWei Fang phy_interface_t interface, int speed, 2362bbe97e34SWei Fang int duplex, bool tx_pause, bool rx_pause) 2363bbe97e34SWei Fang { 2364bbe97e34SWei Fang struct dsa_port *dp = dsa_phylink_to_port(config); 2365bbe97e34SWei Fang struct netc_port *np; 2366bbe97e34SWei Fang 2367bbe97e34SWei Fang np = NETC_PORT(dp->ds, dp->index); 2368bbe97e34SWei Fang netc_port_set_speed(np, speed); 2369bbe97e34SWei Fang 2370bbe97e34SWei Fang if (phy_interface_mode_is_rgmii(interface)) 2371bbe97e34SWei Fang netc_port_set_rgmii_mac(np, speed, duplex); 2372bbe97e34SWei Fang 2373bbe97e34SWei Fang if (interface == PHY_INTERFACE_MODE_RMII || 2374bbe97e34SWei Fang interface == PHY_INTERFACE_MODE_REVMII || 2375bbe97e34SWei Fang interface == PHY_INTERFACE_MODE_MII) 2376bbe97e34SWei Fang netc_port_set_rmii_mii_mac(np, speed, duplex); 2377bbe97e34SWei Fang 2378a5ccb7f5SWei Fang netc_port_set_tx_pause(np, tx_pause); 2379a5ccb7f5SWei Fang netc_port_set_rx_pause(np, rx_pause); 2380bbe97e34SWei Fang netc_port_mac_tx_enable(np); 2381bbe97e34SWei Fang netc_port_mac_rx_enable(np); 2382bbe97e34SWei Fang } 2383bbe97e34SWei Fang 2384bbe97e34SWei Fang static void netc_mac_link_down(struct phylink_config *config, 2385bbe97e34SWei Fang unsigned int mode, 2386bbe97e34SWei Fang phy_interface_t interface) 2387bbe97e34SWei Fang { 2388bbe97e34SWei Fang struct dsa_port *dp = dsa_phylink_to_port(config); 2389bbe97e34SWei Fang struct netc_port *np; 2390bbe97e34SWei Fang 2391bbe97e34SWei Fang np = NETC_PORT(dp->ds, dp->index); 2392bbe97e34SWei Fang netc_port_mac_rx_graceful_stop(np); 2393bbe97e34SWei Fang netc_port_mac_tx_graceful_stop(np); 2394751aa5a5SWei Fang netc_port_remove_dynamic_entries(np); 2395bbe97e34SWei Fang } 2396bbe97e34SWei Fang 2397bbe97e34SWei Fang static const struct phylink_mac_ops netc_phylink_mac_ops = { 2398bbe97e34SWei Fang .mac_config = netc_mac_config, 2399bbe97e34SWei Fang .mac_link_up = netc_mac_link_up, 2400bbe97e34SWei Fang .mac_link_down = netc_mac_link_down, 2401bbe97e34SWei Fang }; 2402bbe97e34SWei Fang 2403187fbae0SWei Fang static const struct dsa_switch_ops netc_switch_ops = { 2404187fbae0SWei Fang .get_tag_protocol = netc_get_tag_protocol, 2405187fbae0SWei Fang .setup = netc_setup, 2406187fbae0SWei Fang .teardown = netc_teardown, 2407bbe97e34SWei Fang .phylink_get_caps = netc_phylink_get_caps, 240846d64076SWei Fang .port_enable = netc_port_enable, 240946d64076SWei Fang .port_disable = netc_port_disable, 241046d64076SWei Fang .port_stp_state_set = netc_port_stp_state_set, 241146d64076SWei Fang .port_change_mtu = netc_port_change_mtu, 241246d64076SWei Fang .port_max_mtu = netc_port_max_mtu, 241346d64076SWei Fang .port_fdb_add = netc_port_fdb_add, 241446d64076SWei Fang .port_fdb_del = netc_port_fdb_del, 241546d64076SWei Fang .port_fdb_dump = netc_port_fdb_dump, 241646d64076SWei Fang .port_mdb_add = netc_port_mdb_add, 241746d64076SWei Fang .port_mdb_del = netc_port_mdb_del, 241846d64076SWei Fang .port_set_host_flood = netc_port_set_host_flood, 2419751aa5a5SWei Fang .port_vlan_filtering = netc_port_vlan_filtering, 242084b4a3b3SWei Fang .port_vlan_add = netc_port_vlan_add, 242184b4a3b3SWei Fang .port_vlan_del = netc_port_vlan_del, 2422751aa5a5SWei Fang .port_bridge_join = netc_port_bridge_join, 2423751aa5a5SWei Fang .port_bridge_leave = netc_port_bridge_leave, 2424*05b5ee61SWei Fang .set_ageing_time = netc_set_ageing_time, 2425751aa5a5SWei Fang .port_fast_age = netc_port_fast_age, 242625049d8bSWei Fang .get_pause_stats = netc_port_get_pause_stats, 242725049d8bSWei Fang .get_rmon_stats = netc_port_get_rmon_stats, 242825049d8bSWei Fang .get_eth_ctrl_stats = netc_port_get_eth_ctrl_stats, 242925049d8bSWei Fang .get_eth_mac_stats = netc_port_get_eth_mac_stats, 2430beb0e54fSWei Fang .get_sset_count = netc_port_get_sset_count, 2431beb0e54fSWei Fang .get_strings = netc_port_get_strings, 2432beb0e54fSWei Fang .get_ethtool_stats = netc_port_get_ethtool_stats, 2433187fbae0SWei Fang }; 2434187fbae0SWei Fang 2435187fbae0SWei Fang static int netc_switch_probe(struct pci_dev *pdev, 2436187fbae0SWei Fang const struct pci_device_id *id) 2437187fbae0SWei Fang { 2438187fbae0SWei Fang struct device_node *node = dev_of_node(&pdev->dev); 2439187fbae0SWei Fang struct device *dev = &pdev->dev; 2440187fbae0SWei Fang struct netc_switch *priv; 2441187fbae0SWei Fang struct dsa_switch *ds; 2442187fbae0SWei Fang int err; 2443187fbae0SWei Fang 2444187fbae0SWei Fang if (!node) 2445187fbae0SWei Fang return dev_err_probe(dev, -ENODEV, 2446187fbae0SWei Fang "No DT bindings, skipping\n"); 2447187fbae0SWei Fang 2448187fbae0SWei Fang err = netc_switch_check_emdio_is_ready(dev); 2449187fbae0SWei Fang if (err) 2450187fbae0SWei Fang return err; 2451187fbae0SWei Fang 2452187fbae0SWei Fang err = netc_switch_pci_init(pdev); 2453187fbae0SWei Fang if (err) 2454187fbae0SWei Fang return err; 2455187fbae0SWei Fang 2456187fbae0SWei Fang priv = pci_get_drvdata(pdev); 2457187fbae0SWei Fang netc_switch_get_ip_revision(priv); 2458187fbae0SWei Fang 2459187fbae0SWei Fang err = netc_switch_platform_probe(priv); 2460187fbae0SWei Fang if (err) 2461187fbae0SWei Fang return err; 2462187fbae0SWei Fang 2463187fbae0SWei Fang ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL); 2464187fbae0SWei Fang if (!ds) 2465187fbae0SWei Fang return -ENOMEM; 2466187fbae0SWei Fang 2467187fbae0SWei Fang ds->dev = dev; 2468187fbae0SWei Fang ds->num_ports = priv->info->num_ports; 2469187fbae0SWei Fang ds->num_tx_queues = NETC_TC_NUM; 2470187fbae0SWei Fang ds->ops = &netc_switch_ops; 2471bbe97e34SWei Fang ds->phylink_mac_ops = &netc_phylink_mac_ops; 247246d64076SWei Fang ds->fdb_isolation = true; 2473751aa5a5SWei Fang ds->max_num_bridges = priv->info->num_ports - 1; 2474*05b5ee61SWei Fang ds->ageing_time_min = 1000; 2475*05b5ee61SWei Fang ds->ageing_time_max = U32_MAX; 2476187fbae0SWei Fang ds->priv = priv; 2477187fbae0SWei Fang priv->ds = ds; 2478187fbae0SWei Fang 2479187fbae0SWei Fang err = dsa_register_switch(ds); 2480187fbae0SWei Fang if (err) 2481187fbae0SWei Fang return dev_err_probe(dev, err, 2482187fbae0SWei Fang "Failed to register DSA switch\n"); 2483187fbae0SWei Fang 2484187fbae0SWei Fang return 0; 2485187fbae0SWei Fang } 2486187fbae0SWei Fang 2487187fbae0SWei Fang static void netc_switch_remove(struct pci_dev *pdev) 2488187fbae0SWei Fang { 2489187fbae0SWei Fang struct netc_switch *priv = pci_get_drvdata(pdev); 2490187fbae0SWei Fang 2491187fbae0SWei Fang if (!priv) 2492187fbae0SWei Fang return; 2493187fbae0SWei Fang 2494187fbae0SWei Fang dsa_unregister_switch(priv->ds); 2495187fbae0SWei Fang } 2496187fbae0SWei Fang 2497187fbae0SWei Fang static void netc_switch_shutdown(struct pci_dev *pdev) 2498187fbae0SWei Fang { 2499187fbae0SWei Fang struct netc_switch *priv = pci_get_drvdata(pdev); 2500187fbae0SWei Fang 2501187fbae0SWei Fang if (!priv) 2502187fbae0SWei Fang return; 2503187fbae0SWei Fang 2504187fbae0SWei Fang dsa_switch_shutdown(priv->ds); 2505187fbae0SWei Fang pci_set_drvdata(pdev, NULL); 2506187fbae0SWei Fang } 2507187fbae0SWei Fang 2508187fbae0SWei Fang static const struct pci_device_id netc_switch_ids[] = { 2509187fbae0SWei Fang { PCI_DEVICE(NETC_SWITCH_VENDOR_ID, NETC_SWITCH_DEVICE_ID) }, 2510187fbae0SWei Fang { } 2511187fbae0SWei Fang }; 2512187fbae0SWei Fang MODULE_DEVICE_TABLE(pci, netc_switch_ids); 2513187fbae0SWei Fang 2514187fbae0SWei Fang static struct pci_driver netc_switch_driver = { 2515187fbae0SWei Fang .name = KBUILD_MODNAME, 2516187fbae0SWei Fang .id_table = netc_switch_ids, 2517187fbae0SWei Fang .probe = netc_switch_probe, 2518187fbae0SWei Fang .remove = netc_switch_remove, 2519187fbae0SWei Fang .shutdown = netc_switch_shutdown, 2520187fbae0SWei Fang }; 2521187fbae0SWei Fang module_pci_driver(netc_switch_driver); 2522187fbae0SWei Fang 2523187fbae0SWei Fang MODULE_DESCRIPTION("NXP NETC Switch driver"); 2524187fbae0SWei Fang MODULE_LICENSE("Dual BSD/GPL"); 2525