Lines Matching +full:lan966x +full:- +full:serdes
1 // SPDX-License-Identifier: GPL-2.0+
25 #define XTR_VALID_BYTES(x) (4 - (((x) >> 24) & 3))
30 { .compatible = "microchip,lan966x-switch" },
65 struct lan966x *lan966x) in lan966x_create_targets() argument
80 dev_err(&pdev->dev, "Invalid resource\n"); in lan966x_create_targets()
81 return -EINVAL; in lan966x_create_targets()
84 begin[idx] = devm_ioremap(&pdev->dev, in lan966x_create_targets()
85 iores[idx]->start, in lan966x_create_targets()
88 dev_err(&pdev->dev, "Unable to get registers: %s\n", in lan966x_create_targets()
89 iores[idx]->name); in lan966x_create_targets()
90 return -ENOMEM; in lan966x_create_targets()
98 lan966x->regs[iomap->id] = begin[iomap->range] + iomap->offset; in lan966x_create_targets()
107 struct lan966x *lan966x = port->lan966x; in lan966x_port_unique_address() local
110 for (p = 0; p < lan966x->num_phys_ports; ++p) { in lan966x_port_unique_address()
111 port = lan966x->ports[p]; in lan966x_port_unique_address()
112 if (!port || port->dev == dev) in lan966x_port_unique_address()
115 if (ether_addr_equal(dev->dev_addr, port->dev->dev_addr)) in lan966x_port_unique_address()
125 struct lan966x *lan966x = port->lan966x; in lan966x_port_set_mac_address() local
129 if (ether_addr_equal(addr->sa_data, dev->dev_addr)) in lan966x_port_set_mac_address()
133 ret = lan966x_mac_cpu_learn(lan966x, addr->sa_data, HOST_PVID); in lan966x_port_set_mac_address()
144 ret = lan966x_mac_cpu_forget(lan966x, dev->dev_addr, HOST_PVID); in lan966x_port_set_mac_address()
149 eth_hw_addr_set(dev, addr->sa_data); in lan966x_port_set_mac_address()
159 ret = snprintf(buf, len, "p%d", port->chip_port); in lan966x_port_get_phys_port_name()
161 return -EINVAL; in lan966x_port_get_phys_port_name()
169 struct lan966x *lan966x = port->lan966x; in lan966x_port_open() local
172 /* Enable receiving frames on the port, and activate auto-learning of in lan966x_port_open()
177 ANA_PORT_CFG_PORTID_VAL_SET(port->chip_port), in lan966x_port_open()
181 lan966x, ANA_PORT_CFG(port->chip_port)); in lan966x_port_open()
183 err = phylink_fwnode_phy_connect(port->phylink, port->fwnode, 0); in lan966x_port_open()
189 phylink_start(port->phylink); in lan966x_port_open()
199 phylink_stop(port->phylink); in lan966x_port_stop()
200 phylink_disconnect_phy(port->phylink); in lan966x_port_stop()
205 static int lan966x_port_inj_status(struct lan966x *lan966x) in lan966x_port_inj_status() argument
207 return lan_rd(lan966x, QS_INJ_STATUS); in lan966x_port_inj_status()
210 static int lan966x_port_inj_ready(struct lan966x *lan966x, u8 grp) in lan966x_port_inj_ready() argument
214 if (lan_rd(lan966x, QS_INJ_STATUS) & QS_INJ_STATUS_FIFO_RDY_SET(BIT(grp))) in lan966x_port_inj_ready()
217 return readx_poll_timeout_atomic(lan966x_port_inj_status, lan966x, val, in lan966x_port_inj_ready()
227 struct lan966x *lan966x = port->lan966x; in lan966x_port_ifh_xmit() local
233 val = lan_rd(lan966x, QS_INJ_STATUS); in lan966x_port_ifh_xmit()
241 lan966x, QS_INJ_CTRL(grp)); in lan966x_port_ifh_xmit()
246 err = lan966x_port_inj_ready(lan966x, grp); in lan966x_port_ifh_xmit()
250 lan_wr((__force u32)ifh[i], lan966x, QS_INJ_WR(grp)); in lan966x_port_ifh_xmit()
254 count = DIV_ROUND_UP(skb->len, 4); in lan966x_port_ifh_xmit()
255 last = skb->len % 4; in lan966x_port_ifh_xmit()
258 err = lan966x_port_inj_ready(lan966x, grp); in lan966x_port_ifh_xmit()
262 lan_wr(((u32 *)skb->data)[i], lan966x, QS_INJ_WR(grp)); in lan966x_port_ifh_xmit()
268 err = lan966x_port_inj_ready(lan966x, grp); in lan966x_port_ifh_xmit()
272 lan_wr(0, lan966x, QS_INJ_WR(grp)); in lan966x_port_ifh_xmit()
278 QS_INJ_CTRL_VLD_BYTES_SET(skb->len < LAN966X_BUFFER_MIN_SZ ? in lan966x_port_ifh_xmit()
281 lan966x, QS_INJ_CTRL(grp)); in lan966x_port_ifh_xmit()
284 lan_wr(0, lan966x, QS_INJ_WR(grp)); in lan966x_port_ifh_xmit()
287 dev->stats.tx_packets++; in lan966x_port_ifh_xmit()
288 dev->stats.tx_bytes += skb->len; in lan966x_port_ifh_xmit()
290 if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && in lan966x_port_ifh_xmit()
291 LAN966X_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP) in lan966x_port_ifh_xmit()
298 if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && in lan966x_port_ifh_xmit()
299 LAN966X_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP) in lan966x_port_ifh_xmit()
307 packing(ifh, &bypass, IFH_POS_BYPASS + IFH_WID_BYPASS - 1, in lan966x_ifh_set_bypass()
313 packing(ifh, &bypass, IFH_POS_DSTS + IFH_WID_DSTS - 1, in lan966x_ifh_set_port()
319 packing(ifh, &bypass, IFH_POS_QOS_CLASS + IFH_WID_QOS_CLASS - 1, in lan966x_ifh_set_qos_class()
325 packing(ifh, &bypass, IFH_POS_IPV + IFH_WID_IPV - 1, in lan966x_ifh_set_ipv()
331 packing(ifh, &vid, IFH_POS_TCI + IFH_WID_TCI - 1, in lan966x_ifh_set_vid()
337 packing(ifh, &rew_op, IFH_POS_REW_CMD + IFH_WID_REW_CMD - 1, in lan966x_ifh_set_rew_op()
343 packing(ifh, ×tamp, IFH_POS_TIMESTAMP + IFH_WID_TIMESTAMP - 1, in lan966x_ifh_set_timestamp()
351 struct lan966x *lan966x = port->lan966x; in lan966x_port_xmit() local
358 lan966x_ifh_set_port(ifh, BIT_ULL(port->chip_port)); in lan966x_port_xmit()
359 lan966x_ifh_set_qos_class(ifh, skb->priority >= 7 ? 0x7 : skb->priority); in lan966x_port_xmit()
360 lan966x_ifh_set_ipv(ifh, skb->priority >= 7 ? 0x7 : skb->priority); in lan966x_port_xmit()
363 if (port->lan966x->ptp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { in lan966x_port_xmit()
368 lan966x_ifh_set_rew_op(ifh, LAN966X_SKB_CB(skb)->rew_op); in lan966x_port_xmit()
369 lan966x_ifh_set_timestamp(ifh, LAN966X_SKB_CB(skb)->ts_id); in lan966x_port_xmit()
372 spin_lock(&lan966x->tx_lock); in lan966x_port_xmit()
373 if (port->lan966x->fdma) in lan966x_port_xmit()
377 spin_unlock(&lan966x->tx_lock); in lan966x_port_xmit()
385 struct lan966x *lan966x = port->lan966x; in lan966x_port_change_mtu() local
386 int old_mtu = dev->mtu; in lan966x_port_change_mtu()
390 lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); in lan966x_port_change_mtu()
391 dev->mtu = new_mtu; in lan966x_port_change_mtu()
393 if (!lan966x->fdma) in lan966x_port_change_mtu()
396 err = lan966x_fdma_change_mtu(lan966x); in lan966x_port_change_mtu()
399 lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); in lan966x_port_change_mtu()
400 dev->mtu = old_mtu; in lan966x_port_change_mtu()
409 struct lan966x *lan966x = port->lan966x; in lan966x_mc_unsync() local
411 return lan966x_mac_forget(lan966x, addr, HOST_PVID, ENTRYTYPE_LOCKED); in lan966x_mc_unsync()
417 struct lan966x *lan966x = port->lan966x; in lan966x_mc_sync() local
419 return lan966x_mac_cpu_learn(lan966x, addr, HOST_PVID); in lan966x_mc_sync()
431 struct lan966x *lan966x = port->lan966x; in lan966x_port_get_parent_id() local
433 ppid->id_len = sizeof(lan966x->base_mac); in lan966x_port_get_parent_id()
434 memcpy(&ppid->id, &lan966x->base_mac, ppid->id_len); in lan966x_port_get_parent_id()
444 if (!phy_has_hwtstamp(dev->phydev) && port->lan966x->ptp) { in lan966x_port_ioctl()
453 if (!dev->phydev) in lan966x_port_ioctl()
454 return -ENODEV; in lan966x_port_ioctl()
456 return phy_mii_ioctl(dev->phydev, ifr, cmd); in lan966x_port_ioctl()
475 return dev->netdev_ops == &lan966x_port_netdev_ops; in lan966x_netdevice_check()
478 bool lan966x_hw_offload(struct lan966x *lan966x, u32 port, struct sk_buff *skb) in lan966x_hw_offload() argument
486 val = lan_rd(lan966x, ANA_CPU_FWD_CFG(port)); in lan966x_hw_offload()
491 if (eth_type_vlan(skb->protocol)) { in lan966x_hw_offload()
497 if (skb->protocol == htons(ETH_P_IP) && in lan966x_hw_offload()
498 ip_hdr(skb)->protocol == IPPROTO_IGMP) in lan966x_hw_offload()
502 skb->protocol == htons(ETH_P_IPV6) && in lan966x_hw_offload()
503 ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) && in lan966x_hw_offload()
510 static int lan966x_port_xtr_status(struct lan966x *lan966x, u8 grp) in lan966x_port_xtr_status() argument
512 return lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_port_xtr_status()
515 static int lan966x_port_xtr_ready(struct lan966x *lan966x, u8 grp) in lan966x_port_xtr_ready() argument
522 lan966x, grp); in lan966x_port_xtr_ready()
525 static int lan966x_rx_frame_word(struct lan966x *lan966x, u8 grp, u32 *rval) in lan966x_rx_frame_word() argument
531 val = lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_rx_frame_word()
533 err = lan966x_port_xtr_ready(lan966x, grp); in lan966x_rx_frame_word()
535 return -EIO; in lan966x_rx_frame_word()
540 return -EIO; in lan966x_rx_frame_word()
547 val = lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_rx_frame_word()
549 *rval = lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_rx_frame_word()
555 *rval = lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_rx_frame_word()
567 packing(ifh, src_port, IFH_POS_SRCPORT + IFH_WID_SRCPORT - 1, in lan966x_ifh_get_src_port()
573 packing(ifh, len, IFH_POS_LEN + IFH_WID_LEN - 1, in lan966x_ifh_get_len()
579 packing(ifh, timestamp, IFH_POS_TIMESTAMP + IFH_WID_TIMESTAMP - 1, in lan966x_ifh_get_timestamp()
585 struct lan966x *lan966x = args; in lan966x_xtr_irq_handler() local
588 if (!(lan_rd(lan966x, QS_XTR_DATA_PRESENT) & BIT(grp))) in lan966x_xtr_irq_handler()
601 err = lan966x_rx_frame_word(lan966x, grp, &ifh[i]); in lan966x_xtr_irq_handler()
612 WARN_ON(src_port >= lan966x->num_phys_ports); in lan966x_xtr_irq_handler()
614 dev = lan966x->ports[src_port]->dev; in lan966x_xtr_irq_handler()
618 err = -ENOMEM; in lan966x_xtr_irq_handler()
621 buf_len = len - ETH_FCS_LEN; in lan966x_xtr_irq_handler()
626 sz = lan966x_rx_frame_word(lan966x, grp, &val); in lan966x_xtr_irq_handler()
637 sz = lan966x_rx_frame_word(lan966x, grp, &val); in lan966x_xtr_irq_handler()
644 len -= ETH_FCS_LEN - sz; in lan966x_xtr_irq_handler()
646 if (unlikely(dev->features & NETIF_F_RXFCS)) { in lan966x_xtr_irq_handler()
651 lan966x_ptp_rxtstamp(lan966x, skb, timestamp); in lan966x_xtr_irq_handler()
652 skb->protocol = eth_type_trans(skb, dev); in lan966x_xtr_irq_handler()
654 if (lan966x->bridge_mask & BIT(src_port)) { in lan966x_xtr_irq_handler()
655 skb->offload_fwd_mark = 1; in lan966x_xtr_irq_handler()
658 if (!lan966x_hw_offload(lan966x, src_port, skb)) in lan966x_xtr_irq_handler()
659 skb->offload_fwd_mark = 0; in lan966x_xtr_irq_handler()
665 dev->stats.rx_bytes += len; in lan966x_xtr_irq_handler()
666 dev->stats.rx_packets++; in lan966x_xtr_irq_handler()
670 lan_rd(lan966x, QS_XTR_RD(grp)); in lan966x_xtr_irq_handler()
672 } while (lan_rd(lan966x, QS_XTR_DATA_PRESENT) & BIT(grp)); in lan966x_xtr_irq_handler()
679 struct lan966x *lan966x = args; in lan966x_ana_irq_handler() local
681 return lan966x_mac_irq_handler(lan966x); in lan966x_ana_irq_handler()
684 static void lan966x_cleanup_ports(struct lan966x *lan966x) in lan966x_cleanup_ports() argument
689 for (p = 0; p < lan966x->num_phys_ports; p++) { in lan966x_cleanup_ports()
690 port = lan966x->ports[p]; in lan966x_cleanup_ports()
694 if (port->dev) in lan966x_cleanup_ports()
695 unregister_netdev(port->dev); in lan966x_cleanup_ports()
697 if (lan966x->fdma && lan966x->fdma_ndev == port->dev) in lan966x_cleanup_ports()
698 lan966x_fdma_netdev_deinit(lan966x, port->dev); in lan966x_cleanup_ports()
700 if (port->phylink) { in lan966x_cleanup_ports()
702 lan966x_port_stop(port->dev); in lan966x_cleanup_ports()
704 phylink_destroy(port->phylink); in lan966x_cleanup_ports()
705 port->phylink = NULL; in lan966x_cleanup_ports()
708 if (port->fwnode) in lan966x_cleanup_ports()
709 fwnode_handle_put(port->fwnode); in lan966x_cleanup_ports()
712 disable_irq(lan966x->xtr_irq); in lan966x_cleanup_ports()
713 lan966x->xtr_irq = -ENXIO; in lan966x_cleanup_ports()
715 if (lan966x->ana_irq > 0) { in lan966x_cleanup_ports()
716 disable_irq(lan966x->ana_irq); in lan966x_cleanup_ports()
717 lan966x->ana_irq = -ENXIO; in lan966x_cleanup_ports()
720 if (lan966x->fdma) in lan966x_cleanup_ports()
721 devm_free_irq(lan966x->dev, lan966x->fdma_irq, lan966x); in lan966x_cleanup_ports()
723 if (lan966x->ptp_irq > 0) in lan966x_cleanup_ports()
724 devm_free_irq(lan966x->dev, lan966x->ptp_irq, lan966x); in lan966x_cleanup_ports()
726 if (lan966x->ptp_ext_irq > 0) in lan966x_cleanup_ports()
727 devm_free_irq(lan966x->dev, lan966x->ptp_ext_irq, lan966x); in lan966x_cleanup_ports()
730 static int lan966x_probe_port(struct lan966x *lan966x, u32 p, in lan966x_probe_port() argument
739 if (p >= lan966x->num_phys_ports) in lan966x_probe_port()
740 return -EINVAL; in lan966x_probe_port()
742 dev = devm_alloc_etherdev_mqs(lan966x->dev, in lan966x_probe_port()
746 return -ENOMEM; in lan966x_probe_port()
748 SET_NETDEV_DEV(dev, lan966x->dev); in lan966x_probe_port()
750 port->dev = dev; in lan966x_probe_port()
751 port->lan966x = lan966x; in lan966x_probe_port()
752 port->chip_port = p; in lan966x_probe_port()
753 lan966x->ports[p] = port; in lan966x_probe_port()
755 dev->max_mtu = ETH_MAX_MTU; in lan966x_probe_port()
757 dev->netdev_ops = &lan966x_port_netdev_ops; in lan966x_probe_port()
758 dev->ethtool_ops = &lan966x_ethtool_ops; in lan966x_probe_port()
759 dev->features |= NETIF_F_HW_VLAN_CTAG_TX | in lan966x_probe_port()
762 dev->hw_features |= NETIF_F_HW_TC; in lan966x_probe_port()
763 dev->needed_headroom = IFH_LEN * sizeof(u32); in lan966x_probe_port()
765 eth_hw_addr_gen(dev, lan966x->base_mac, p + 1); in lan966x_probe_port()
767 lan966x_mac_learn(lan966x, PGID_CPU, dev->dev_addr, HOST_PVID, in lan966x_probe_port()
770 port->phylink_config.dev = &port->dev->dev; in lan966x_probe_port()
771 port->phylink_config.type = PHYLINK_NETDEV; in lan966x_probe_port()
772 port->phylink_pcs.poll = true; in lan966x_probe_port()
773 port->phylink_pcs.ops = &lan966x_phylink_pcs_ops; in lan966x_probe_port()
775 port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | in lan966x_probe_port()
778 phy_interface_set_rgmii(port->phylink_config.supported_interfaces); in lan966x_probe_port()
780 port->phylink_config.supported_interfaces); in lan966x_probe_port()
782 port->phylink_config.supported_interfaces); in lan966x_probe_port()
784 port->phylink_config.supported_interfaces); in lan966x_probe_port()
786 port->phylink_config.supported_interfaces); in lan966x_probe_port()
788 port->phylink_config.supported_interfaces); in lan966x_probe_port()
790 port->phylink_config.supported_interfaces); in lan966x_probe_port()
792 port->phylink_config.supported_interfaces); in lan966x_probe_port()
794 phylink = phylink_create(&port->phylink_config, in lan966x_probe_port()
799 port->dev = NULL; in lan966x_probe_port()
803 port->phylink = phylink; in lan966x_probe_port()
807 dev_err(lan966x->dev, "register_netdev failed\n"); in lan966x_probe_port()
818 static void lan966x_init(struct lan966x *lan966x) in lan966x_init() argument
823 lan966x_mac_init(lan966x); in lan966x_init()
825 lan966x_vlan_init(lan966x); in lan966x_init()
828 lan_wr(lan_rd(lan966x, QS_XTR_FLUSH) | in lan966x_init()
830 lan966x, QS_XTR_FLUSH); in lan966x_init()
836 lan_wr(lan_rd(lan966x, QS_XTR_FLUSH) & in lan966x_init()
838 lan966x, QS_XTR_FLUSH); in lan966x_init()
844 lan966x, ANA_AUTOAGE); in lan966x_init()
849 lan966x, ANA_ADVLEARN); in lan966x_init()
851 /* Setup frame ageing - "2 sec" - The unit is 6.5 us on lan966x */ in lan966x_init()
854 lan966x, SYS_FRM_AGING); in lan966x_init()
857 lan_wr(0, lan966x, QSYS_CPU_GROUP_MAP); in lan966x_init()
859 /* Do byte-swap and expect status after last data word in lan966x_init()
862 lan_wr(QS_XTR_GRP_CFG_MODE_SET(lan966x->fdma ? 2 : 1) | in lan966x_init()
864 lan966x, QS_XTR_GRP_CFG(0)); in lan966x_init()
867 lan_wr(QS_INJ_GRP_CFG_MODE_SET(lan966x->fdma ? 2 : 1) | in lan966x_init()
869 lan966x, QS_INJ_GRP_CFG(0)); in lan966x_init()
873 lan966x, QS_INJ_CTRL(0)); in lan966x_init()
878 lan966x, SYS_PORT_MODE(CPU_PORT)); in lan966x_init()
885 lan966x, ANA_FLOODING_IPMC); in lan966x_init()
895 lan966x, ANA_FLOODING(i)); in lan966x_init()
901 lan966x, ANA_PGID_CFG(i)); in lan966x_init()
903 for (p = 0; p < lan966x->num_phys_ports; p++) { in lan966x_init()
907 lan966x, ANA_PGID(p + PGID_SRC)); in lan966x_init()
912 lan_wr(0xffff, lan966x, ANA_CPU_FWD_BPDU_CFG(p)); in lan966x_init()
917 lan_wr(1500 / 64, lan966x, QSYS_RES_CFG(i)); in lan966x_init()
918 lan_wr(1500 / 64, lan966x, QSYS_RES_CFG(512 + i)); in lan966x_init()
925 lan966x, QSYS_SW_PORT_MODE(CPU_PORT)); in lan966x_init()
930 lan966x, ANA_PGID(CPU_PORT)); in lan966x_init()
933 lan966x, ANA_PGID(PGID_CPU)); in lan966x_init()
936 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
938 lan966x, ANA_PGID(PGID_MC)); in lan966x_init()
941 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
943 lan966x, ANA_PGID(PGID_MCIPV4)); in lan966x_init()
945 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
947 lan966x, ANA_PGID(PGID_MCIPV6)); in lan966x_init()
950 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
952 lan966x, ANA_PGID(PGID_UC)); in lan966x_init()
955 lan_rmw(ANA_PGID_PGID_SET(BIT(CPU_PORT) | GENMASK(lan966x->num_phys_ports - 1, 0)), in lan966x_init()
957 lan966x, ANA_PGID(PGID_BC)); in lan966x_init()
960 lan966x, REW_PORT_CFG(CPU_PORT)); in lan966x_init()
964 lan966x, ANA_ANAINTR); in lan966x_init()
966 spin_lock_init(&lan966x->tx_lock); in lan966x_init()
968 lan966x_taprio_init(lan966x); in lan966x_init()
971 static int lan966x_ram_init(struct lan966x *lan966x) in lan966x_ram_init() argument
973 return lan_rd(lan966x, SYS_RAM_INIT); in lan966x_ram_init()
976 static int lan966x_reset_switch(struct lan966x *lan966x) in lan966x_reset_switch() argument
982 switch_reset = devm_reset_control_get_optional_shared(lan966x->dev, in lan966x_reset_switch()
985 return dev_err_probe(lan966x->dev, PTR_ERR(switch_reset), in lan966x_reset_switch()
990 lan_wr(SYS_RESET_CFG_CORE_ENA_SET(0), lan966x, SYS_RESET_CFG); in lan966x_reset_switch()
991 lan_wr(SYS_RAM_INIT_RAM_INIT_SET(1), lan966x, SYS_RAM_INIT); in lan966x_reset_switch()
992 ret = readx_poll_timeout(lan966x_ram_init, lan966x, in lan966x_reset_switch()
998 lan_wr(SYS_RESET_CFG_CORE_ENA_SET(1), lan966x, SYS_RESET_CFG); in lan966x_reset_switch()
1006 struct lan966x *lan966x; in lan966x_probe() local
1010 lan966x = devm_kzalloc(&pdev->dev, sizeof(*lan966x), GFP_KERNEL); in lan966x_probe()
1011 if (!lan966x) in lan966x_probe()
1012 return -ENOMEM; in lan966x_probe()
1014 platform_set_drvdata(pdev, lan966x); in lan966x_probe()
1015 lan966x->dev = &pdev->dev; in lan966x_probe()
1017 if (!device_get_mac_address(&pdev->dev, mac_addr)) { in lan966x_probe()
1018 ether_addr_copy(lan966x->base_mac, mac_addr); in lan966x_probe()
1021 eth_random_addr(lan966x->base_mac); in lan966x_probe()
1022 lan966x->base_mac[5] &= 0xf0; in lan966x_probe()
1025 ports = device_get_named_child_node(&pdev->dev, "ethernet-ports"); in lan966x_probe()
1027 return dev_err_probe(&pdev->dev, -ENODEV, in lan966x_probe()
1028 "no ethernet-ports child found\n"); in lan966x_probe()
1030 err = lan966x_create_targets(pdev, lan966x); in lan966x_probe()
1032 return dev_err_probe(&pdev->dev, err, in lan966x_probe()
1035 err = lan966x_reset_switch(lan966x); in lan966x_probe()
1037 return dev_err_probe(&pdev->dev, err, "Reset failed"); in lan966x_probe()
1039 lan966x->num_phys_ports = NUM_PHYS_PORTS; in lan966x_probe()
1040 lan966x->ports = devm_kcalloc(&pdev->dev, lan966x->num_phys_ports, in lan966x_probe()
1043 if (!lan966x->ports) in lan966x_probe()
1044 return -ENOMEM; in lan966x_probe()
1047 lan966x->shared_queue_sz = LAN966X_BUFFER_MEMORY; in lan966x_probe()
1050 lan966x->xtr_irq = platform_get_irq_byname(pdev, "xtr"); in lan966x_probe()
1051 if (lan966x->xtr_irq <= 0) in lan966x_probe()
1052 return -EINVAL; in lan966x_probe()
1054 err = devm_request_threaded_irq(&pdev->dev, lan966x->xtr_irq, NULL, in lan966x_probe()
1056 "frame extraction", lan966x); in lan966x_probe()
1059 return -ENODEV; in lan966x_probe()
1062 lan966x->ana_irq = platform_get_irq_byname(pdev, "ana"); in lan966x_probe()
1063 if (lan966x->ana_irq > 0) { in lan966x_probe()
1064 err = devm_request_threaded_irq(&pdev->dev, lan966x->ana_irq, NULL, in lan966x_probe()
1066 "ana irq", lan966x); in lan966x_probe()
1068 return dev_err_probe(&pdev->dev, err, "Unable to use ana irq"); in lan966x_probe()
1071 lan966x->ptp_irq = platform_get_irq_byname(pdev, "ptp"); in lan966x_probe()
1072 if (lan966x->ptp_irq > 0) { in lan966x_probe()
1073 err = devm_request_threaded_irq(&pdev->dev, lan966x->ptp_irq, NULL, in lan966x_probe()
1075 "ptp irq", lan966x); in lan966x_probe()
1077 return dev_err_probe(&pdev->dev, err, "Unable to use ptp irq"); in lan966x_probe()
1079 lan966x->ptp = 1; in lan966x_probe()
1082 lan966x->fdma_irq = platform_get_irq_byname(pdev, "fdma"); in lan966x_probe()
1083 if (lan966x->fdma_irq > 0) { in lan966x_probe()
1084 err = devm_request_irq(&pdev->dev, lan966x->fdma_irq, in lan966x_probe()
1086 "fdma irq", lan966x); in lan966x_probe()
1088 return dev_err_probe(&pdev->dev, err, "Unable to use fdma irq"); in lan966x_probe()
1090 lan966x->fdma = true; in lan966x_probe()
1093 if (lan966x->ptp) { in lan966x_probe()
1094 lan966x->ptp_ext_irq = platform_get_irq_byname(pdev, "ptp-ext"); in lan966x_probe()
1095 if (lan966x->ptp_ext_irq > 0) { in lan966x_probe()
1096 err = devm_request_threaded_irq(&pdev->dev, in lan966x_probe()
1097 lan966x->ptp_ext_irq, NULL, in lan966x_probe()
1100 "ptp-ext irq", lan966x); in lan966x_probe()
1102 return dev_err_probe(&pdev->dev, err, in lan966x_probe()
1103 "Unable to use ptp-ext irq"); in lan966x_probe()
1108 lan966x_init(lan966x); in lan966x_probe()
1109 lan966x_stats_init(lan966x); in lan966x_probe()
1114 struct phy *serdes; in lan966x_probe() local
1121 err = lan966x_probe_port(lan966x, p, phy_mode, portnp); in lan966x_probe()
1126 lan966x->ports[p]->config.portmode = phy_mode; in lan966x_probe()
1127 lan966x->ports[p]->fwnode = fwnode_handle_get(portnp); in lan966x_probe()
1129 serdes = devm_of_phy_get(lan966x->dev, to_of_node(portnp), NULL); in lan966x_probe()
1130 if (PTR_ERR(serdes) == -ENODEV) in lan966x_probe()
1131 serdes = NULL; in lan966x_probe()
1132 if (IS_ERR(serdes)) { in lan966x_probe()
1133 err = PTR_ERR(serdes); in lan966x_probe()
1136 lan966x->ports[p]->serdes = serdes; in lan966x_probe()
1138 lan966x_port_init(lan966x->ports[p]); in lan966x_probe()
1141 lan966x_mdb_init(lan966x); in lan966x_probe()
1142 err = lan966x_fdb_init(lan966x); in lan966x_probe()
1146 err = lan966x_ptp_init(lan966x); in lan966x_probe()
1150 err = lan966x_fdma_init(lan966x); in lan966x_probe()
1157 lan966x_ptp_deinit(lan966x); in lan966x_probe()
1160 lan966x_fdb_deinit(lan966x); in lan966x_probe()
1165 lan966x_cleanup_ports(lan966x); in lan966x_probe()
1167 cancel_delayed_work_sync(&lan966x->stats_work); in lan966x_probe()
1168 destroy_workqueue(lan966x->stats_queue); in lan966x_probe()
1169 mutex_destroy(&lan966x->stats_lock); in lan966x_probe()
1176 struct lan966x *lan966x = platform_get_drvdata(pdev); in lan966x_remove() local
1178 lan966x_taprio_deinit(lan966x); in lan966x_remove()
1179 lan966x_fdma_deinit(lan966x); in lan966x_remove()
1180 lan966x_cleanup_ports(lan966x); in lan966x_remove()
1182 cancel_delayed_work_sync(&lan966x->stats_work); in lan966x_remove()
1183 destroy_workqueue(lan966x->stats_queue); in lan966x_remove()
1184 mutex_destroy(&lan966x->stats_lock); in lan966x_remove()
1186 lan966x_mac_purge_entries(lan966x); in lan966x_remove()
1187 lan966x_mdb_deinit(lan966x); in lan966x_remove()
1188 lan966x_fdb_deinit(lan966x); in lan966x_remove()
1189 lan966x_ptp_deinit(lan966x); in lan966x_remove()
1198 .name = "lan966x-switch",
1229 MODULE_DESCRIPTION("Microchip LAN966X switch driver");