Lines Matching +full:am654 +full:- +full:pru
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
12 #include <linux/dma-mapping.h>
13 #include <linux/dma/ti-cppi5.h>
19 #include <linux/io-64-nonatomic-hi-lo.h>
37 #include "../k3-cppi-desc-pool.h"
56 struct prueth *prueth = emac->prueth; in emac_get_tx_ts()
65 memcpy_fromio(rsp, prueth->shram.va + addr, sizeof(*rsp)); in emac_get_tx_ts()
89 !emac->tx_ts_skb[tsr.cookie]) { in tx_ts_work()
90 netdev_err(emac->ndev, "Invalid TX TS cookie 0x%x\n", in tx_ts_work()
95 skb = emac->tx_ts_skb[tsr.cookie]; in tx_ts_work()
96 emac->tx_ts_skb[tsr.cookie] = NULL; /* free slot */ in tx_ts_work()
98 netdev_err(emac->ndev, "Driver Bug! got NULL skb\n"); in tx_ts_work()
102 hi_sw = readl(emac->prueth->shram.va + in tx_ts_work()
113 if (atomic_dec_and_test(&emac->tx_ts_pending)) /* no more? */ in tx_ts_work()
130 .pru = "ti-pruss/am65x-sr2-pru0-pruhsr-fw.elf",
131 .rtu = "ti-pruss/am65x-sr2-rtu0-pruhsr-fw.elf",
132 .txpru = "ti-pruss/am65x-sr2-txpru0-pruhsr-fw.elf",
135 .pru = "ti-pruss/am65x-sr2-pru1-pruhsr-fw.elf",
136 .rtu = "ti-pruss/am65x-sr2-rtu1-pruhsr-fw.elf",
137 .txpru = "ti-pruss/am65x-sr2-txpru1-pruhsr-fw.elf",
143 .pru = "ti-pruss/am65x-sr2-pru0-prusw-fw.elf",
144 .rtu = "ti-pruss/am65x-sr2-rtu0-prusw-fw.elf",
145 .txpru = "ti-pruss/am65x-sr2-txpru0-prusw-fw.elf",
148 .pru = "ti-pruss/am65x-sr2-pru1-prusw-fw.elf",
149 .rtu = "ti-pruss/am65x-sr2-rtu1-prusw-fw.elf",
150 .txpru = "ti-pruss/am65x-sr2-txpru1-prusw-fw.elf",
156 .pru = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
157 .rtu = "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
158 .txpru = "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
161 .pru = "ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
162 .rtu = "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
163 .txpru = "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
185 struct device *dev = prueth->dev; in prueth_emac_start()
188 if (prueth->is_switch_mode) in prueth_emac_start()
190 else if (prueth->is_hsr_offload_mode) in prueth_emac_start()
196 ret = prueth_start(prueth->pru[slice], firmwares[slice].pru); in prueth_emac_start()
198 dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret); in prueth_emac_start()
202 ret = prueth_start(prueth->rtu[slice], firmwares[slice].rtu); in prueth_emac_start()
205 rproc_shutdown(prueth->pru[slice]); in prueth_emac_start()
209 ret = prueth_start(prueth->txpru[slice], firmwares[slice].txpru); in prueth_emac_start()
212 rproc_shutdown(prueth->rtu[slice]); in prueth_emac_start()
213 rproc_shutdown(prueth->pru[slice]); in prueth_emac_start()
221 while (--slice >= 0) { in prueth_emac_start()
222 prueth_shutdown(prueth->txpru[slice]); in prueth_emac_start()
223 prueth_shutdown(prueth->rtu[slice]); in prueth_emac_start()
224 prueth_shutdown(prueth->pru[slice]); in prueth_emac_start()
235 prueth_shutdown(prueth->txpru[slice]); in prueth_emac_stop()
236 prueth_shutdown(prueth->rtu[slice]); in prueth_emac_stop()
237 prueth_shutdown(prueth->pru[slice]); in prueth_emac_stop()
247 if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1]) in prueth_emac_common_start()
248 return -EINVAL; in prueth_emac_common_start()
251 memset_io(prueth->msmcram.va, 0, prueth->msmcram.size); in prueth_emac_common_start()
252 memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS); in prueth_emac_common_start()
254 icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false); in prueth_emac_common_start()
255 icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false); in prueth_emac_common_start()
257 if (prueth->is_switch_mode || prueth->is_hsr_offload_mode) in prueth_emac_common_start()
263 emac = prueth->emac[slice]; in prueth_emac_common_start()
275 emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] : in prueth_emac_common_start()
276 prueth->emac[ICSS_SLICE1]; in prueth_emac_common_start()
277 ret = icss_iep_init(emac->iep, &prueth_iep_clockops, in prueth_emac_common_start()
280 dev_err(prueth->dev, "Failed to initialize IEP module\n"); in prueth_emac_common_start()
290 icssg_class_disable(prueth->miig_rt, ICSS_SLICE0); in prueth_emac_common_start()
291 icssg_class_disable(prueth->miig_rt, ICSS_SLICE1); in prueth_emac_common_start()
300 if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1]) in prueth_emac_common_stop()
301 return -EINVAL; in prueth_emac_common_stop()
303 icssg_class_disable(prueth->miig_rt, ICSS_SLICE0); in prueth_emac_common_stop()
304 icssg_class_disable(prueth->miig_rt, ICSS_SLICE1); in prueth_emac_common_stop()
308 emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] : in prueth_emac_common_stop()
309 prueth->emac[ICSS_SLICE1]; in prueth_emac_common_stop()
310 icss_iep_exit(emac->iep); in prueth_emac_common_stop()
319 struct phy_device *phydev = ndev->phydev; in emac_adjust_link()
320 struct prueth *prueth = emac->prueth; in emac_adjust_link()
324 if (phydev->link) { in emac_adjust_link()
325 /* check the mode of operation - full/half duplex */ in emac_adjust_link()
326 if (phydev->duplex != emac->duplex) { in emac_adjust_link()
328 emac->duplex = phydev->duplex; in emac_adjust_link()
330 if (phydev->speed != emac->speed) { in emac_adjust_link()
332 emac->speed = phydev->speed; in emac_adjust_link()
334 if (!emac->link) { in emac_adjust_link()
336 emac->link = 1; in emac_adjust_link()
338 } else if (emac->link) { in emac_adjust_link()
340 emac->link = 0; in emac_adjust_link()
343 emac->speed = SPEED_1000; in emac_adjust_link()
346 emac->duplex = DUPLEX_FULL; in emac_adjust_link()
355 if (emac->link) { in emac_adjust_link()
356 if (emac->duplex == DUPLEX_HALF) in emac_adjust_link()
359 icssg_update_rgmii_cfg(prueth->miig_rt, emac); in emac_adjust_link()
362 spin_lock_irqsave(&emac->lock, flags); in emac_adjust_link()
364 spin_unlock_irqrestore(&emac->lock, flags); in emac_adjust_link()
373 if (emac->link) { in emac_adjust_link()
388 enable_irq(emac->rx_chns.irq[rx_flow]); in emac_rx_timer_callback()
394 struct prueth *prueth = emac->prueth; in emac_phy_connect()
395 struct net_device *ndev = emac->ndev; in emac_phy_connect()
397 ndev->phydev = of_phy_connect(emac->ndev, emac->phy_node, in emac_phy_connect()
399 emac->phy_if); in emac_phy_connect()
400 if (!ndev->phydev) { in emac_phy_connect()
401 dev_err(prueth->dev, "couldn't connect to phy %s\n", in emac_phy_connect()
402 emac->phy_node->full_name); in emac_phy_connect()
403 return -ENODEV; in emac_phy_connect()
406 if (!emac->half_duplex) { in emac_phy_connect()
407 dev_dbg(prueth->dev, "half duplex mode is not supported\n"); in emac_phy_connect()
408 phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); in emac_phy_connect()
409 phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); in emac_phy_connect()
413 phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); in emac_phy_connect()
414 phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Pause_BIT); in emac_phy_connect()
415 phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); in emac_phy_connect()
417 if (emac->phy_if == PHY_INTERFACE_MODE_MII) in emac_phy_connect()
418 phy_set_max_speed(ndev->phydev, SPEED_100); in emac_phy_connect()
427 struct prueth *prueth = emac->prueth; in prueth_iep_gettime()
435 fw_count_hi_addr = prueth->shram.va + TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET; in prueth_iep_gettime()
436 fw_hi_r_count_addr = prueth->shram.va + TIMESYNC_FW_WC_HI_ROLLOVER_COUNT_OFFSET; in prueth_iep_gettime()
440 iepcount_hi = icss_iep_get_count_hi(emac->iep); in prueth_iep_gettime()
444 iepcount_lo = icss_iep_get_count_low(emac->iep); in prueth_iep_gettime()
447 iepcount_hi_r = icss_iep_get_count_hi(emac->iep); in prueth_iep_gettime()
469 sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET; in prueth_iep_settime()
475 sc_desc.margin = cycletime - 1000; in prueth_iep_settime()
479 /* Count from 0 to (cycle time) - emac->iep->def_inc */ in prueth_iep_settime()
480 sc_desc.CMP0_current = cycletime - emac->iep->def_inc; in prueth_iep_settime()
484 writeb(1, &sc_descp->request); in prueth_iep_settime()
486 timeout = 5; /* fw should take 2-3 ms */ in prueth_iep_settime()
487 while (timeout--) { in prueth_iep_settime()
488 if (readb(&sc_descp->acknowledgment)) in prueth_iep_settime()
494 dev_err(emac->prueth->dev, "settime timeout\n"); in prueth_iep_settime()
512 ts.tv_sec = req->period.sec; in prueth_perout_enable()
513 ts.tv_nsec = req->period.nsec; in prueth_perout_enable()
518 return -ENXIO; in prueth_perout_enable()
535 if (offset > IEP_DEFAULT_CYCLE_TIME_NS - 8) in prueth_perout_enable()
536 offset = IEP_DEFAULT_CYCLE_TIME_NS - 8; in prueth_perout_enable()
538 /* we're in shadow mode so need to set upper 32-bits */ in prueth_perout_enable()
541 writel(reduction_factor, emac->prueth->shram.va + in prueth_perout_enable()
544 current_cycle = icssg_read_time(emac->prueth->shram.va + in prueth_perout_enable()
550 hi_lo_writeq(start_offset, emac->prueth->shram.va + in prueth_perout_enable()
573 port_mask = BIT(emac->port_id) | icssg_fdb_lookup(emac, addr, vlan_id); in icssg_prueth_add_mcast()
592 port_mask = BIT(emac->port_id); in icssg_prueth_del_mcast()
617 icssg_vtbl_modify(emac, vid, BIT(emac->port_id), in icssg_prueth_hsr_fdb_add_del()
618 BIT(emac->port_id), add); in icssg_prueth_hsr_fdb_add_del()
634 return -EINVAL; in icssg_prueth_hsr_add_mcast()
659 return -EINVAL; in icssg_prueth_hsr_del_mcast()
680 __hw_addr_sync_multiple(&emac->vlan_mcast_list[vid], &vdev->mc, in icssg_update_vlan_mcast()
681 vdev->addr_len); in icssg_update_vlan_mcast()
684 if (emac->prueth->is_hsr_offload_mode) in icssg_update_vlan_mcast()
685 __hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev, in icssg_update_vlan_mcast()
689 __hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev, in icssg_update_vlan_mcast()
697 * emac_ndo_open - EMAC device open
707 int ret, i, num_data_chn = emac->tx_ch_num; in emac_ndo_open()
709 struct prueth *prueth = emac->prueth; in emac_ndo_open()
711 struct device *dev = prueth->dev; in emac_ndo_open()
715 /* set h/w MAC as user might have re-configured */ in emac_ndo_open()
716 ether_addr_copy(emac->mac_addr, ndev->dev_addr); in emac_ndo_open()
718 icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); in emac_ndo_open()
719 icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); in emac_ndo_open()
728 init_completion(&emac->cmd_complete); in emac_ndo_open()
736 ret = prueth_init_rx_chns(emac, &emac->rx_chns, "rx", in emac_ndo_open()
749 ret = request_irq(emac->rx_chns.irq[rx_flow], prueth_rx_irq, in emac_ndo_open()
756 if (!prueth->emacs_initialized) { in emac_ndo_open()
762 flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET; in emac_ndo_open()
763 writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow); in emac_ndo_open()
771 icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu); in emac_ndo_open()
773 ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq, in emac_ndo_open()
779 ret = prueth_prepare_rx_chan(emac, &emac->rx_chns, PRUETH_MAX_PKT_SIZE); in emac_ndo_open()
783 ret = k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn); in emac_ndo_open()
787 for (i = 0; i < emac->tx_ch_num; i++) { in emac_ndo_open()
788 ret = k3_udma_glue_enable_tx_chn(emac->tx_chns[i].tx_chn); in emac_ndo_open()
794 for (i = 0; i < emac->tx_ch_num; i++) in emac_ndo_open()
795 napi_enable(&emac->tx_chns[i].napi_tx); in emac_ndo_open()
796 napi_enable(&emac->napi_rx); in emac_ndo_open()
799 phy_start(ndev->phydev); in emac_ndo_open()
801 prueth->emacs_initialized++; in emac_ndo_open()
803 queue_work(system_long_wq, &emac->stats_work.work); in emac_ndo_open()
813 prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false); in emac_ndo_open()
815 free_irq(emac->tx_ts_irq, emac); in emac_ndo_open()
817 if (!prueth->emacs_initialized) in emac_ndo_open()
820 free_irq(emac->rx_chns.irq[rx_flow], emac); in emac_ndo_open()
822 prueth_ndev_del_tx_napi(emac, emac->tx_ch_num); in emac_ndo_open()
824 prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows); in emac_ndo_open()
832 * emac_ndo_stop - EMAC device stop
842 struct prueth *prueth = emac->prueth; in emac_ndo_stop()
851 if (ndev->phydev) in emac_ndo_stop()
852 phy_stop(ndev->phydev); in emac_ndo_stop()
854 if (emac->prueth->is_hsr_offload_mode) in emac_ndo_stop()
859 atomic_set(&emac->tdown_cnt, emac->tx_ch_num); in emac_ndo_stop()
863 reinit_completion(&emac->tdown_complete); in emac_ndo_stop()
864 for (i = 0; i < emac->tx_ch_num; i++) in emac_ndo_stop()
865 k3_udma_glue_tdown_tx_chn(emac->tx_chns[i].tx_chn, false); in emac_ndo_stop()
867 ret = wait_for_completion_timeout(&emac->tdown_complete, in emac_ndo_stop()
872 prueth_reset_tx_chan(emac, emac->tx_ch_num, true); in emac_ndo_stop()
873 for (i = 0; i < emac->tx_ch_num; i++) { in emac_ndo_stop()
874 napi_disable(&emac->tx_chns[i].napi_tx); in emac_ndo_stop()
875 hrtimer_cancel(&emac->tx_chns[i].tx_hrtimer); in emac_ndo_stop()
879 k3_udma_glue_tdown_rx_chn(emac->rx_chns.rx_chn, true); in emac_ndo_stop()
881 prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, true); in emac_ndo_stop()
883 napi_disable(&emac->napi_rx); in emac_ndo_stop()
884 hrtimer_cancel(&emac->rx_hrtimer); in emac_ndo_stop()
886 cancel_work_sync(&emac->rx_mode_work); in emac_ndo_stop()
889 cancel_delayed_work_sync(&emac->stats_work); in emac_ndo_stop()
892 if (prueth->emacs_initialized == 1) in emac_ndo_stop()
895 free_irq(emac->tx_ts_irq, emac); in emac_ndo_stop()
897 free_irq(emac->rx_chns.irq[rx_flow], emac); in emac_ndo_stop()
898 prueth_ndev_del_tx_napi(emac, emac->tx_ch_num); in emac_ndo_stop()
900 prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows); in emac_ndo_stop()
903 prueth->emacs_initialized--; in emac_ndo_stop()
911 struct net_device *ndev = emac->ndev; in emac_ndo_set_rx_mode_work()
917 promisc = ndev->flags & IFF_PROMISC; in emac_ndo_set_rx_mode_work()
918 allmulti = ndev->flags & IFF_ALLMULTI; in emac_ndo_set_rx_mode_work()
933 if (emac->prueth->is_hsr_offload_mode) { in emac_ndo_set_rx_mode_work()
937 vlan_for_each(emac->prueth->hsr_dev, in emac_ndo_set_rx_mode_work()
952 * emac_ndo_set_rx_mode - EMAC set receive mode function
962 queue_work(emac->cmd_wq, &emac->rx_mode_work); in emac_ndo_set_rx_mode()
972 if (!(ndev->features & (NETIF_F_HW_HSR_DUP | NETIF_F_HW_HSR_TAG_INS))) in emac_ndo_fix_features()
978 if ((ndev->features & NETIF_F_HW_HSR_DUP) || in emac_ndo_fix_features()
979 (ndev->features & NETIF_F_HW_HSR_TAG_INS)) in emac_ndo_fix_features()
992 struct prueth *prueth = emac->prueth; in emac_ndo_vlan_rx_add_vid()
993 int port_mask = BIT(emac->port_id); in emac_ndo_vlan_rx_add_vid()
996 if (prueth->is_hsr_offload_mode) in emac_ndo_vlan_rx_add_vid()
999 __hw_addr_init(&emac->vlan_mcast_list[vid]); in emac_ndo_vlan_rx_add_vid()
1000 netdev_dbg(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n", in emac_ndo_vlan_rx_add_vid()
1004 icssg_set_pvid(emac->prueth, vid, emac->port_id); in emac_ndo_vlan_rx_add_vid()
1013 struct prueth *prueth = emac->prueth; in emac_ndo_vlan_rx_del_vid()
1014 int port_mask = BIT(emac->port_id); in emac_ndo_vlan_rx_del_vid()
1017 if (prueth->is_hsr_offload_mode) in emac_ndo_vlan_rx_del_vid()
1020 netdev_dbg(emac->ndev, "VID del vid:%u port_mask:%X untag_mask %X\n", in emac_ndo_vlan_rx_del_vid()
1055 return -EINVAL; in prueth_netdev_init()
1059 return -EINVAL; in prueth_netdev_init()
1063 return -ENOMEM; in prueth_netdev_init()
1066 emac->prueth = prueth; in prueth_netdev_init()
1067 emac->ndev = ndev; in prueth_netdev_init()
1068 emac->port_id = port; in prueth_netdev_init()
1069 emac->cmd_wq = create_singlethread_workqueue("icssg_cmd_wq"); in prueth_netdev_init()
1070 if (!emac->cmd_wq) { in prueth_netdev_init()
1071 ret = -ENOMEM; in prueth_netdev_init()
1074 INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work); in prueth_netdev_init()
1076 INIT_DELAYED_WORK(&emac->stats_work, icssg_stats_work_handler); in prueth_netdev_init()
1078 ret = pruss_request_mem_region(prueth->pruss, in prueth_netdev_init()
1081 &emac->dram); in prueth_netdev_init()
1083 dev_err(prueth->dev, "unable to get DRAM: %d\n", ret); in prueth_netdev_init()
1084 ret = -ENOMEM; in prueth_netdev_init()
1088 emac->tx_ch_num = 1; in prueth_netdev_init()
1091 if (emac->port_id == PRUETH_PORT_MII1) in prueth_netdev_init()
1093 emac->tx_ts_irq = platform_get_irq_byname_optional(prueth->pdev, irq_name); in prueth_netdev_init()
1094 if (emac->tx_ts_irq < 0) { in prueth_netdev_init()
1095 ret = dev_err_probe(prueth->dev, emac->tx_ts_irq, "could not get tx_ts_irq\n"); in prueth_netdev_init()
1099 SET_NETDEV_DEV(ndev, prueth->dev); in prueth_netdev_init()
1100 spin_lock_init(&emac->lock); in prueth_netdev_init()
1101 mutex_init(&emac->cmd_lock); in prueth_netdev_init()
1103 emac->phy_node = of_parse_phandle(eth_node, "phy-handle", 0); in prueth_netdev_init()
1104 if (!emac->phy_node && !of_phy_is_fixed_link(eth_node)) { in prueth_netdev_init()
1105 dev_err(prueth->dev, "couldn't find phy-handle\n"); in prueth_netdev_init()
1106 ret = -ENODEV; in prueth_netdev_init()
1111 ret = dev_err_probe(prueth->dev, ret, in prueth_netdev_init()
1112 "failed to register fixed-link phy\n"); in prueth_netdev_init()
1116 emac->phy_node = eth_node; in prueth_netdev_init()
1119 ret = of_get_phy_mode(eth_node, &emac->phy_if); in prueth_netdev_init()
1121 dev_err(prueth->dev, "could not get phy-mode property\n"); in prueth_netdev_init()
1125 if (emac->phy_if != PHY_INTERFACE_MODE_MII && in prueth_netdev_init()
1126 !phy_interface_mode_is_rgmii(emac->phy_if)) { in prueth_netdev_init()
1127 dev_err(prueth->dev, "PHY mode unsupported %s\n", phy_modes(emac->phy_if)); in prueth_netdev_init()
1128 ret = -EINVAL; in prueth_netdev_init()
1137 switch (emac->phy_if) { in prueth_netdev_init()
1139 emac->phy_if = PHY_INTERFACE_MODE_RGMII_RXID; in prueth_netdev_init()
1142 emac->phy_if = PHY_INTERFACE_MODE_RGMII; in prueth_netdev_init()
1146 dev_err(prueth->dev, "RGMII mode without TX delay is not supported"); in prueth_netdev_init()
1147 ret = -EINVAL; in prueth_netdev_init()
1155 if (!is_valid_ether_addr(ndev->dev_addr)) { in prueth_netdev_init()
1157 dev_warn(prueth->dev, "port %d: using random MAC addr: %pM\n", in prueth_netdev_init()
1158 port, ndev->dev_addr); in prueth_netdev_init()
1160 ether_addr_copy(emac->mac_addr, ndev->dev_addr); in prueth_netdev_init()
1162 ndev->dev.of_node = eth_node; in prueth_netdev_init()
1163 ndev->min_mtu = PRUETH_MIN_PKT_SIZE; in prueth_netdev_init()
1164 ndev->max_mtu = PRUETH_MAX_MTU; in prueth_netdev_init()
1165 ndev->netdev_ops = &emac_netdev_ops; in prueth_netdev_init()
1166 ndev->ethtool_ops = &icssg_ethtool_ops; in prueth_netdev_init()
1167 ndev->hw_features = NETIF_F_SG; in prueth_netdev_init()
1168 ndev->features = ndev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER; in prueth_netdev_init()
1169 ndev->hw_features |= NETIF_PRUETH_HSR_OFFLOAD_FEATURES; in prueth_netdev_init()
1171 netif_napi_add(ndev, &emac->napi_rx, icssg_napi_rx_poll); in prueth_netdev_init()
1172 hrtimer_init(&emac->rx_hrtimer, CLOCK_MONOTONIC, in prueth_netdev_init()
1174 emac->rx_hrtimer.function = &emac_rx_timer_callback; in prueth_netdev_init()
1175 prueth->emac[mac] = emac; in prueth_netdev_init()
1180 pruss_release_mem_region(prueth->pruss, &emac->dram); in prueth_netdev_init()
1182 destroy_workqueue(emac->cmd_wq); in prueth_netdev_init()
1184 emac->ndev = NULL; in prueth_netdev_init()
1185 prueth->emac[mac] = NULL; in prueth_netdev_init()
1193 if (ndev->netdev_ops == &emac_netdev_ops && netif_running(ndev)) { in prueth_dev_check()
1196 return emac->prueth->is_switch_mode; in prueth_dev_check()
1207 if (prueth->br_members == (BIT(PRUETH_PORT_MII0) | BIT(PRUETH_PORT_MII1))) in prueth_offload_fwd_mark_update()
1210 dev_dbg(prueth->dev, "set offload_fwd_mark %d\n", set_val); in prueth_offload_fwd_mark_update()
1213 struct prueth_emac *emac = prueth->emac[i]; in prueth_offload_fwd_mark_update()
1215 if (!emac || !emac->ndev) in prueth_offload_fwd_mark_update()
1218 emac->offload_fwd_mark = set_val; in prueth_offload_fwd_mark_update()
1224 struct prueth_emac *emac0 = prueth->emac[PRUETH_MAC0]; in prueth_emac_restart()
1225 struct prueth_emac *emac1 = prueth->emac[PRUETH_MAC1]; in prueth_emac_restart()
1229 if (netif_running(emac0->ndev)) in prueth_emac_restart()
1230 netif_device_detach(emac0->ndev); in prueth_emac_restart()
1231 if (netif_running(emac1->ndev)) in prueth_emac_restart()
1232 netif_device_detach(emac1->ndev); in prueth_emac_restart()
1240 /* Stop both pru cores for both PRUeth ports*/ in prueth_emac_restart()
1243 dev_err(prueth->dev, "Failed to stop the firmwares"); in prueth_emac_restart()
1247 /* Start both pru cores for both PRUeth ports */ in prueth_emac_restart()
1250 dev_err(prueth->dev, "Failed to start the firmwares"); in prueth_emac_restart()
1259 netif_device_attach(emac0->ndev); in prueth_emac_restart()
1260 netif_device_attach(emac1->ndev); in prueth_emac_restart()
1272 dev_err(prueth->dev, "Failed to restart the firmwares, aborting the process"); in icssg_change_mode()
1277 emac = prueth->emac[mac]; in icssg_change_mode()
1278 if (prueth->is_hsr_offload_mode) { in icssg_change_mode()
1279 if (emac->ndev->features & NETIF_F_HW_HSR_TAG_RM) in icssg_change_mode()
1285 if (netif_running(emac->ndev)) { in icssg_change_mode()
1286 icssg_fdb_add_del(emac, eth_stp_addr, prueth->default_vlan, in icssg_change_mode()
1292 icssg_vtbl_modify(emac, emac->port_vlan | DEFAULT_VID, in icssg_change_mode()
1293 BIT(emac->port_id) | DEFAULT_PORT_MASK, in icssg_change_mode()
1294 BIT(emac->port_id) | DEFAULT_UNTAG_MASK, in icssg_change_mode()
1296 if (prueth->is_hsr_offload_mode) in icssg_change_mode()
1300 icssg_set_pvid(prueth, emac->port_vlan, emac->port_id); in icssg_change_mode()
1301 if (prueth->is_switch_mode) in icssg_change_mode()
1312 struct prueth *prueth = emac->prueth; in prueth_netdevice_port_link()
1315 if (!prueth->br_members) { in prueth_netdevice_port_link()
1316 prueth->hw_bridge_dev = br_ndev; in prueth_netdevice_port_link()
1321 if (prueth->hw_bridge_dev != br_ndev) in prueth_netdevice_port_link()
1322 return -EOPNOTSUPP; in prueth_netdevice_port_link()
1326 &prueth->prueth_switchdev_nb, in prueth_netdevice_port_link()
1327 &prueth->prueth_switchdev_bl_nb, in prueth_netdevice_port_link()
1332 prueth->br_members |= BIT(emac->port_id); in prueth_netdevice_port_link()
1334 if (!prueth->is_switch_mode) { in prueth_netdevice_port_link()
1335 if (prueth->br_members & BIT(PRUETH_PORT_MII0) && in prueth_netdevice_port_link()
1336 prueth->br_members & BIT(PRUETH_PORT_MII1)) { in prueth_netdevice_port_link()
1337 prueth->is_switch_mode = true; in prueth_netdevice_port_link()
1338 prueth->default_vlan = PRUETH_DFLT_VLAN_SW; in prueth_netdevice_port_link()
1339 emac->port_vlan = prueth->default_vlan; in prueth_netdevice_port_link()
1352 struct prueth *prueth = emac->prueth; in prueth_netdevice_port_unlink()
1355 prueth->br_members &= ~BIT(emac->port_id); in prueth_netdevice_port_unlink()
1357 if (prueth->is_switch_mode) { in prueth_netdevice_port_unlink()
1358 prueth->is_switch_mode = false; in prueth_netdevice_port_unlink()
1359 emac->port_vlan = 0; in prueth_netdevice_port_unlink()
1362 dev_err(prueth->dev, "Failed to restart the firmwares, aborting the process"); in prueth_netdevice_port_unlink()
1369 if (!prueth->br_members) in prueth_netdevice_port_unlink()
1370 prueth->hw_bridge_dev = NULL; in prueth_netdevice_port_unlink()
1376 struct prueth *prueth = emac->prueth; in prueth_hsr_port_link()
1380 emac0 = prueth->emac[PRUETH_MAC0]; in prueth_hsr_port_link()
1381 emac1 = prueth->emac[PRUETH_MAC1]; in prueth_hsr_port_link()
1383 if (prueth->is_switch_mode) in prueth_hsr_port_link()
1384 return -EOPNOTSUPP; in prueth_hsr_port_link()
1386 prueth->hsr_members |= BIT(emac->port_id); in prueth_hsr_port_link()
1387 if (!prueth->is_hsr_offload_mode) { in prueth_hsr_port_link()
1388 if (prueth->hsr_members & BIT(PRUETH_PORT_MII0) && in prueth_hsr_port_link()
1389 prueth->hsr_members & BIT(PRUETH_PORT_MII1)) { in prueth_hsr_port_link()
1390 if (!(emac0->ndev->features & in prueth_hsr_port_link()
1392 !(emac1->ndev->features & in prueth_hsr_port_link()
1394 return -EOPNOTSUPP; in prueth_hsr_port_link()
1395 prueth->is_hsr_offload_mode = true; in prueth_hsr_port_link()
1396 prueth->default_vlan = PRUETH_DFLT_VLAN_HSR; in prueth_hsr_port_link()
1397 emac0->port_vlan = prueth->default_vlan; in prueth_hsr_port_link()
1398 emac1->port_vlan = prueth->default_vlan; in prueth_hsr_port_link()
1410 struct prueth *prueth = emac->prueth; in prueth_hsr_port_unlink()
1415 emac0 = prueth->emac[PRUETH_MAC0]; in prueth_hsr_port_unlink()
1416 emac1 = prueth->emac[PRUETH_MAC1]; in prueth_hsr_port_unlink()
1418 prueth->hsr_members &= ~BIT(emac->port_id); in prueth_hsr_port_unlink()
1419 if (prueth->is_hsr_offload_mode) { in prueth_hsr_port_unlink()
1420 prueth->is_hsr_offload_mode = false; in prueth_hsr_port_unlink()
1421 emac0->port_vlan = 0; in prueth_hsr_port_unlink()
1422 emac1->port_vlan = 0; in prueth_hsr_port_unlink()
1423 prueth->hsr_dev = NULL; in prueth_hsr_port_unlink()
1426 dev_err(prueth->dev, "Failed to restart the firmwares, aborting the process"); in prueth_hsr_port_unlink()
1441 struct prueth *prueth = emac->prueth; in prueth_netdevice_event()
1444 if (ndev->netdev_ops != &emac_netdev_ops) in prueth_netdevice_event()
1451 if ((ndev->features & NETIF_PRUETH_HSR_OFFLOAD_FEATURES) && in prueth_netdevice_event()
1452 is_hsr_master(info->upper_dev)) { in prueth_netdevice_event()
1453 if (info->linking) { in prueth_netdevice_event()
1454 if (!prueth->hsr_dev) { in prueth_netdevice_event()
1455 prueth->hsr_dev = info->upper_dev; in prueth_netdevice_event()
1456 icssg_class_set_host_mac_addr(prueth->miig_rt, in prueth_netdevice_event()
1457 prueth->hsr_dev->dev_addr); in prueth_netdevice_event()
1459 if (prueth->hsr_dev != info->upper_dev) { in prueth_netdevice_event()
1461 return -EOPNOTSUPP; in prueth_netdevice_event()
1470 if (netif_is_bridge_master(info->upper_dev)) { in prueth_netdevice_event()
1471 if (info->linking) in prueth_netdevice_event()
1472 ret = prueth_netdevice_port_link(ndev, info->upper_dev, extack); in prueth_netdevice_event()
1488 prueth->prueth_netdevice_nb.notifier_call = &prueth_netdevice_event; in prueth_register_notifiers()
1489 ret = register_netdevice_notifier(&prueth->prueth_netdevice_nb); in prueth_register_notifiers()
1491 dev_err(prueth->dev, "can't register netdevice notifier\n"); in prueth_register_notifiers()
1497 unregister_netdevice_notifier(&prueth->prueth_netdevice_nb); in prueth_register_notifiers()
1505 unregister_netdevice_notifier(&prueth->prueth_netdevice_nb); in prueth_unregister_notifiers()
1516 struct device *dev = &pdev->dev; in prueth_probe()
1523 np = dev->of_node; in prueth_probe()
1527 return -ENOMEM; in prueth_probe()
1530 prueth->pdev = pdev; in prueth_probe()
1531 prueth->pdata = *(const struct prueth_pdata *)device_get_match_data(dev); in prueth_probe()
1533 prueth->dev = dev; in prueth_probe()
1534 eth_ports_node = of_get_child_by_name(np, "ethernet-ports"); in prueth_probe()
1536 return -ENOENT; in prueth_probe()
1541 if (strcmp(eth_node->name, "port")) in prueth_probe()
1573 return -ENODEV; in prueth_probe()
1579 return -ENODEV; in prueth_probe()
1582 prueth->eth_node[PRUETH_MAC0] = eth0_node; in prueth_probe()
1583 prueth->eth_node[PRUETH_MAC1] = eth1_node; in prueth_probe()
1585 prueth->miig_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-g-rt"); in prueth_probe()
1586 if (IS_ERR(prueth->miig_rt)) { in prueth_probe()
1587 dev_err(dev, "couldn't get ti,mii-g-rt syscon regmap\n"); in prueth_probe()
1588 return -ENODEV; in prueth_probe()
1591 prueth->mii_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-rt"); in prueth_probe()
1592 if (IS_ERR(prueth->mii_rt)) { in prueth_probe()
1593 dev_err(dev, "couldn't get ti,mii-rt syscon regmap\n"); in prueth_probe()
1594 return -ENODEV; in prueth_probe()
1597 prueth->pa_stats = syscon_regmap_lookup_by_phandle(np, "ti,pa-stats"); in prueth_probe()
1598 if (IS_ERR(prueth->pa_stats)) { in prueth_probe()
1599 dev_err(dev, "couldn't get ti,pa-stats syscon regmap\n"); in prueth_probe()
1600 prueth->pa_stats = NULL; in prueth_probe()
1613 prueth->pru[ICSS_SLICE0] : prueth->pru[ICSS_SLICE1]); in prueth_probe()
1620 prueth->pruss = pruss; in prueth_probe()
1623 &prueth->shram); in prueth_probe()
1629 prueth->sram_pool = of_gen_pool_get(np, "sram", 0); in prueth_probe()
1630 if (!prueth->sram_pool) { in prueth_probe()
1632 ret = -ENODEV; in prueth_probe()
1638 prueth->is_switchmode_supported = prueth->pdata.switch_mode; in prueth_probe()
1639 if (prueth->is_switchmode_supported) in prueth_probe()
1643 prueth->msmcram.va = in prueth_probe()
1644 (void __iomem *)gen_pool_alloc_algo(prueth->sram_pool, in prueth_probe()
1649 if (!prueth->msmcram.va) { in prueth_probe()
1650 ret = -ENOMEM; in prueth_probe()
1654 prueth->msmcram.pa = gen_pool_virt_to_phys(prueth->sram_pool, in prueth_probe()
1655 (unsigned long)prueth->msmcram.va); in prueth_probe()
1656 prueth->msmcram.size = msmc_ram_size; in prueth_probe()
1657 memset_io(prueth->msmcram.va, 0, msmc_ram_size); in prueth_probe()
1658 dev_dbg(dev, "sram: pa %llx va %p size %zx\n", prueth->msmcram.pa, in prueth_probe()
1659 prueth->msmcram.va, prueth->msmcram.size); in prueth_probe()
1661 prueth->iep0 = icss_iep_get_idx(np, 0); in prueth_probe()
1662 if (IS_ERR(prueth->iep0)) { in prueth_probe()
1663 ret = dev_err_probe(dev, PTR_ERR(prueth->iep0), "iep0 get failed\n"); in prueth_probe()
1664 prueth->iep0 = NULL; in prueth_probe()
1668 prueth->iep1 = icss_iep_get_idx(np, 1); in prueth_probe()
1669 if (IS_ERR(prueth->iep1)) { in prueth_probe()
1670 ret = dev_err_probe(dev, PTR_ERR(prueth->iep1), "iep1 get failed\n"); in prueth_probe()
1674 if (prueth->pdata.quirk_10m_link_issue) { in prueth_probe()
1678 icss_iep_init_fw(prueth->iep1); in prueth_probe()
1681 spin_lock_init(&prueth->vtbl_lock); in prueth_probe()
1682 spin_lock_init(&prueth->stats_lock); in prueth_probe()
1688 eth0_node->name); in prueth_probe()
1692 prueth->emac[PRUETH_MAC0]->half_duplex = in prueth_probe()
1693 of_property_read_bool(eth0_node, "ti,half-duplex-capable"); in prueth_probe()
1695 prueth->emac[PRUETH_MAC0]->iep = prueth->iep0; in prueth_probe()
1702 eth1_node->name); in prueth_probe()
1706 prueth->emac[PRUETH_MAC1]->half_duplex = in prueth_probe()
1707 of_property_read_bool(eth1_node, "ti,half-duplex-capable"); in prueth_probe()
1709 prueth->emac[PRUETH_MAC1]->iep = prueth->iep0; in prueth_probe()
1714 ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev); in prueth_probe()
1720 prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev; in prueth_probe()
1722 ret = emac_phy_connect(prueth->emac[PRUETH_MAC0]); in prueth_probe()
1725 "can't connect to MII0 PHY, error -%d", ret); in prueth_probe()
1728 phy_attached_info(prueth->emac[PRUETH_MAC0]->ndev->phydev); in prueth_probe()
1732 ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev); in prueth_probe()
1738 prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev; in prueth_probe()
1739 ret = emac_phy_connect(prueth->emac[PRUETH_MAC1]); in prueth_probe()
1745 phy_attached_info(prueth->emac[PRUETH_MAC1]->ndev->phydev); in prueth_probe()
1748 if (prueth->is_switchmode_supported) { in prueth_probe()
1753 sprintf(prueth->switch_id, "%s", dev_name(dev)); in prueth_probe()
1756 dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n", in prueth_probe()
1767 if (!prueth->registered_netdevs[i]) in prueth_probe()
1769 if (prueth->emac[i]->ndev->phydev) { in prueth_probe()
1770 phy_disconnect(prueth->emac[i]->ndev->phydev); in prueth_probe()
1771 prueth->emac[i]->ndev->phydev = NULL; in prueth_probe()
1773 unregister_netdev(prueth->registered_netdevs[i]); in prueth_probe()
1778 eth_node = prueth->eth_node[i]; in prueth_probe()
1786 if (prueth->pdata.quirk_10m_link_issue) in prueth_probe()
1787 icss_iep_exit_fw(prueth->iep1); in prueth_probe()
1788 icss_iep_put(prueth->iep1); in prueth_probe()
1791 icss_iep_put(prueth->iep0); in prueth_probe()
1792 prueth->iep0 = NULL; in prueth_probe()
1793 prueth->iep1 = NULL; in prueth_probe()
1796 gen_pool_free(prueth->sram_pool, in prueth_probe()
1797 (unsigned long)prueth->msmcram.va, msmc_ram_size); in prueth_probe()
1800 pruss_release_mem_region(prueth->pruss, &prueth->shram); in prueth_probe()
1803 pruss_put(prueth->pruss); in prueth_probe()
1826 if (!prueth->registered_netdevs[i]) in prueth_remove()
1828 phy_stop(prueth->emac[i]->ndev->phydev); in prueth_remove()
1829 phy_disconnect(prueth->emac[i]->ndev->phydev); in prueth_remove()
1830 prueth->emac[i]->ndev->phydev = NULL; in prueth_remove()
1831 unregister_netdev(prueth->registered_netdevs[i]); in prueth_remove()
1835 eth_node = prueth->eth_node[i]; in prueth_remove()
1842 if (prueth->pdata.quirk_10m_link_issue) in prueth_remove()
1843 icss_iep_exit_fw(prueth->iep1); in prueth_remove()
1845 icss_iep_put(prueth->iep1); in prueth_remove()
1846 icss_iep_put(prueth->iep0); in prueth_remove()
1848 gen_pool_free(prueth->sram_pool, in prueth_remove()
1849 (unsigned long)prueth->msmcram.va, in prueth_remove()
1852 pruss_release_mem_region(prueth->pruss, &prueth->shram); in prueth_remove()
1854 pruss_put(prueth->pruss); in prueth_remove()
1856 if (prueth->eth_node[PRUETH_MAC1]) in prueth_remove()
1859 if (prueth->eth_node[PRUETH_MAC0]) in prueth_remove()
1876 { .compatible = "ti,am654-icssg-prueth", .data = &am654_icssg_pdata },
1877 { .compatible = "ti,am642-icssg-prueth", .data = &am64x_icssg_pdata },
1886 .name = "icssg-prueth",