Lines Matching +full:ext +full:- +full:irq +full:- +full:range

1 // SPDX-License-Identifier: GPL-2.0+
25 #define XTR_VALID_BYTES(x) (4 - (((x) >> 24) & 3))
30 { .compatible = "microchip,lan966x-switch" },
38 int range; member
74 /* Initially map the entire range and after that update each target to in lan966x_create_targets()
83 dev_err(&pdev->dev, "Invalid resource\n"); in lan966x_create_targets()
84 return -EINVAL; in lan966x_create_targets()
87 begin[idx] = devm_ioremap(&pdev->dev, in lan966x_create_targets()
88 iores[idx]->start, in lan966x_create_targets()
91 dev_err(&pdev->dev, "Unable to get registers: %s\n", in lan966x_create_targets()
92 iores[idx]->name); in lan966x_create_targets()
93 return -ENOMEM; in lan966x_create_targets()
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()
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()
115 if (!port || port->dev == dev) in lan966x_port_unique_address()
118 if (ether_addr_equal(dev->dev_addr, port->dev->dev_addr)) in lan966x_port_unique_address()
128 struct lan966x *lan966x = port->lan966x; in lan966x_port_set_mac_address()
132 if (ether_addr_equal(addr->sa_data, dev->dev_addr)) in lan966x_port_set_mac_address()
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()
152 eth_hw_addr_set(dev, addr->sa_data); in lan966x_port_set_mac_address()
162 ret = snprintf(buf, len, "p%d", port->chip_port); in lan966x_port_get_phys_port_name()
164 return -EINVAL; in lan966x_port_get_phys_port_name()
172 struct lan966x *lan966x = port->lan966x; in lan966x_port_open()
175 /* Enable receiving frames on the port, and activate auto-learning of in lan966x_port_open()
180 ANA_PORT_CFG_PORTID_VAL_SET(port->chip_port), in lan966x_port_open()
184 lan966x, ANA_PORT_CFG(port->chip_port)); in lan966x_port_open()
186 err = phylink_fwnode_phy_connect(port->phylink, port->fwnode, 0); in lan966x_port_open()
192 phylink_start(port->phylink); in lan966x_port_open()
202 phylink_stop(port->phylink); in lan966x_port_stop()
203 phylink_disconnect_phy(port->phylink); in lan966x_port_stop()
230 struct lan966x *lan966x = port->lan966x; in lan966x_port_ifh_xmit()
257 count = DIV_ROUND_UP(skb->len, 4); in lan966x_port_ifh_xmit()
258 last = skb->len % 4; in lan966x_port_ifh_xmit()
265 lan_wr(((u32 *)skb->data)[i], lan966x, QS_INJ_WR(grp)); in lan966x_port_ifh_xmit()
281 QS_INJ_CTRL_VLD_BYTES_SET(skb->len < LAN966X_BUFFER_MIN_SZ ? in lan966x_port_ifh_xmit()
290 dev->stats.tx_packets++; in lan966x_port_ifh_xmit()
291 dev->stats.tx_bytes += skb->len; in lan966x_port_ifh_xmit()
293 if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && in lan966x_port_ifh_xmit()
294 LAN966X_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP) in lan966x_port_ifh_xmit()
301 if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && in lan966x_port_ifh_xmit()
302 LAN966X_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP) in lan966x_port_ifh_xmit()
313 u8 p = IFH_LEN_BYTES - (pos + i) / 8 - 1; in lan966x_ifh_set()
320 ifh[p - 1] |= v >> (8 - (pos + i) % 8); in lan966x_ifh_set()
365 struct lan966x *lan966x = port->lan966x; in lan966x_port_xmit()
372 lan966x_ifh_set_port(ifh, BIT_ULL(port->chip_port)); in lan966x_port_xmit()
373 lan966x_ifh_set_qos_class(ifh, skb->priority >= 7 ? 0x7 : skb->priority); in lan966x_port_xmit()
374 lan966x_ifh_set_ipv(ifh, skb->priority >= 7 ? 0x7 : skb->priority); in lan966x_port_xmit()
377 if (port->lan966x->ptp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { in lan966x_port_xmit()
382 lan966x_ifh_set_rew_op(ifh, LAN966X_SKB_CB(skb)->rew_op); in lan966x_port_xmit()
383 lan966x_ifh_set_timestamp(ifh, LAN966X_SKB_CB(skb)->ts_id); in lan966x_port_xmit()
386 spin_lock(&lan966x->tx_lock); in lan966x_port_xmit()
387 if (port->lan966x->fdma) in lan966x_port_xmit()
391 spin_unlock(&lan966x->tx_lock); in lan966x_port_xmit()
399 struct lan966x *lan966x = port->lan966x; in lan966x_port_change_mtu()
400 int old_mtu = dev->mtu; in lan966x_port_change_mtu()
404 lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); in lan966x_port_change_mtu()
405 WRITE_ONCE(dev->mtu, new_mtu); in lan966x_port_change_mtu()
407 if (!lan966x->fdma) in lan966x_port_change_mtu()
413 lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); in lan966x_port_change_mtu()
414 dev->mtu = old_mtu; in lan966x_port_change_mtu()
423 struct lan966x *lan966x = port->lan966x; in lan966x_mc_unsync()
431 struct lan966x *lan966x = port->lan966x; in lan966x_mc_sync()
445 struct lan966x *lan966x = port->lan966x; in lan966x_port_get_parent_id()
447 ppid->id_len = sizeof(lan966x->base_mac); in lan966x_port_get_parent_id()
448 memcpy(&ppid->id, &lan966x->base_mac, ppid->id_len); in lan966x_port_get_parent_id()
458 if (!port->lan966x->ptp) in lan966x_port_hwtstamp_get()
459 return -EOPNOTSUPP; in lan966x_port_hwtstamp_get()
473 if (cfg->source != HWTSTAMP_SOURCE_NETDEV && in lan966x_port_hwtstamp_set()
474 cfg->source != HWTSTAMP_SOURCE_PHYLIB) in lan966x_port_hwtstamp_set()
475 return -EOPNOTSUPP; in lan966x_port_hwtstamp_set()
477 if (cfg->source == HWTSTAMP_SOURCE_NETDEV && !port->lan966x->ptp) in lan966x_port_hwtstamp_set()
478 return -EOPNOTSUPP; in lan966x_port_hwtstamp_set()
484 if (cfg->source == HWTSTAMP_SOURCE_NETDEV) { in lan966x_port_hwtstamp_set()
515 return dev->netdev_ops == &lan966x_port_netdev_ops; in lan966x_netdevice_check()
531 if (eth_type_vlan(skb->protocol)) { in lan966x_hw_offload()
537 if (skb->protocol == htons(ETH_P_IP) && in lan966x_hw_offload()
538 ip_hdr(skb)->protocol == IPPROTO_IGMP) in lan966x_hw_offload()
542 skb->protocol == htons(ETH_P_IPV6) && in lan966x_hw_offload()
543 ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) && in lan966x_hw_offload()
575 return -EIO; in lan966x_rx_frame_word()
580 return -EIO; in lan966x_rx_frame_word()
615 v = ifh[IFH_LEN_BYTES - (j / 8) - 1]; in lan966x_ifh_get()
639 static irqreturn_t lan966x_xtr_irq_handler(int irq, void *args) in lan966x_xtr_irq_handler() argument
668 WARN_ON(src_port >= lan966x->num_phys_ports); in lan966x_xtr_irq_handler()
670 dev = lan966x->ports[src_port]->dev; in lan966x_xtr_irq_handler()
676 buf_len = len - ETH_FCS_LEN; in lan966x_xtr_irq_handler()
699 len -= ETH_FCS_LEN - sz; in lan966x_xtr_irq_handler()
701 if (unlikely(dev->features & NETIF_F_RXFCS)) { in lan966x_xtr_irq_handler()
707 skb->protocol = eth_type_trans(skb, dev); in lan966x_xtr_irq_handler()
709 if (lan966x->bridge_mask & BIT(src_port)) { in lan966x_xtr_irq_handler()
710 skb->offload_fwd_mark = 1; in lan966x_xtr_irq_handler()
714 skb->offload_fwd_mark = 0; in lan966x_xtr_irq_handler()
720 dev->stats.rx_bytes += len; in lan966x_xtr_irq_handler()
721 dev->stats.rx_packets++; in lan966x_xtr_irq_handler()
732 static irqreturn_t lan966x_ana_irq_handler(int irq, void *args) in lan966x_ana_irq_handler() argument
744 for (p = 0; p < lan966x->num_phys_ports; p++) { in lan966x_cleanup_ports()
745 port = lan966x->ports[p]; in lan966x_cleanup_ports()
749 if (port->dev) in lan966x_cleanup_ports()
750 unregister_netdev(port->dev); in lan966x_cleanup_ports()
753 if (lan966x->fdma && lan966x->fdma_ndev == port->dev) in lan966x_cleanup_ports()
754 lan966x_fdma_netdev_deinit(lan966x, port->dev); in lan966x_cleanup_ports()
756 if (port->phylink) { in lan966x_cleanup_ports()
758 lan966x_port_stop(port->dev); in lan966x_cleanup_ports()
760 phylink_destroy(port->phylink); in lan966x_cleanup_ports()
761 port->phylink = NULL; in lan966x_cleanup_ports()
764 if (port->fwnode) in lan966x_cleanup_ports()
765 fwnode_handle_put(port->fwnode); in lan966x_cleanup_ports()
768 disable_irq(lan966x->xtr_irq); in lan966x_cleanup_ports()
769 lan966x->xtr_irq = -ENXIO; in lan966x_cleanup_ports()
771 if (lan966x->ana_irq > 0) { in lan966x_cleanup_ports()
772 disable_irq(lan966x->ana_irq); in lan966x_cleanup_ports()
773 lan966x->ana_irq = -ENXIO; in lan966x_cleanup_ports()
776 if (lan966x->fdma) in lan966x_cleanup_ports()
777 devm_free_irq(lan966x->dev, lan966x->fdma_irq, lan966x); in lan966x_cleanup_ports()
779 if (lan966x->ptp_irq > 0) in lan966x_cleanup_ports()
780 devm_free_irq(lan966x->dev, lan966x->ptp_irq, lan966x); in lan966x_cleanup_ports()
782 if (lan966x->ptp_ext_irq > 0) in lan966x_cleanup_ports()
783 devm_free_irq(lan966x->dev, lan966x->ptp_ext_irq, lan966x); in lan966x_cleanup_ports()
795 if (p >= lan966x->num_phys_ports) in lan966x_probe_port()
796 return -EINVAL; in lan966x_probe_port()
798 dev = devm_alloc_etherdev_mqs(lan966x->dev, in lan966x_probe_port()
802 return -ENOMEM; in lan966x_probe_port()
804 SET_NETDEV_DEV(dev, lan966x->dev); in lan966x_probe_port()
806 port->dev = dev; in lan966x_probe_port()
807 port->lan966x = lan966x; in lan966x_probe_port()
808 port->chip_port = p; in lan966x_probe_port()
809 lan966x->ports[p] = port; in lan966x_probe_port()
811 dev->max_mtu = ETH_MAX_MTU; in lan966x_probe_port()
813 dev->netdev_ops = &lan966x_port_netdev_ops; in lan966x_probe_port()
814 dev->ethtool_ops = &lan966x_ethtool_ops; in lan966x_probe_port()
815 dev->features |= NETIF_F_HW_VLAN_CTAG_TX | in lan966x_probe_port()
818 dev->hw_features |= NETIF_F_HW_TC; in lan966x_probe_port()
819 dev->see_all_hwtstamp_requests = true; in lan966x_probe_port()
820 dev->needed_headroom = IFH_LEN_BYTES; in lan966x_probe_port()
822 eth_hw_addr_gen(dev, lan966x->base_mac, p + 1); in lan966x_probe_port()
824 lan966x_mac_learn(lan966x, PGID_CPU, dev->dev_addr, HOST_PVID, in lan966x_probe_port()
827 port->phylink_config.dev = &port->dev->dev; in lan966x_probe_port()
828 port->phylink_config.type = PHYLINK_NETDEV; in lan966x_probe_port()
829 port->phylink_pcs.poll = true; in lan966x_probe_port()
830 port->phylink_pcs.ops = &lan966x_phylink_pcs_ops; in lan966x_probe_port()
831 port->phylink_pcs.neg_mode = true; in lan966x_probe_port()
833 port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | in lan966x_probe_port()
836 phy_interface_set_rgmii(port->phylink_config.supported_interfaces); in lan966x_probe_port()
838 port->phylink_config.supported_interfaces); in lan966x_probe_port()
840 port->phylink_config.supported_interfaces); in lan966x_probe_port()
842 port->phylink_config.supported_interfaces); in lan966x_probe_port()
844 port->phylink_config.supported_interfaces); in lan966x_probe_port()
846 port->phylink_config.supported_interfaces); in lan966x_probe_port()
848 port->phylink_config.supported_interfaces); in lan966x_probe_port()
850 port->phylink_config.supported_interfaces); in lan966x_probe_port()
852 phylink = phylink_create(&port->phylink_config, in lan966x_probe_port()
857 port->dev = NULL; in lan966x_probe_port()
861 port->phylink = phylink; in lan966x_probe_port()
863 if (lan966x->fdma) in lan966x_probe_port()
864 dev->xdp_features = NETDEV_XDP_ACT_BASIC | in lan966x_probe_port()
870 dev_err(lan966x->dev, "register_netdev failed\n"); in lan966x_probe_port()
914 /* Setup frame ageing - "2 sec" - The unit is 6.5 us on lan966x */ in lan966x_init()
922 /* Do byte-swap and expect status after last data word in lan966x_init()
925 lan_wr(QS_XTR_GRP_CFG_MODE_SET(lan966x->fdma ? 2 : 1) | in lan966x_init()
930 lan_wr(QS_INJ_GRP_CFG_MODE_SET(lan966x->fdma ? 2 : 1) | in lan966x_init()
966 for (p = 0; p < lan966x->num_phys_ports; p++) { in lan966x_init()
999 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
1004 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
1008 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
1013 lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0), in lan966x_init()
1018 lan_rmw(ANA_PGID_PGID_SET(BIT(CPU_PORT) | GENMASK(lan966x->num_phys_ports - 1, 0)), in lan966x_init()
1029 spin_lock_init(&lan966x->tx_lock); in lan966x_init()
1045 switch_reset = devm_reset_control_get_optional_shared(lan966x->dev, in lan966x_reset_switch()
1048 return dev_err_probe(lan966x->dev, PTR_ERR(switch_reset), in lan966x_reset_switch()
1083 lan966x = devm_kzalloc(&pdev->dev, sizeof(*lan966x), GFP_KERNEL); in lan966x_probe()
1085 return -ENOMEM; in lan966x_probe()
1088 lan966x->dev = &pdev->dev; in lan966x_probe()
1090 if (!device_get_mac_address(&pdev->dev, mac_addr)) { in lan966x_probe()
1091 ether_addr_copy(lan966x->base_mac, mac_addr); in lan966x_probe()
1094 eth_random_addr(lan966x->base_mac); in lan966x_probe()
1095 lan966x->base_mac[5] &= 0xf0; in lan966x_probe()
1100 return dev_err_probe(&pdev->dev, err, in lan966x_probe()
1105 return dev_err_probe(&pdev->dev, err, "Reset failed"); in lan966x_probe()
1107 lan966x->num_phys_ports = NUM_PHYS_PORTS; in lan966x_probe()
1108 lan966x->ports = devm_kcalloc(&pdev->dev, lan966x->num_phys_ports, in lan966x_probe()
1111 if (!lan966x->ports) in lan966x_probe()
1112 return -ENOMEM; in lan966x_probe()
1115 lan966x->shared_queue_sz = LAN966X_BUFFER_MEMORY; in lan966x_probe()
1117 /* set irq */ in lan966x_probe()
1118 lan966x->xtr_irq = platform_get_irq_byname(pdev, "xtr"); in lan966x_probe()
1119 if (lan966x->xtr_irq < 0) in lan966x_probe()
1120 return lan966x->xtr_irq; in lan966x_probe()
1122 err = devm_request_threaded_irq(&pdev->dev, lan966x->xtr_irq, NULL, in lan966x_probe()
1126 pr_err("Unable to use xtr irq"); in lan966x_probe()
1127 return -ENODEV; in lan966x_probe()
1130 lan966x->ana_irq = platform_get_irq_byname(pdev, "ana"); in lan966x_probe()
1131 if (lan966x->ana_irq > 0) { in lan966x_probe()
1132 err = devm_request_threaded_irq(&pdev->dev, lan966x->ana_irq, NULL, in lan966x_probe()
1134 "ana irq", lan966x); in lan966x_probe()
1136 return dev_err_probe(&pdev->dev, err, "Unable to use ana irq"); in lan966x_probe()
1139 lan966x->ptp_irq = platform_get_irq_byname(pdev, "ptp"); in lan966x_probe()
1140 if (lan966x->ptp_irq > 0) { in lan966x_probe()
1141 err = devm_request_threaded_irq(&pdev->dev, lan966x->ptp_irq, NULL, in lan966x_probe()
1143 "ptp irq", lan966x); in lan966x_probe()
1145 return dev_err_probe(&pdev->dev, err, "Unable to use ptp irq"); in lan966x_probe()
1147 lan966x->ptp = 1; in lan966x_probe()
1150 lan966x->fdma_irq = platform_get_irq_byname(pdev, "fdma"); in lan966x_probe()
1151 if (lan966x->fdma_irq > 0) { in lan966x_probe()
1152 err = devm_request_irq(&pdev->dev, lan966x->fdma_irq, in lan966x_probe()
1154 "fdma irq", lan966x); in lan966x_probe()
1156 return dev_err_probe(&pdev->dev, err, "Unable to use fdma irq"); in lan966x_probe()
1158 lan966x->fdma = true; in lan966x_probe()
1161 if (lan966x->ptp) { in lan966x_probe()
1162 lan966x->ptp_ext_irq = platform_get_irq_byname(pdev, "ptp-ext"); in lan966x_probe()
1163 if (lan966x->ptp_ext_irq > 0) { in lan966x_probe()
1164 err = devm_request_threaded_irq(&pdev->dev, in lan966x_probe()
1165 lan966x->ptp_ext_irq, NULL, in lan966x_probe()
1168 "ptp-ext irq", lan966x); in lan966x_probe()
1170 return dev_err_probe(&pdev->dev, err, in lan966x_probe()
1171 "Unable to use ptp-ext irq"); in lan966x_probe()
1175 ports = device_get_named_child_node(&pdev->dev, "ethernet-ports"); in lan966x_probe()
1177 return dev_err_probe(&pdev->dev, -ENODEV, in lan966x_probe()
1178 "no ethernet-ports child found\n"); in lan966x_probe()
1180 lan966x->debugfs_root = debugfs_create_dir("lan966x", NULL); in lan966x_probe()
1201 lan966x->ports[p]->config.portmode = phy_mode; in lan966x_probe()
1202 lan966x->ports[p]->fwnode = fwnode_handle_get(portnp); in lan966x_probe()
1204 serdes = devm_of_phy_optional_get(lan966x->dev, in lan966x_probe()
1210 lan966x->ports[p]->serdes = serdes; in lan966x_probe()
1212 lan966x_port_init(lan966x->ports[p]); in lan966x_probe()
1213 err = lan966x_xdp_port_init(lan966x->ports[p]); in lan966x_probe()
1256 cancel_delayed_work_sync(&lan966x->stats_work); in lan966x_probe()
1257 destroy_workqueue(lan966x->stats_queue); in lan966x_probe()
1258 mutex_destroy(&lan966x->stats_lock); in lan966x_probe()
1260 debugfs_remove_recursive(lan966x->debugfs_root); in lan966x_probe()
1274 cancel_delayed_work_sync(&lan966x->stats_work); in lan966x_remove()
1275 destroy_workqueue(lan966x->stats_queue); in lan966x_remove()
1276 mutex_destroy(&lan966x->stats_lock); in lan966x_remove()
1283 debugfs_remove_recursive(lan966x->debugfs_root); in lan966x_remove()
1290 .name = "lan966x-switch",