Lines Matching +full:port +full:- +full:mapping +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0
7 * Copyright (C) 2017 - 2019 Hauke Mehrtens <hauke@hauke-m.de>
16 * The hardware does not support VLAN filter on the port, but on the
20 * rule and the CPU port is also added to all bridges. This makes it possible
23 * each switch port which is used when the port is used without an
46 #include <dt-bindings/mips/lantiq_rcu_gphy.h>
64 #define GSWIP_MDIO_PHYp(p) (0x15 - (p))
135 #define GSWIP_BM_RAM_VAL(x) (0x043 - (x))
143 /* buffer management Port Configuration Register */
147 /* buffer management Port Control Register */
153 #define GSWIP_PCE_TBL_KEY(x) (0x447 - (x))
155 #define GSWIP_PCE_TBL_VAL(x) (0x44D - (x))
169 #define GSWIP_PCE_PMAP1 0x453 /* Monitoring port map */
170 #define GSWIP_PCE_PMAP2 0x454 /* Default Multicast port map */
171 #define GSWIP_PCE_PMAP3 0x455 /* Default Unknown Unicast port map */
178 #define GSWIP_PCE_GCTRL_1_MAC_GLOCK_MOD BIT(3) /* Mac address table lock forwarding mode */
180 #define GSWIP_PCE_PCTRL_0_TVM BIT(5) /* Transparent VLAN mode */
181 #define GSWIP_PCE_PCTRL_0_VREP BIT(6) /* VLAN Replace Mode */
219 /* Ethernet Switch Fetch DMA Port Control Register */
221 #define GSWIP_FDMA_PCTRL_EN BIT(0) /* FDMA Port Enable */
230 /* Ethernet Switch Store DMA Port Control Register */
232 #define GSWIP_SDMA_PCTRL_EN BIT(0) /* SDMA Port Enable */
244 * but long packets currently cause lock-ups with an MTU of over 2526. Medium
245 * packets are sometimes dropped (e.g. TCP over 2477, UDP over 2516-2519, ICMP
293 u16 index; // PCE_TBL_ADDR.ADDR = pData->table_index
294 u16 table; // PCE_TBL_CTRL.ADDR = pData->table
329 /** Receive Size 1024-1522 (or more, if configured) Packet Count. */
344 /** Transmit Size 1024-1522 (or more, if configured) Packet Count. */
357 return __raw_readl(priv->gswip + (offset * 4)); in gswip_switch_r()
362 __raw_writel(val, priv->gswip + (offset * 4)); in gswip_switch_w()
380 return readx_poll_timeout(__raw_readl, priv->gswip + (offset * 4), val, in gswip_switch_r_timeout()
386 return __raw_readl(priv->mdio + (offset * 4)); in gswip_mdio_r()
391 __raw_writel(val, priv->mdio + (offset * 4)); in gswip_mdio_w()
406 return __raw_readl(priv->mii + (offset * 4)); in gswip_mii_r()
411 __raw_writel(val, priv->mii + (offset * 4)); in gswip_mii_w()
425 int port) in gswip_mii_mask_cfg() argument
427 /* There's no MII_CFG register for the CPU port */ in gswip_mii_mask_cfg()
428 if (!dsa_is_cpu_port(priv->ds, port)) in gswip_mii_mask_cfg()
429 gswip_mii_mask(priv, clear, set, GSWIP_MII_CFGp(port)); in gswip_mii_mask_cfg()
433 int port) in gswip_mii_mask_pcdu() argument
435 switch (port) { in gswip_mii_mask_pcdu()
452 while (likely(cnt--)) { in gswip_mdio_poll()
460 return -ETIMEDOUT; in gswip_mdio_poll()
465 struct gswip_priv *priv = bus->priv; in gswip_mdio_wr()
470 dev_err(&bus->dev, "waiting for MDIO bus busy timed out\n"); in gswip_mdio_wr()
485 struct gswip_priv *priv = bus->priv; in gswip_mdio_rd()
490 dev_err(&bus->dev, "waiting for MDIO bus busy timed out\n"); in gswip_mdio_rd()
501 dev_err(&bus->dev, "waiting for MDIO bus busy timed out\n"); in gswip_mdio_rd()
510 struct dsa_switch *ds = priv->ds; in gswip_mdio()
513 ds->slave_mii_bus = mdiobus_alloc(); in gswip_mdio()
514 if (!ds->slave_mii_bus) in gswip_mdio()
515 return -ENOMEM; in gswip_mdio()
517 ds->slave_mii_bus->priv = priv; in gswip_mdio()
518 ds->slave_mii_bus->read = gswip_mdio_rd; in gswip_mdio()
519 ds->slave_mii_bus->write = gswip_mdio_wr; in gswip_mdio()
520 ds->slave_mii_bus->name = "lantiq,xrx200-mdio"; in gswip_mdio()
521 snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "%s-mii", in gswip_mdio()
522 dev_name(priv->dev)); in gswip_mdio()
523 ds->slave_mii_bus->parent = priv->dev; in gswip_mdio()
524 ds->slave_mii_bus->phy_mask = ~ds->phys_mii_mask; in gswip_mdio()
526 err = of_mdiobus_register(ds->slave_mii_bus, mdio_np); in gswip_mdio()
528 mdiobus_free(ds->slave_mii_bus); in gswip_mdio()
539 u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSRD : in gswip_pce_table_entry_read()
542 mutex_lock(&priv->pce_table_lock); in gswip_pce_table_entry_read()
547 mutex_unlock(&priv->pce_table_lock); in gswip_pce_table_entry_read()
551 gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); in gswip_pce_table_entry_read()
554 tbl->table | addr_mode | GSWIP_PCE_TBL_CTRL_BAS, in gswip_pce_table_entry_read()
560 mutex_unlock(&priv->pce_table_lock); in gswip_pce_table_entry_read()
564 for (i = 0; i < ARRAY_SIZE(tbl->key); i++) in gswip_pce_table_entry_read()
565 tbl->key[i] = gswip_switch_r(priv, GSWIP_PCE_TBL_KEY(i)); in gswip_pce_table_entry_read()
567 for (i = 0; i < ARRAY_SIZE(tbl->val); i++) in gswip_pce_table_entry_read()
568 tbl->val[i] = gswip_switch_r(priv, GSWIP_PCE_TBL_VAL(i)); in gswip_pce_table_entry_read()
570 tbl->mask = gswip_switch_r(priv, GSWIP_PCE_TBL_MASK); in gswip_pce_table_entry_read()
574 tbl->type = !!(crtl & GSWIP_PCE_TBL_CTRL_TYPE); in gswip_pce_table_entry_read()
575 tbl->valid = !!(crtl & GSWIP_PCE_TBL_CTRL_VLD); in gswip_pce_table_entry_read()
576 tbl->gmap = (crtl & GSWIP_PCE_TBL_CTRL_GMAP_MASK) >> 7; in gswip_pce_table_entry_read()
578 mutex_unlock(&priv->pce_table_lock); in gswip_pce_table_entry_read()
589 u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSWR : in gswip_pce_table_entry_write()
592 mutex_lock(&priv->pce_table_lock); in gswip_pce_table_entry_write()
597 mutex_unlock(&priv->pce_table_lock); in gswip_pce_table_entry_write()
601 gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); in gswip_pce_table_entry_write()
604 tbl->table | addr_mode, in gswip_pce_table_entry_write()
607 for (i = 0; i < ARRAY_SIZE(tbl->key); i++) in gswip_pce_table_entry_write()
608 gswip_switch_w(priv, tbl->key[i], GSWIP_PCE_TBL_KEY(i)); in gswip_pce_table_entry_write()
610 for (i = 0; i < ARRAY_SIZE(tbl->val); i++) in gswip_pce_table_entry_write()
611 gswip_switch_w(priv, tbl->val[i], GSWIP_PCE_TBL_VAL(i)); in gswip_pce_table_entry_write()
615 tbl->table | addr_mode, in gswip_pce_table_entry_write()
618 gswip_switch_w(priv, tbl->mask, GSWIP_PCE_TBL_MASK); in gswip_pce_table_entry_write()
623 if (tbl->type) in gswip_pce_table_entry_write()
625 if (tbl->valid) in gswip_pce_table_entry_write()
627 crtl |= (tbl->gmap << 7) & GSWIP_PCE_TBL_CTRL_GMAP_MASK; in gswip_pce_table_entry_write()
634 mutex_unlock(&priv->pce_table_lock); in gswip_pce_table_entry_write()
639 /* Add the LAN port into a bridge with the CPU port by
644 static int gswip_add_single_port_br(struct gswip_priv *priv, int port, bool add) in gswip_add_single_port_br() argument
648 unsigned int cpu_port = priv->hw_info->cpu_port; in gswip_add_single_port_br()
649 unsigned int max_ports = priv->hw_info->max_ports; in gswip_add_single_port_br()
652 if (port >= max_ports) { in gswip_add_single_port_br()
653 dev_err(priv->dev, "single port for %i supported\n", port); in gswip_add_single_port_br()
654 return -EIO; in gswip_add_single_port_br()
657 vlan_active.index = port + 1; in gswip_add_single_port_br()
660 vlan_active.val[0] = port + 1 /* fid */; in gswip_add_single_port_br()
664 dev_err(priv->dev, "failed to write active VLAN: %d\n", err); in gswip_add_single_port_br()
671 vlan_mapping.index = port + 1; in gswip_add_single_port_br()
674 vlan_mapping.val[1] = BIT(port) | BIT(cpu_port); in gswip_add_single_port_br()
678 dev_err(priv->dev, "failed to write VLAN mapping: %d\n", err); in gswip_add_single_port_br()
685 static int gswip_port_enable(struct dsa_switch *ds, int port, in gswip_port_enable() argument
688 struct gswip_priv *priv = ds->priv; in gswip_port_enable()
691 if (!dsa_is_user_port(ds, port)) in gswip_port_enable()
694 if (!dsa_is_cpu_port(ds, port)) { in gswip_port_enable()
695 err = gswip_add_single_port_br(priv, port, true); in gswip_port_enable()
700 /* RMON Counter Enable for port */ in gswip_port_enable()
701 gswip_switch_w(priv, GSWIP_BM_PCFG_CNTEN, GSWIP_BM_PCFGp(port)); in gswip_port_enable()
703 /* enable port fetch/store dma & VLAN Modification */ in gswip_port_enable()
706 GSWIP_FDMA_PCTRLp(port)); in gswip_port_enable()
708 GSWIP_SDMA_PCTRLp(port)); in gswip_port_enable()
710 if (!dsa_is_cpu_port(ds, port)) { in gswip_port_enable()
714 mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK; in gswip_port_enable()
717 GSWIP_MDIO_PHYp(port)); in gswip_port_enable()
723 static void gswip_port_disable(struct dsa_switch *ds, int port) in gswip_port_disable() argument
725 struct gswip_priv *priv = ds->priv; in gswip_port_disable()
727 if (!dsa_is_user_port(ds, port)) in gswip_port_disable()
731 GSWIP_FDMA_PCTRLp(port)); in gswip_port_disable()
733 GSWIP_SDMA_PCTRLp(port)); in gswip_port_disable()
773 static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port, in gswip_port_vlan_filtering() argument
777 struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port)); in gswip_port_vlan_filtering()
778 struct gswip_priv *priv = ds->priv; in gswip_port_vlan_filtering()
781 if (bridge && !!(priv->port_vlan_filter & BIT(port)) != vlan_filtering) { in gswip_port_vlan_filtering()
784 return -EIO; in gswip_port_vlan_filtering()
788 /* Use port based VLAN tag */ in gswip_port_vlan_filtering()
793 GSWIP_PCE_VCTRL(port)); in gswip_port_vlan_filtering()
795 GSWIP_PCE_PCTRL_0p(port)); in gswip_port_vlan_filtering()
797 /* Use port based VLAN tag */ in gswip_port_vlan_filtering()
802 GSWIP_PCE_VCTRL(port)); in gswip_port_vlan_filtering()
804 GSWIP_PCE_PCTRL_0p(port)); in gswip_port_vlan_filtering()
812 struct gswip_priv *priv = ds->priv; in gswip_setup()
813 unsigned int cpu_port = priv->hw_info->cpu_port; in gswip_setup()
821 /* disable port fetch/store dma on all ports */ in gswip_setup()
822 for (i = 0; i < priv->hw_info->max_ports; i++) { in gswip_setup()
832 dev_err(priv->dev, "writing PCE microcode failed, %i", err); in gswip_setup()
836 /* Default unknown Broadcast/Multicast/Unicast port maps */ in gswip_setup()
848 * to the switch port being completely dead (RX and TX are both not in gswip_setup()
850 * Also with various other PHY / port combinations (PHY11G GPHY, PHY22F in gswip_setup()
863 for (i = 0; i < priv->hw_info->max_ports; i++) in gswip_setup()
868 /* enable special tag insertion on cpu port */ in gswip_setup()
888 dev_err(priv->dev, "MAC flushing didn't finish\n"); in gswip_setup()
892 ds->mtu_enforcement_ingress = true; in gswip_setup()
896 ds->configure_vlan_while_not_filtering = false; in gswip_setup()
902 int port, in gswip_get_tag_protocol() argument
913 unsigned int max_ports = priv->hw_info->max_ports; in gswip_vlan_active_create()
914 int idx = -1; in gswip_vlan_active_create()
919 for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { in gswip_vlan_active_create()
920 if (!priv->vlans[i].bridge) { in gswip_vlan_active_create()
926 if (idx == -1) in gswip_vlan_active_create()
927 return -ENOSPC; in gswip_vlan_active_create()
929 if (fid == -1) in gswip_vlan_active_create()
940 dev_err(priv->dev, "failed to write active VLAN: %d\n", err); in gswip_vlan_active_create()
944 priv->vlans[idx].bridge = bridge; in gswip_vlan_active_create()
945 priv->vlans[idx].vid = vid; in gswip_vlan_active_create()
946 priv->vlans[idx].fid = fid; in gswip_vlan_active_create()
961 dev_err(priv->dev, "failed to delete active VLAN: %d\n", err); in gswip_vlan_active_remove()
962 priv->vlans[idx].bridge = NULL; in gswip_vlan_active_remove()
968 struct net_device *bridge, int port) in gswip_vlan_add_unaware() argument
971 unsigned int max_ports = priv->hw_info->max_ports; in gswip_vlan_add_unaware()
972 unsigned int cpu_port = priv->hw_info->cpu_port; in gswip_vlan_add_unaware()
974 int idx = -1; in gswip_vlan_add_unaware()
979 for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { in gswip_vlan_add_unaware()
980 if (priv->vlans[i].bridge == bridge) { in gswip_vlan_add_unaware()
987 * entry in a free slot and prepare the VLAN mapping table entry. in gswip_vlan_add_unaware()
989 if (idx == -1) { in gswip_vlan_add_unaware()
990 idx = gswip_vlan_active_create(priv, bridge, -1, 0); in gswip_vlan_add_unaware()
1000 /* Read the existing VLAN mapping entry from the switch */ in gswip_vlan_add_unaware()
1005 dev_err(priv->dev, "failed to read VLAN mapping: %d\n", in gswip_vlan_add_unaware()
1011 /* Update the VLAN mapping entry and write it to the switch */ in gswip_vlan_add_unaware()
1013 vlan_mapping.val[1] |= BIT(port); in gswip_vlan_add_unaware()
1016 dev_err(priv->dev, "failed to write VLAN mapping: %d\n", err); in gswip_vlan_add_unaware()
1023 gswip_switch_w(priv, 0, GSWIP_PCE_DEFPVID(port)); in gswip_vlan_add_unaware()
1028 struct net_device *bridge, int port, in gswip_vlan_add_aware() argument
1033 unsigned int max_ports = priv->hw_info->max_ports; in gswip_vlan_add_aware()
1034 unsigned int cpu_port = priv->hw_info->cpu_port; in gswip_vlan_add_aware()
1036 int idx = -1; in gswip_vlan_add_aware()
1037 int fid = -1; in gswip_vlan_add_aware()
1042 for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { in gswip_vlan_add_aware()
1043 if (priv->vlans[i].bridge == bridge) { in gswip_vlan_add_aware()
1044 if (fid != -1 && fid != priv->vlans[i].fid) in gswip_vlan_add_aware()
1045 dev_err(priv->dev, "one bridge with multiple flow ids\n"); in gswip_vlan_add_aware()
1046 fid = priv->vlans[i].fid; in gswip_vlan_add_aware()
1047 if (priv->vlans[i].vid == vid) { in gswip_vlan_add_aware()
1055 * entry in a free slot and prepare the VLAN mapping table entry. in gswip_vlan_add_aware()
1057 if (idx == -1) { in gswip_vlan_add_aware()
1068 /* Read the existing VLAN mapping entry from the switch */ in gswip_vlan_add_aware()
1073 dev_err(priv->dev, "failed to read VLAN mapping: %d\n", in gswip_vlan_add_aware()
1080 /* Update the VLAN mapping entry and write it to the switch */ in gswip_vlan_add_aware()
1083 vlan_mapping.val[1] |= BIT(port); in gswip_vlan_add_aware()
1085 vlan_mapping.val[2] &= ~BIT(port); in gswip_vlan_add_aware()
1087 vlan_mapping.val[2] |= BIT(port); in gswip_vlan_add_aware()
1090 dev_err(priv->dev, "failed to write VLAN mapping: %d\n", err); in gswip_vlan_add_aware()
1098 gswip_switch_w(priv, idx, GSWIP_PCE_DEFPVID(port)); in gswip_vlan_add_aware()
1104 struct net_device *bridge, int port, in gswip_vlan_remove() argument
1108 unsigned int max_ports = priv->hw_info->max_ports; in gswip_vlan_remove()
1109 unsigned int cpu_port = priv->hw_info->cpu_port; in gswip_vlan_remove()
1110 int idx = -1; in gswip_vlan_remove()
1115 for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { in gswip_vlan_remove()
1116 if (priv->vlans[i].bridge == bridge && in gswip_vlan_remove()
1117 (!vlan_aware || priv->vlans[i].vid == vid)) { in gswip_vlan_remove()
1123 if (idx == -1) { in gswip_vlan_remove()
1124 dev_err(priv->dev, "bridge to leave does not exists\n"); in gswip_vlan_remove()
1125 return -ENOENT; in gswip_vlan_remove()
1132 dev_err(priv->dev, "failed to read VLAN mapping: %d\n", err); in gswip_vlan_remove()
1136 vlan_mapping.val[1] &= ~BIT(port); in gswip_vlan_remove()
1137 vlan_mapping.val[2] &= ~BIT(port); in gswip_vlan_remove()
1140 dev_err(priv->dev, "failed to write VLAN mapping: %d\n", err); in gswip_vlan_remove()
1148 dev_err(priv->dev, "failed to write active VLAN: %d\n", in gswip_vlan_remove()
1156 gswip_switch_w(priv, 0, GSWIP_PCE_DEFPVID(port)); in gswip_vlan_remove()
1161 static int gswip_port_bridge_join(struct dsa_switch *ds, int port, in gswip_port_bridge_join() argument
1167 struct gswip_priv *priv = ds->priv; in gswip_port_bridge_join()
1174 err = gswip_vlan_add_unaware(priv, br, port); in gswip_port_bridge_join()
1177 priv->port_vlan_filter &= ~BIT(port); in gswip_port_bridge_join()
1179 priv->port_vlan_filter |= BIT(port); in gswip_port_bridge_join()
1181 return gswip_add_single_port_br(priv, port, false); in gswip_port_bridge_join()
1184 static void gswip_port_bridge_leave(struct dsa_switch *ds, int port, in gswip_port_bridge_leave() argument
1188 struct gswip_priv *priv = ds->priv; in gswip_port_bridge_leave()
1190 gswip_add_single_port_br(priv, port, true); in gswip_port_bridge_leave()
1196 gswip_vlan_remove(priv, br, port, 0, true, false); in gswip_port_bridge_leave()
1199 static int gswip_port_vlan_prepare(struct dsa_switch *ds, int port, in gswip_port_vlan_prepare() argument
1203 struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port)); in gswip_port_vlan_prepare()
1204 struct gswip_priv *priv = ds->priv; in gswip_port_vlan_prepare()
1205 unsigned int max_ports = priv->hw_info->max_ports; in gswip_port_vlan_prepare()
1207 int i, idx = -1; in gswip_port_vlan_prepare()
1210 if (!dsa_is_cpu_port(ds, port) && !bridge) in gswip_port_vlan_prepare()
1211 return -EOPNOTSUPP; in gswip_port_vlan_prepare()
1214 for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { in gswip_port_vlan_prepare()
1215 if (priv->vlans[i].bridge == bridge && in gswip_port_vlan_prepare()
1216 priv->vlans[i].vid == vlan->vid) { in gswip_port_vlan_prepare()
1226 if (idx == -1) { in gswip_port_vlan_prepare()
1228 for (; pos < ARRAY_SIZE(priv->vlans); pos++) { in gswip_port_vlan_prepare()
1229 if (!priv->vlans[pos].bridge) { in gswip_port_vlan_prepare()
1236 if (idx == -1) { in gswip_port_vlan_prepare()
1238 return -ENOSPC; in gswip_port_vlan_prepare()
1245 static int gswip_port_vlan_add(struct dsa_switch *ds, int port, in gswip_port_vlan_add() argument
1249 struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port)); in gswip_port_vlan_add()
1250 struct gswip_priv *priv = ds->priv; in gswip_port_vlan_add()
1251 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; in gswip_port_vlan_add()
1252 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; in gswip_port_vlan_add()
1255 err = gswip_port_vlan_prepare(ds, port, vlan, extack); in gswip_port_vlan_add()
1259 /* We have to receive all packets on the CPU port and should not in gswip_port_vlan_add()
1264 if (dsa_is_cpu_port(ds, port)) in gswip_port_vlan_add()
1267 return gswip_vlan_add_aware(priv, bridge, port, vlan->vid, in gswip_port_vlan_add()
1271 static int gswip_port_vlan_del(struct dsa_switch *ds, int port, in gswip_port_vlan_del() argument
1274 struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port)); in gswip_port_vlan_del()
1275 struct gswip_priv *priv = ds->priv; in gswip_port_vlan_del()
1276 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; in gswip_port_vlan_del()
1278 /* We have to receive all packets on the CPU port and should not in gswip_port_vlan_del()
1283 if (dsa_is_cpu_port(ds, port)) in gswip_port_vlan_del()
1286 return gswip_vlan_remove(priv, bridge, port, vlan->vid, pvid, true); in gswip_port_vlan_del()
1289 static void gswip_port_fast_age(struct dsa_switch *ds, int port) in gswip_port_fast_age() argument
1291 struct gswip_priv *priv = ds->priv; in gswip_port_fast_age()
1302 dev_err(priv->dev, "failed to read mac bridge: %d\n", in gswip_port_fast_age()
1313 if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) != port) in gswip_port_fast_age()
1319 dev_err(priv->dev, "failed to write mac bridge: %d\n", in gswip_port_fast_age()
1326 static void gswip_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) in gswip_port_stp_state_set() argument
1328 struct gswip_priv *priv = ds->priv; in gswip_port_stp_state_set()
1334 GSWIP_SDMA_PCTRLp(port)); in gswip_port_stp_state_set()
1347 dev_err(priv->dev, "invalid STP state: %d\n", state); in gswip_port_stp_state_set()
1352 GSWIP_SDMA_PCTRLp(port)); in gswip_port_stp_state_set()
1354 GSWIP_PCE_PCTRL_0p(port)); in gswip_port_stp_state_set()
1357 static int gswip_port_fdb(struct dsa_switch *ds, int port, in gswip_port_fdb() argument
1360 struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port)); in gswip_port_fdb()
1361 struct gswip_priv *priv = ds->priv; in gswip_port_fdb()
1363 unsigned int max_ports = priv->hw_info->max_ports; in gswip_port_fdb()
1364 int fid = -1; in gswip_port_fdb()
1369 return -EINVAL; in gswip_port_fdb()
1371 for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { in gswip_port_fdb()
1372 if (priv->vlans[i].bridge == bridge) { in gswip_port_fdb()
1373 fid = priv->vlans[i].fid; in gswip_port_fdb()
1378 if (fid == -1) { in gswip_port_fdb()
1379 dev_err(priv->dev, "Port not part of a bridge\n"); in gswip_port_fdb()
1380 return -EINVAL; in gswip_port_fdb()
1389 mac_bridge.val[0] = add ? BIT(port) : 0; /* port map */ in gswip_port_fdb()
1395 dev_err(priv->dev, "failed to write mac bridge: %d\n", err); in gswip_port_fdb()
1400 static int gswip_port_fdb_add(struct dsa_switch *ds, int port, in gswip_port_fdb_add() argument
1404 return gswip_port_fdb(ds, port, addr, vid, true); in gswip_port_fdb_add()
1407 static int gswip_port_fdb_del(struct dsa_switch *ds, int port, in gswip_port_fdb_del() argument
1411 return gswip_port_fdb(ds, port, addr, vid, false); in gswip_port_fdb_del()
1414 static int gswip_port_fdb_dump(struct dsa_switch *ds, int port, in gswip_port_fdb_dump() argument
1417 struct gswip_priv *priv = ds->priv; in gswip_port_fdb_dump()
1429 dev_err(priv->dev, in gswip_port_fdb_dump()
1445 if (mac_bridge.val[0] & BIT(port)) { in gswip_port_fdb_dump()
1451 if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) { in gswip_port_fdb_dump()
1461 static int gswip_port_max_mtu(struct dsa_switch *ds, int port) in gswip_port_max_mtu() argument
1464 return GSWIP_MAX_PACKET_LENGTH - VLAN_ETH_HLEN - ETH_FCS_LEN; in gswip_port_max_mtu()
1467 static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) in gswip_port_change_mtu() argument
1469 struct gswip_priv *priv = ds->priv; in gswip_port_change_mtu()
1470 int cpu_port = priv->hw_info->cpu_port; in gswip_port_change_mtu()
1472 /* CPU port always has maximum mtu of user ports, so use it to set in gswip_port_change_mtu()
1475 if (port == cpu_port) { in gswip_port_change_mtu()
1481 /* Enable MLEN for ports with non-standard MTUs, including the special in gswip_port_change_mtu()
1482 * header on the CPU port added above. in gswip_port_change_mtu()
1486 GSWIP_MAC_CTRL_2p(port)); in gswip_port_change_mtu()
1489 GSWIP_MAC_CTRL_2p(port)); in gswip_port_change_mtu()
1494 static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port, in gswip_xrx200_phylink_get_caps() argument
1497 switch (port) { in gswip_xrx200_phylink_get_caps()
1500 phy_interface_set_rgmii(config->supported_interfaces); in gswip_xrx200_phylink_get_caps()
1502 config->supported_interfaces); in gswip_xrx200_phylink_get_caps()
1504 config->supported_interfaces); in gswip_xrx200_phylink_get_caps()
1506 config->supported_interfaces); in gswip_xrx200_phylink_get_caps()
1513 config->supported_interfaces); in gswip_xrx200_phylink_get_caps()
1517 phy_interface_set_rgmii(config->supported_interfaces); in gswip_xrx200_phylink_get_caps()
1519 config->supported_interfaces); in gswip_xrx200_phylink_get_caps()
1523 config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | in gswip_xrx200_phylink_get_caps()
1527 static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port, in gswip_xrx300_phylink_get_caps() argument
1530 switch (port) { in gswip_xrx300_phylink_get_caps()
1532 phy_interface_set_rgmii(config->supported_interfaces); in gswip_xrx300_phylink_get_caps()
1534 config->supported_interfaces); in gswip_xrx300_phylink_get_caps()
1536 config->supported_interfaces); in gswip_xrx300_phylink_get_caps()
1544 config->supported_interfaces); in gswip_xrx300_phylink_get_caps()
1548 phy_interface_set_rgmii(config->supported_interfaces); in gswip_xrx300_phylink_get_caps()
1550 config->supported_interfaces); in gswip_xrx300_phylink_get_caps()
1552 config->supported_interfaces); in gswip_xrx300_phylink_get_caps()
1556 config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | in gswip_xrx300_phylink_get_caps()
1560 static void gswip_port_set_link(struct gswip_priv *priv, int port, bool link) in gswip_port_set_link() argument
1570 GSWIP_MDIO_PHYp(port)); in gswip_port_set_link()
1573 static void gswip_port_set_speed(struct gswip_priv *priv, int port, int speed, in gswip_port_set_speed() argument
1611 GSWIP_MDIO_PHYp(port)); in gswip_port_set_speed()
1612 gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_RATE_MASK, mii_cfg, port); in gswip_port_set_speed()
1614 GSWIP_MAC_CTRL_0p(port)); in gswip_port_set_speed()
1617 static void gswip_port_set_duplex(struct gswip_priv *priv, int port, int duplex) in gswip_port_set_duplex() argument
1630 GSWIP_MAC_CTRL_0p(port)); in gswip_port_set_duplex()
1632 GSWIP_MDIO_PHYp(port)); in gswip_port_set_duplex()
1635 static void gswip_port_set_pause(struct gswip_priv *priv, int port, in gswip_port_set_pause() argument
1659 mac_ctrl_0, GSWIP_MAC_CTRL_0p(port)); in gswip_port_set_pause()
1663 mdio_phy, GSWIP_MDIO_PHYp(port)); in gswip_port_set_pause()
1666 static void gswip_phylink_mac_config(struct dsa_switch *ds, int port, in gswip_phylink_mac_config() argument
1667 unsigned int mode, in gswip_phylink_mac_config() argument
1670 struct gswip_priv *priv = ds->priv; in gswip_phylink_mac_config()
1675 switch (state->interface) { in gswip_phylink_mac_config()
1696 dev_err(ds->dev, in gswip_phylink_mac_config()
1697 "Unsupported interface: %d\n", state->interface); in gswip_phylink_mac_config()
1704 miicfg, port); in gswip_phylink_mac_config()
1706 switch (state->interface) { in gswip_phylink_mac_config()
1709 GSWIP_MII_PCDU_RXDLY_MASK, 0, port); in gswip_phylink_mac_config()
1712 gswip_mii_mask_pcdu(priv, GSWIP_MII_PCDU_RXDLY_MASK, 0, port); in gswip_phylink_mac_config()
1715 gswip_mii_mask_pcdu(priv, GSWIP_MII_PCDU_TXDLY_MASK, 0, port); in gswip_phylink_mac_config()
1722 static void gswip_phylink_mac_link_down(struct dsa_switch *ds, int port, in gswip_phylink_mac_link_down() argument
1723 unsigned int mode, in gswip_phylink_mac_link_down() argument
1726 struct gswip_priv *priv = ds->priv; in gswip_phylink_mac_link_down()
1728 gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, port); in gswip_phylink_mac_link_down()
1730 if (!dsa_is_cpu_port(ds, port)) in gswip_phylink_mac_link_down()
1731 gswip_port_set_link(priv, port, false); in gswip_phylink_mac_link_down()
1734 static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port, in gswip_phylink_mac_link_up() argument
1735 unsigned int mode, in gswip_phylink_mac_link_up() argument
1741 struct gswip_priv *priv = ds->priv; in gswip_phylink_mac_link_up()
1743 if (!dsa_is_cpu_port(ds, port)) { in gswip_phylink_mac_link_up()
1744 gswip_port_set_link(priv, port, true); in gswip_phylink_mac_link_up()
1745 gswip_port_set_speed(priv, port, speed, interface); in gswip_phylink_mac_link_up()
1746 gswip_port_set_duplex(priv, port, duplex); in gswip_phylink_mac_link_up()
1747 gswip_port_set_pause(priv, port, tx_pause, rx_pause); in gswip_phylink_mac_link_up()
1750 gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); in gswip_phylink_mac_link_up()
1753 static void gswip_get_strings(struct dsa_switch *ds, int port, u32 stringset, in gswip_get_strings() argument
1781 dev_err(priv->dev, "timeout while reading table: %u, index: %u", in gswip_bcm_ram_entry_read()
1792 static void gswip_get_ethtool_stats(struct dsa_switch *ds, int port, in gswip_get_ethtool_stats() argument
1795 struct gswip_priv *priv = ds->priv; in gswip_get_ethtool_stats()
1803 data[i] = gswip_bcm_ram_entry_read(priv, port, in gswip_get_ethtool_stats()
1804 rmon_cnt->offset); in gswip_get_ethtool_stats()
1805 if (rmon_cnt->size == 2) { in gswip_get_ethtool_stats()
1806 high = gswip_bcm_ram_entry_read(priv, port, in gswip_get_ethtool_stats()
1807 rmon_cnt->offset + 1); in gswip_get_ethtool_stats()
1813 static int gswip_get_sset_count(struct dsa_switch *ds, int port, int sset) in gswip_get_sset_count() argument
1889 { .compatible = "lantiq,xrx200-gphy-fw", .data = NULL },
1890 { .compatible = "lantiq,xrx200a1x-gphy-fw", .data = &xrx200a1x_gphy_data },
1891 { .compatible = "lantiq,xrx200a2x-gphy-fw", .data = &xrx200a2x_gphy_data },
1892 { .compatible = "lantiq,xrx300-gphy-fw", .data = &xrx300_gphy_data },
1893 { .compatible = "lantiq,xrx330-gphy-fw", .data = &xrx300_gphy_data },
1899 struct device *dev = priv->dev; in gswip_gphy_fw_load()
1907 ret = clk_prepare_enable(gphy_fw->clk_gate); in gswip_gphy_fw_load()
1911 reset_control_assert(gphy_fw->reset); in gswip_gphy_fw_load()
1919 ret = request_firmware(&fw, gphy_fw->fw_name, dev); in gswip_gphy_fw_load()
1922 gphy_fw->fw_name, ret); in gswip_gphy_fw_load()
1929 size = fw->size + XRX200_GPHY_FW_ALIGN; in gswip_gphy_fw_load()
1935 memcpy(fw_addr, fw->data, fw->size); in gswip_gphy_fw_load()
1939 return -ENOMEM; in gswip_gphy_fw_load()
1944 ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, dev_addr); in gswip_gphy_fw_load()
1948 reset_control_deassert(gphy_fw->reset); in gswip_gphy_fw_load()
1957 struct device *dev = priv->dev; in gswip_gphy_fw_probe()
1964 gphy_fw->clk_gate = devm_clk_get(dev, gphyname); in gswip_gphy_fw_probe()
1965 if (IS_ERR(gphy_fw->clk_gate)) { in gswip_gphy_fw_probe()
1967 return PTR_ERR(gphy_fw->clk_gate); in gswip_gphy_fw_probe()
1970 ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset); in gswip_gphy_fw_probe()
1974 ret = of_property_read_u32(gphy_fw_np, "lantiq,gphy-mode", &gphy_mode); in gswip_gphy_fw_probe()
1975 /* Default to GE mode */ in gswip_gphy_fw_probe()
1981 gphy_fw->fw_name = priv->gphy_fw_name_cfg->fe_firmware_name; in gswip_gphy_fw_probe()
1984 gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name; in gswip_gphy_fw_probe()
1987 dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode); in gswip_gphy_fw_probe()
1988 return -EINVAL; in gswip_gphy_fw_probe()
1991 gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np); in gswip_gphy_fw_probe()
1992 if (IS_ERR(gphy_fw->reset)) in gswip_gphy_fw_probe()
1993 return dev_err_probe(dev, PTR_ERR(gphy_fw->reset), in gswip_gphy_fw_probe()
2005 if (!gphy_fw->fw_name) in gswip_gphy_fw_remove()
2008 ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, 0); in gswip_gphy_fw_remove()
2010 dev_err(priv->dev, "can not reset GPHY FW pointer"); in gswip_gphy_fw_remove()
2012 clk_disable_unprepare(gphy_fw->clk_gate); in gswip_gphy_fw_remove()
2014 reset_control_put(gphy_fw->reset); in gswip_gphy_fw_remove()
2020 struct device *dev = priv->dev; in gswip_gphy_fw_list()
2030 if (of_device_is_compatible(gphy_fw_list_np, "lantiq,xrx200-gphy-fw")) { in gswip_gphy_fw_list()
2033 priv->gphy_fw_name_cfg = &xrx200a1x_gphy_data; in gswip_gphy_fw_list()
2036 priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data; in gswip_gphy_fw_list()
2040 return -ENOENT; in gswip_gphy_fw_list()
2045 if (match && match->data) in gswip_gphy_fw_list()
2046 priv->gphy_fw_name_cfg = match->data; in gswip_gphy_fw_list()
2048 if (!priv->gphy_fw_name_cfg) { in gswip_gphy_fw_list()
2050 return -ENOENT; in gswip_gphy_fw_list()
2053 priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np); in gswip_gphy_fw_list()
2054 if (!priv->num_gphy_fw) in gswip_gphy_fw_list()
2055 return -ENOENT; in gswip_gphy_fw_list()
2057 priv->rcu_regmap = syscon_regmap_lookup_by_phandle(gphy_fw_list_np, in gswip_gphy_fw_list()
2059 if (IS_ERR(priv->rcu_regmap)) in gswip_gphy_fw_list()
2060 return PTR_ERR(priv->rcu_regmap); in gswip_gphy_fw_list()
2062 priv->gphy_fw = devm_kmalloc_array(dev, priv->num_gphy_fw, in gswip_gphy_fw_list()
2063 sizeof(*priv->gphy_fw), in gswip_gphy_fw_list()
2065 if (!priv->gphy_fw) in gswip_gphy_fw_list()
2066 return -ENOMEM; in gswip_gphy_fw_list()
2069 err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i], in gswip_gphy_fw_list()
2080 * taken out of reset. For the SoC-internal GPHY variant there in gswip_gphy_fw_list()
2091 for (i = 0; i < priv->num_gphy_fw; i++) in gswip_gphy_fw_list()
2092 gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]); in gswip_gphy_fw_list()
2100 struct device *dev = &pdev->dev; in gswip_probe()
2107 return -ENOMEM; in gswip_probe()
2109 priv->gswip = devm_platform_ioremap_resource(pdev, 0); in gswip_probe()
2110 if (IS_ERR(priv->gswip)) in gswip_probe()
2111 return PTR_ERR(priv->gswip); in gswip_probe()
2113 priv->mdio = devm_platform_ioremap_resource(pdev, 1); in gswip_probe()
2114 if (IS_ERR(priv->mdio)) in gswip_probe()
2115 return PTR_ERR(priv->mdio); in gswip_probe()
2117 priv->mii = devm_platform_ioremap_resource(pdev, 2); in gswip_probe()
2118 if (IS_ERR(priv->mii)) in gswip_probe()
2119 return PTR_ERR(priv->mii); in gswip_probe()
2121 priv->hw_info = of_device_get_match_data(dev); in gswip_probe()
2122 if (!priv->hw_info) in gswip_probe()
2123 return -EINVAL; in gswip_probe()
2125 priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL); in gswip_probe()
2126 if (!priv->ds) in gswip_probe()
2127 return -ENOMEM; in gswip_probe()
2129 priv->ds->dev = dev; in gswip_probe()
2130 priv->ds->num_ports = priv->hw_info->max_ports; in gswip_probe()
2131 priv->ds->priv = priv; in gswip_probe()
2132 priv->ds->ops = priv->hw_info->ops; in gswip_probe()
2133 priv->dev = dev; in gswip_probe()
2134 mutex_init(&priv->pce_table_lock); in gswip_probe()
2137 np = dev->of_node; in gswip_probe()
2141 if (!of_device_is_compatible(np, "lantiq,xrx200-gswip")) in gswip_probe()
2142 return -EINVAL; in gswip_probe()
2146 if (!of_device_is_compatible(np, "lantiq,xrx300-gswip") && in gswip_probe()
2147 !of_device_is_compatible(np, "lantiq,xrx330-gswip")) in gswip_probe()
2148 return -EINVAL; in gswip_probe()
2152 return -ENOENT; in gswip_probe()
2156 gphy_fw_np = of_get_compatible_child(dev->of_node, "lantiq,gphy-fw"); in gswip_probe()
2167 mdio_np = of_get_compatible_child(dev->of_node, "lantiq,xrx200-mdio"); in gswip_probe()
2176 err = dsa_register_switch(priv->ds); in gswip_probe()
2181 if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) { in gswip_probe()
2182 dev_err(dev, "wrong CPU port defined, HW only supports port: %i", in gswip_probe()
2183 priv->hw_info->cpu_port); in gswip_probe()
2184 err = -EINVAL; in gswip_probe()
2197 dsa_unregister_switch(priv->ds); in gswip_probe()
2200 mdiobus_unregister(priv->ds->slave_mii_bus); in gswip_probe()
2201 mdiobus_free(priv->ds->slave_mii_bus); in gswip_probe()
2205 for (i = 0; i < priv->num_gphy_fw; i++) in gswip_probe()
2206 gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]); in gswip_probe()
2221 dsa_unregister_switch(priv->ds); in gswip_remove()
2223 if (priv->ds->slave_mii_bus) { in gswip_remove()
2224 mdiobus_unregister(priv->ds->slave_mii_bus); in gswip_remove()
2225 of_node_put(priv->ds->slave_mii_bus->dev.of_node); in gswip_remove()
2226 mdiobus_free(priv->ds->slave_mii_bus); in gswip_remove()
2229 for (i = 0; i < priv->num_gphy_fw; i++) in gswip_remove()
2230 gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]); in gswip_remove()
2242 dsa_switch_shutdown(priv->ds); in gswip_shutdown()
2260 { .compatible = "lantiq,xrx200-gswip", .data = &gswip_xrx200 },
2261 { .compatible = "lantiq,xrx300-gswip", .data = &gswip_xrx300 },
2262 { .compatible = "lantiq,xrx330-gswip", .data = &gswip_xrx300 },
2285 MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");