Lines Matching full:lan966x
30 { .compatible = "microchip,lan966x-switch" },
68 struct lan966x *lan966x) in lan966x_create_targets() argument
101 lan966x->regs[iomap->id] = begin[iomap->range] + iomap->offset; in lan966x_create_targets()
110 struct lan966x *lan966x = port->lan966x; in lan966x_port_unique_address() local
113 for (p = 0; p < lan966x->num_phys_ports; ++p) { in lan966x_port_unique_address()
114 port = lan966x->ports[p]; in lan966x_port_unique_address()
128 struct lan966x *lan966x = port->lan966x; in lan966x_port_set_mac_address() local
136 ret = lan966x_mac_cpu_learn(lan966x, addr->sa_data, HOST_PVID); in lan966x_port_set_mac_address()
147 ret = lan966x_mac_cpu_forget(lan966x, dev->dev_addr, HOST_PVID); in lan966x_port_set_mac_address()
172 struct lan966x *lan966x = port->lan966x; in lan966x_port_open() local
184 lan966x, ANA_PORT_CFG(port->chip_port)); in lan966x_port_open()
208 static int lan966x_port_inj_status(struct lan966x *lan966x) in lan966x_port_inj_status() argument
210 return lan_rd(lan966x, QS_INJ_STATUS); in lan966x_port_inj_status()
213 static int lan966x_port_inj_ready(struct lan966x *lan966x, u8 grp) in lan966x_port_inj_ready() argument
217 if (lan_rd(lan966x, QS_INJ_STATUS) & QS_INJ_STATUS_FIFO_RDY_SET(BIT(grp))) in lan966x_port_inj_ready()
220 return readx_poll_timeout_atomic(lan966x_port_inj_status, lan966x, val, in lan966x_port_inj_ready()
230 struct lan966x *lan966x = port->lan966x; in lan966x_port_ifh_xmit() local
236 val = lan_rd(lan966x, QS_INJ_STATUS); in lan966x_port_ifh_xmit()
244 lan966x, QS_INJ_CTRL(grp)); in lan966x_port_ifh_xmit()
249 err = lan966x_port_inj_ready(lan966x, grp); in lan966x_port_ifh_xmit()
253 lan_wr((__force u32)ifh[i], lan966x, QS_INJ_WR(grp)); in lan966x_port_ifh_xmit()
261 err = lan966x_port_inj_ready(lan966x, grp); in lan966x_port_ifh_xmit()
265 lan_wr(((u32 *)skb->data)[i], lan966x, QS_INJ_WR(grp)); in lan966x_port_ifh_xmit()
271 err = lan966x_port_inj_ready(lan966x, grp); in lan966x_port_ifh_xmit()
275 lan_wr(0, lan966x, QS_INJ_WR(grp)); in lan966x_port_ifh_xmit()
284 lan966x, QS_INJ_CTRL(grp)); in lan966x_port_ifh_xmit()
287 lan_wr(0, lan966x, QS_INJ_WR(grp)); in lan966x_port_ifh_xmit()
370 struct lan966x *lan966x = port->lan966x; in lan966x_port_xmit() local
382 if (port->lan966x->ptp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { in lan966x_port_xmit()
392 spin_lock(&lan966x->tx_lock); in lan966x_port_xmit()
393 if (port->lan966x->fdma) in lan966x_port_xmit()
397 spin_unlock(&lan966x->tx_lock); in lan966x_port_xmit()
405 struct lan966x *lan966x = port->lan966x; in lan966x_port_change_mtu() local
410 lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); in lan966x_port_change_mtu()
413 if (!lan966x->fdma) in lan966x_port_change_mtu()
416 err = lan966x_fdma_change_mtu(lan966x); in lan966x_port_change_mtu()
419 lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); in lan966x_port_change_mtu()
429 struct lan966x *lan966x = port->lan966x; in lan966x_mc_unsync() local
431 return lan966x_mac_forget(lan966x, addr, HOST_PVID, ENTRYTYPE_LOCKED); in lan966x_mc_unsync()
437 struct lan966x *lan966x = port->lan966x; in lan966x_mc_sync() local
439 return lan966x_mac_cpu_learn(lan966x, addr, HOST_PVID); in lan966x_mc_sync()
451 struct lan966x *lan966x = port->lan966x; in lan966x_port_get_parent_id() local
453 ppid->id_len = sizeof(lan966x->base_mac); in lan966x_port_get_parent_id()
454 memcpy(&ppid->id, &lan966x->base_mac, ppid->id_len); in lan966x_port_get_parent_id()
464 if (!port->lan966x->ptp) in lan966x_port_hwtstamp_get()
483 if (cfg->source == HWTSTAMP_SOURCE_NETDEV && !port->lan966x->ptp) in lan966x_port_hwtstamp_set()
524 bool lan966x_hw_offload(struct lan966x *lan966x, u32 port, struct sk_buff *skb) in lan966x_hw_offload() argument
532 val = lan_rd(lan966x, ANA_CPU_FWD_CFG(port)); in lan966x_hw_offload()
556 static int lan966x_port_xtr_status(struct lan966x *lan966x, u8 grp) in lan966x_port_xtr_status() argument
558 return lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_port_xtr_status()
561 static int lan966x_port_xtr_ready(struct lan966x *lan966x, u8 grp) in lan966x_port_xtr_ready() argument
568 lan966x, grp); in lan966x_port_xtr_ready()
571 static int lan966x_rx_frame_word(struct lan966x *lan966x, u8 grp, u32 *rval) in lan966x_rx_frame_word() argument
577 val = lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_rx_frame_word()
579 err = lan966x_port_xtr_ready(lan966x, grp); in lan966x_rx_frame_word()
593 val = lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_rx_frame_word()
595 *rval = lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_rx_frame_word()
601 *rval = lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_rx_frame_word()
647 struct lan966x *lan966x = args; in lan966x_xtr_irq_handler() local
650 if (!(lan_rd(lan966x, QS_XTR_DATA_PRESENT) & BIT(grp))) in lan966x_xtr_irq_handler()
663 err = lan966x_rx_frame_word(lan966x, grp, &ifh[i]); in lan966x_xtr_irq_handler()
674 WARN_ON(src_port >= lan966x->num_phys_ports); in lan966x_xtr_irq_handler()
676 dev = lan966x->ports[src_port]->dev; in lan966x_xtr_irq_handler()
687 sz = lan966x_rx_frame_word(lan966x, grp, &val); in lan966x_xtr_irq_handler()
698 sz = lan966x_rx_frame_word(lan966x, grp, &val); in lan966x_xtr_irq_handler()
712 lan966x_ptp_rxtstamp(lan966x, skb, src_port, timestamp); in lan966x_xtr_irq_handler()
715 if (lan966x->bridge_mask & BIT(src_port)) { in lan966x_xtr_irq_handler()
719 if (!lan966x_hw_offload(lan966x, src_port, skb)) in lan966x_xtr_irq_handler()
731 lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_xtr_irq_handler()
733 } while (lan_rd(lan966x, QS_XTR_DATA_PRESENT) & BIT(grp)); in lan966x_xtr_irq_handler()
740 struct lan966x *lan966x = args; in lan966x_ana_irq_handler() local
742 return lan966x_mac_irq_handler(lan966x); in lan966x_ana_irq_handler()
745 static void lan966x_cleanup_ports(struct lan966x *lan966x) in lan966x_cleanup_ports() argument
750 for (p = 0; p < lan966x->num_phys_ports; p++) { in lan966x_cleanup_ports()
751 port = lan966x->ports[p]; in lan966x_cleanup_ports()
759 if (lan966x->fdma && lan966x->fdma_ndev == port->dev) in lan966x_cleanup_ports()
760 lan966x_fdma_netdev_deinit(lan966x, port->dev); in lan966x_cleanup_ports()
774 disable_irq(lan966x->xtr_irq); in lan966x_cleanup_ports()
775 lan966x->xtr_irq = -ENXIO; in lan966x_cleanup_ports()
777 if (lan966x->ana_irq > 0) { in lan966x_cleanup_ports()
778 disable_irq(lan966x->ana_irq); in lan966x_cleanup_ports()
779 lan966x->ana_irq = -ENXIO; in lan966x_cleanup_ports()
782 if (lan966x->fdma) in lan966x_cleanup_ports()
783 devm_free_irq(lan966x->dev, lan966x->fdma_irq, lan966x); in lan966x_cleanup_ports()
785 if (lan966x->ptp_irq > 0) in lan966x_cleanup_ports()
786 devm_free_irq(lan966x->dev, lan966x->ptp_irq, lan966x); in lan966x_cleanup_ports()
788 if (lan966x->ptp_ext_irq > 0) in lan966x_cleanup_ports()
789 devm_free_irq(lan966x->dev, lan966x->ptp_ext_irq, lan966x); in lan966x_cleanup_ports()
792 static int lan966x_probe_port(struct lan966x *lan966x, u32 p, in lan966x_probe_port() argument
801 if (p >= lan966x->num_phys_ports) in lan966x_probe_port()
804 dev = devm_alloc_etherdev_mqs(lan966x->dev, in lan966x_probe_port()
810 SET_NETDEV_DEV(dev, lan966x->dev); in lan966x_probe_port()
813 port->lan966x = lan966x; in lan966x_probe_port()
815 lan966x->ports[p] = port; in lan966x_probe_port()
828 eth_hw_addr_gen(dev, lan966x->base_mac, p + 1); in lan966x_probe_port()
830 lan966x_mac_learn(lan966x, PGID_CPU, dev->dev_addr, HOST_PVID, in lan966x_probe_port()
868 if (lan966x->fdma) in lan966x_probe_port()
875 dev_err(lan966x->dev, "register_netdev failed\n"); in lan966x_probe_port()
887 static void lan966x_init(struct lan966x *lan966x) in lan966x_init() argument
892 lan966x_mac_init(lan966x); in lan966x_init()
894 lan966x_vlan_init(lan966x); in lan966x_init()
897 lan_wr(lan_rd(lan966x, QS_XTR_FLUSH) | in lan966x_init()
899 lan966x, QS_XTR_FLUSH); in lan966x_init()
905 lan_wr(lan_rd(lan966x, QS_XTR_FLUSH) & in lan966x_init()
907 lan966x, QS_XTR_FLUSH); in lan966x_init()
913 lan966x, ANA_AUTOAGE); in lan966x_init()
918 lan966x, ANA_ADVLEARN); in lan966x_init()
920 /* Setup frame ageing - "2 sec" - The unit is 6.5 us on lan966x */ in lan966x_init()
923 lan966x, SYS_FRM_AGING); in lan966x_init()
926 lan_wr(0, lan966x, QSYS_CPU_GROUP_MAP); in lan966x_init()
931 lan_wr(QS_XTR_GRP_CFG_MODE_SET(lan966x->fdma ? 2 : 1) | in lan966x_init()
933 lan966x, QS_XTR_GRP_CFG(0)); in lan966x_init()
936 lan_wr(QS_INJ_GRP_CFG_MODE_SET(lan966x->fdma ? 2 : 1) | in lan966x_init()
938 lan966x, QS_INJ_GRP_CFG(0)); in lan966x_init()
942 lan966x, QS_INJ_CTRL(0)); in lan966x_init()
947 lan966x, SYS_PORT_MODE(CPU_PORT)); in lan966x_init()
954 lan966x, ANA_FLOODING_IPMC); in lan966x_init()
964 lan966x, ANA_FLOODING(i)); in lan966x_init()
970 lan966x, ANA_PGID_CFG(i)); in lan966x_init()
972 for (p = 0; p < lan966x->num_phys_ports; p++) { in lan966x_init()
976 lan966x, ANA_PGID(p + PGID_SRC)); in lan966x_init()
981 lan_wr(0xffff, lan966x, ANA_CPU_FWD_BPDU_CFG(p)); in lan966x_init()
986 lan_wr(1500 / 64, lan966x, QSYS_RES_CFG(i)); in lan966x_init()
987 lan_wr(1500 / 64, lan966x, QSYS_RES_CFG(512 + i)); in lan966x_init()
994 lan966x, QSYS_SW_PORT_MODE(CPU_PORT)); in lan966x_init()
999 lan966x, ANA_PGID(CPU_PORT)); in lan966x_init()
1002 lan966x, ANA_PGID(PGID_CPU)); in lan966x_init()
1005 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
1007 lan966x, ANA_PGID(PGID_MC)); in lan966x_init()
1010 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
1012 lan966x, ANA_PGID(PGID_MCIPV4)); in lan966x_init()
1014 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
1016 lan966x, ANA_PGID(PGID_MCIPV6)); in lan966x_init()
1019 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
1021 lan966x, ANA_PGID(PGID_UC)); in lan966x_init()
1024 lan_rmw(ANA_PGID_PGID_SET(BIT(CPU_PORT) | GENMASK(lan966x->num_phys_ports - 1, 0)), in lan966x_init()
1026 lan966x, ANA_PGID(PGID_BC)); in lan966x_init()
1029 lan966x, REW_PORT_CFG(CPU_PORT)); in lan966x_init()
1033 lan966x, ANA_ANAINTR); in lan966x_init()
1035 spin_lock_init(&lan966x->tx_lock); in lan966x_init()
1037 lan966x_taprio_init(lan966x); in lan966x_init()
1040 static int lan966x_ram_init(struct lan966x *lan966x) in lan966x_ram_init() argument
1042 return lan_rd(lan966x, SYS_RAM_INIT); in lan966x_ram_init()
1045 static int lan966x_reset_switch(struct lan966x *lan966x) in lan966x_reset_switch() argument
1051 switch_reset = devm_reset_control_get_optional_shared(lan966x->dev, in lan966x_reset_switch()
1054 return dev_err_probe(lan966x->dev, PTR_ERR(switch_reset), in lan966x_reset_switch()
1066 if (lan_rd(lan966x, SYS_RESET_CFG) & SYS_RESET_CFG_CORE_ENA) in lan966x_reset_switch()
1069 lan_wr(SYS_RESET_CFG_CORE_ENA_SET(0), lan966x, SYS_RESET_CFG); in lan966x_reset_switch()
1070 lan_wr(SYS_RAM_INIT_RAM_INIT_SET(1), lan966x, SYS_RAM_INIT); in lan966x_reset_switch()
1071 ret = readx_poll_timeout(lan966x_ram_init, lan966x, in lan966x_reset_switch()
1077 lan_wr(SYS_RESET_CFG_CORE_ENA_SET(1), lan966x, SYS_RESET_CFG); in lan966x_reset_switch()
1085 struct lan966x *lan966x; in lan966x_probe() local
1089 lan966x = devm_kzalloc(&pdev->dev, sizeof(*lan966x), GFP_KERNEL); in lan966x_probe()
1090 if (!lan966x) in lan966x_probe()
1093 platform_set_drvdata(pdev, lan966x); in lan966x_probe()
1094 lan966x->dev = &pdev->dev; in lan966x_probe()
1097 ether_addr_copy(lan966x->base_mac, mac_addr); in lan966x_probe()
1100 eth_random_addr(lan966x->base_mac); in lan966x_probe()
1101 lan966x->base_mac[5] &= 0xf0; in lan966x_probe()
1104 err = lan966x_create_targets(pdev, lan966x); in lan966x_probe()
1109 err = lan966x_reset_switch(lan966x); in lan966x_probe()
1113 lan966x->num_phys_ports = NUM_PHYS_PORTS; in lan966x_probe()
1114 lan966x->ports = devm_kcalloc(&pdev->dev, lan966x->num_phys_ports, in lan966x_probe()
1117 if (!lan966x->ports) in lan966x_probe()
1121 lan966x->shared_queue_sz = LAN966X_BUFFER_MEMORY; in lan966x_probe()
1124 lan966x->xtr_irq = platform_get_irq_byname(pdev, "xtr"); in lan966x_probe()
1125 if (lan966x->xtr_irq < 0) in lan966x_probe()
1126 return lan966x->xtr_irq; in lan966x_probe()
1128 err = devm_request_threaded_irq(&pdev->dev, lan966x->xtr_irq, NULL, in lan966x_probe()
1130 "frame extraction", lan966x); in lan966x_probe()
1136 lan966x->ana_irq = platform_get_irq_byname(pdev, "ana"); in lan966x_probe()
1137 if (lan966x->ana_irq > 0) { in lan966x_probe()
1138 err = devm_request_threaded_irq(&pdev->dev, lan966x->ana_irq, NULL, in lan966x_probe()
1140 "ana irq", lan966x); in lan966x_probe()
1145 lan966x->ptp_irq = platform_get_irq_byname(pdev, "ptp"); in lan966x_probe()
1146 if (lan966x->ptp_irq > 0) { in lan966x_probe()
1147 err = devm_request_threaded_irq(&pdev->dev, lan966x->ptp_irq, NULL, in lan966x_probe()
1149 "ptp irq", lan966x); in lan966x_probe()
1153 lan966x->ptp = 1; in lan966x_probe()
1156 lan966x->fdma_irq = platform_get_irq_byname(pdev, "fdma"); in lan966x_probe()
1157 if (lan966x->fdma_irq > 0) { in lan966x_probe()
1158 err = devm_request_irq(&pdev->dev, lan966x->fdma_irq, in lan966x_probe()
1160 "fdma irq", lan966x); in lan966x_probe()
1164 lan966x->fdma = true; in lan966x_probe()
1167 if (lan966x->ptp) { in lan966x_probe()
1168 lan966x->ptp_ext_irq = platform_get_irq_byname(pdev, "ptp-ext"); in lan966x_probe()
1169 if (lan966x->ptp_ext_irq > 0) { in lan966x_probe()
1171 lan966x->ptp_ext_irq, NULL, in lan966x_probe()
1174 "ptp-ext irq", lan966x); in lan966x_probe()
1186 lan966x->debugfs_root = debugfs_create_dir("lan966x", NULL); in lan966x_probe()
1189 lan966x_init(lan966x); in lan966x_probe()
1190 lan966x_stats_init(lan966x); in lan966x_probe()
1202 err = lan966x_probe_port(lan966x, p, phy_mode, portnp); in lan966x_probe()
1207 lan966x->ports[p]->config.portmode = phy_mode; in lan966x_probe()
1208 lan966x->ports[p]->fwnode = fwnode_handle_get(portnp); in lan966x_probe()
1210 serdes = devm_of_phy_optional_get(lan966x->dev, in lan966x_probe()
1216 lan966x->ports[p]->serdes = serdes; in lan966x_probe()
1218 lan966x_port_init(lan966x->ports[p]); in lan966x_probe()
1219 err = lan966x_xdp_port_init(lan966x->ports[p]); in lan966x_probe()
1226 lan966x_mdb_init(lan966x); in lan966x_probe()
1227 err = lan966x_fdb_init(lan966x); in lan966x_probe()
1231 err = lan966x_ptp_init(lan966x); in lan966x_probe()
1235 err = lan966x_fdma_init(lan966x); in lan966x_probe()
1239 err = lan966x_vcap_init(lan966x); in lan966x_probe()
1243 lan966x_dcb_init(lan966x); in lan966x_probe()
1248 lan966x_fdma_deinit(lan966x); in lan966x_probe()
1251 lan966x_ptp_deinit(lan966x); in lan966x_probe()
1254 lan966x_fdb_deinit(lan966x); in lan966x_probe()
1260 lan966x_cleanup_ports(lan966x); in lan966x_probe()
1262 cancel_delayed_work_sync(&lan966x->stats_work); in lan966x_probe()
1263 destroy_workqueue(lan966x->stats_queue); in lan966x_probe()
1265 debugfs_remove_recursive(lan966x->debugfs_root); in lan966x_probe()
1272 struct lan966x *lan966x = platform_get_drvdata(pdev); in lan966x_remove() local
1274 lan966x_taprio_deinit(lan966x); in lan966x_remove()
1275 lan966x_vcap_deinit(lan966x); in lan966x_remove()
1276 lan966x_fdma_deinit(lan966x); in lan966x_remove()
1277 lan966x_cleanup_ports(lan966x); in lan966x_remove()
1279 cancel_delayed_work_sync(&lan966x->stats_work); in lan966x_remove()
1280 destroy_workqueue(lan966x->stats_queue); in lan966x_remove()
1282 lan966x_mac_purge_entries(lan966x); in lan966x_remove()
1283 lan966x_mdb_deinit(lan966x); in lan966x_remove()
1284 lan966x_fdb_deinit(lan966x); in lan966x_remove()
1285 lan966x_ptp_deinit(lan966x); in lan966x_remove()
1287 debugfs_remove_recursive(lan966x->debugfs_root); in lan966x_remove()
1294 .name = "lan966x-switch",
1325 MODULE_DESCRIPTION("Microchip LAN966X switch driver");