Lines Matching full:emac

53 static int emac_get_tx_ts(struct prueth_emac *emac,  in emac_get_tx_ts()  argument
56 struct prueth *prueth = emac->prueth; in emac_get_tx_ts()
57 int slice = prueth_emac_slice(emac); in emac_get_tx_ts()
73 static void tx_ts_work(struct prueth_emac *emac) in tx_ts_work() argument
84 ret = emac_get_tx_ts(emac, &tsr); in tx_ts_work()
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()
120 struct prueth_emac *emac = dev_id; in prueth_tx_ts_irq() local
123 tx_ts_work(emac); in prueth_tx_ts_irq()
167 static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) in prueth_emac_start() argument
180 slice = prueth_emac_slice(emac); in prueth_emac_start()
182 netdev_err(emac->ndev, "invalid port\n"); in prueth_emac_start()
186 ret = icssg_config(prueth, emac, slice); in prueth_emac_start()
211 emac->fw_running = 1; in prueth_emac_start()
226 struct prueth_emac *emac = netdev_priv(ndev); in emac_adjust_link() local
228 struct prueth *prueth = emac->prueth; in emac_adjust_link()
234 if (phydev->duplex != emac->duplex) { in emac_adjust_link()
236 emac->duplex = phydev->duplex; in emac_adjust_link()
238 if (phydev->speed != emac->speed) { in emac_adjust_link()
240 emac->speed = phydev->speed; in emac_adjust_link()
242 if (!emac->link) { in emac_adjust_link()
244 emac->link = 1; in emac_adjust_link()
246 } else if (emac->link) { in emac_adjust_link()
248 emac->link = 0; in emac_adjust_link()
251 emac->speed = SPEED_1000; in emac_adjust_link()
254 emac->duplex = DUPLEX_FULL; in emac_adjust_link()
263 if (emac->link) { in emac_adjust_link()
264 if (emac->duplex == DUPLEX_HALF) in emac_adjust_link()
265 icssg_config_half_duplex(emac); in emac_adjust_link()
267 icssg_update_rgmii_cfg(prueth->miig_rt, emac); in emac_adjust_link()
270 spin_lock_irqsave(&emac->lock, flags); in emac_adjust_link()
271 icssg_config_ipg(emac); in emac_adjust_link()
272 spin_unlock_irqrestore(&emac->lock, flags); in emac_adjust_link()
273 icssg_config_set_speed(emac); in emac_adjust_link()
274 icssg_set_port_state(emac, ICSSG_EMAC_PORT_FORWARD); in emac_adjust_link()
277 icssg_set_port_state(emac, ICSSG_EMAC_PORT_DISABLE); in emac_adjust_link()
281 if (emac->link) { in emac_adjust_link()
286 prueth_cleanup_tx_ts(emac); in emac_adjust_link()
292 struct prueth_emac *emac = in emac_rx_timer_callback() local
296 enable_irq(emac->rx_chns.irq[rx_flow]); in emac_rx_timer_callback()
300 static int emac_phy_connect(struct prueth_emac *emac) in emac_phy_connect() argument
302 struct prueth *prueth = emac->prueth; in emac_phy_connect()
303 struct net_device *ndev = emac->ndev; in emac_phy_connect()
305 ndev->phydev = of_phy_connect(emac->ndev, emac->phy_node, in emac_phy_connect()
307 emac->phy_if); in emac_phy_connect()
310 emac->phy_node->full_name); in emac_phy_connect()
314 if (!emac->half_duplex) { in emac_phy_connect()
325 if (emac->phy_if == PHY_INTERFACE_MODE_MII) in emac_phy_connect()
334 struct prueth_emac *emac = clockops_data; in prueth_iep_gettime() local
335 struct prueth *prueth = emac->prueth; in prueth_iep_gettime()
348 iepcount_hi = icss_iep_get_count_hi(emac->iep); in prueth_iep_gettime()
352 iepcount_lo = icss_iep_get_count_low(emac->iep); in prueth_iep_gettime()
355 iepcount_hi_r = icss_iep_get_count_hi(emac->iep); in prueth_iep_gettime()
371 struct prueth_emac *emac = clockops_data; in prueth_iep_settime() local
377 if (!emac->fw_running) in prueth_iep_settime()
380 sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET; in prueth_iep_settime()
390 /* Count from 0 to (cycle time) - emac->iep->def_inc */ in prueth_iep_settime()
391 sc_desc.CMP0_current = cycletime - emac->iep->def_inc; in prueth_iep_settime()
405 dev_err(emac->prueth->dev, "settime timeout\n"); in prueth_iep_settime()
412 struct prueth_emac *emac = clockops_data; in prueth_perout_enable() local
452 writel(reduction_factor, emac->prueth->shram.va + in prueth_perout_enable()
455 current_cycle = icssg_read_time(emac->prueth->shram.va + in prueth_perout_enable()
461 hi_lo_writeq(start_offset, emac->prueth->shram.va + in prueth_perout_enable()
475 struct prueth_emac *emac = netdev_priv(ndev); in icssg_prueth_add_mcast() local
476 int port_mask = BIT(emac->port_id); in icssg_prueth_add_mcast()
478 port_mask |= icssg_fdb_lookup(emac, addr, 0); in icssg_prueth_add_mcast()
479 icssg_fdb_add_del(emac, addr, 0, port_mask, true); in icssg_prueth_add_mcast()
480 icssg_vtbl_modify(emac, 0, port_mask, port_mask, true); in icssg_prueth_add_mcast()
487 struct prueth_emac *emac = netdev_priv(ndev); in icssg_prueth_del_mcast() local
488 int port_mask = BIT(emac->port_id); in icssg_prueth_del_mcast()
491 other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, 0); in icssg_prueth_del_mcast()
493 icssg_fdb_add_del(emac, addr, 0, port_mask, false); in icssg_prueth_del_mcast()
494 icssg_vtbl_modify(emac, 0, port_mask, port_mask, false); in icssg_prueth_del_mcast()
497 icssg_fdb_add_del(emac, addr, 0, other_port_mask, true); in icssg_prueth_del_mcast()
498 icssg_vtbl_modify(emac, 0, other_port_mask, other_port_mask, true); in icssg_prueth_del_mcast()
506 struct prueth_emac *emac = netdev_priv(ndev); in icssg_prueth_hsr_add_mcast() local
507 struct prueth *prueth = emac->prueth; in icssg_prueth_hsr_add_mcast()
509 icssg_fdb_add_del(emac, addr, prueth->default_vlan, in icssg_prueth_hsr_add_mcast()
515 icssg_vtbl_modify(emac, emac->port_vlan, BIT(emac->port_id), in icssg_prueth_hsr_add_mcast()
516 BIT(emac->port_id), true); in icssg_prueth_hsr_add_mcast()
522 struct prueth_emac *emac = netdev_priv(ndev); in icssg_prueth_hsr_del_mcast() local
523 struct prueth *prueth = emac->prueth; in icssg_prueth_hsr_del_mcast()
525 icssg_fdb_add_del(emac, addr, prueth->default_vlan, in icssg_prueth_hsr_del_mcast()
535 * emac_ndo_open - EMAC device open
544 struct prueth_emac *emac = netdev_priv(ndev); in emac_ndo_open() local
545 int ret, i, num_data_chn = emac->tx_ch_num; in emac_ndo_open()
546 struct prueth *prueth = emac->prueth; in emac_ndo_open()
547 int slice = prueth_emac_slice(emac); in emac_ndo_open()
559 ether_addr_copy(emac->mac_addr, ndev->dev_addr); in emac_ndo_open()
561 icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); in emac_ndo_open()
563 icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); in emac_ndo_open()
572 init_completion(&emac->cmd_complete); in emac_ndo_open()
573 ret = prueth_init_tx_chns(emac); in emac_ndo_open()
580 ret = prueth_init_rx_chns(emac, &emac->rx_chns, "rx", in emac_ndo_open()
587 ret = prueth_ndev_add_tx_napi(emac); in emac_ndo_open()
593 ret = request_irq(emac->rx_chns.irq[rx_flow], prueth_rx_irq, in emac_ndo_open()
594 IRQF_TRIGGER_HIGH, dev_name(dev), emac); in emac_ndo_open()
601 ret = prueth_emac_start(prueth, emac); in emac_ndo_open()
608 ret = icss_iep_init(emac->iep, &prueth_iep_clockops, in emac_ndo_open()
609 emac, IEP_DEFAULT_CYCLE_TIME_NS); in emac_ndo_open()
612 ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq, in emac_ndo_open()
613 IRQF_ONESHOT, dev_name(dev), emac); in emac_ndo_open()
618 ret = prueth_prepare_rx_chan(emac, &emac->rx_chns, PRUETH_MAX_PKT_SIZE); in emac_ndo_open()
622 ret = k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn); in emac_ndo_open()
626 for (i = 0; i < emac->tx_ch_num; i++) { in emac_ndo_open()
627 ret = k3_udma_glue_enable_tx_chn(emac->tx_chns[i].tx_chn); in emac_ndo_open()
633 for (i = 0; i < emac->tx_ch_num; i++) in emac_ndo_open()
634 napi_enable(&emac->tx_chns[i].napi_tx); in emac_ndo_open()
635 napi_enable(&emac->napi_rx); in emac_ndo_open()
642 queue_work(system_long_wq, &emac->stats_work.work); in emac_ndo_open()
650 prueth_reset_tx_chan(emac, i, false); in emac_ndo_open()
652 prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false); in emac_ndo_open()
654 free_irq(emac->tx_ts_irq, emac); in emac_ndo_open()
656 prueth_emac_stop(emac); in emac_ndo_open()
658 free_irq(emac->rx_chns.irq[rx_flow], emac); in emac_ndo_open()
660 prueth_ndev_del_tx_napi(emac, emac->tx_ch_num); in emac_ndo_open()
662 prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows); in emac_ndo_open()
664 prueth_cleanup_tx_chns(emac); in emac_ndo_open()
670 * emac_ndo_stop - EMAC device stop
679 struct prueth_emac *emac = netdev_priv(ndev); in emac_ndo_stop() local
680 struct prueth *prueth = emac->prueth; in emac_ndo_stop()
692 icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac)); in emac_ndo_stop()
694 if (emac->prueth->is_hsr_offload_mode) in emac_ndo_stop()
699 atomic_set(&emac->tdown_cnt, emac->tx_ch_num); in emac_ndo_stop()
703 reinit_completion(&emac->tdown_complete); in emac_ndo_stop()
704 for (i = 0; i < emac->tx_ch_num; i++) in emac_ndo_stop()
705 k3_udma_glue_tdown_tx_chn(emac->tx_chns[i].tx_chn, false); in emac_ndo_stop()
707 ret = wait_for_completion_timeout(&emac->tdown_complete, in emac_ndo_stop()
712 prueth_reset_tx_chan(emac, emac->tx_ch_num, true); in emac_ndo_stop()
713 for (i = 0; i < emac->tx_ch_num; i++) { in emac_ndo_stop()
714 napi_disable(&emac->tx_chns[i].napi_tx); in emac_ndo_stop()
715 hrtimer_cancel(&emac->tx_chns[i].tx_hrtimer); in emac_ndo_stop()
719 k3_udma_glue_tdown_rx_chn(emac->rx_chns.rx_chn, true); in emac_ndo_stop()
721 prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, true); in emac_ndo_stop()
723 napi_disable(&emac->napi_rx); in emac_ndo_stop()
724 hrtimer_cancel(&emac->rx_hrtimer); in emac_ndo_stop()
726 cancel_work_sync(&emac->rx_mode_work); in emac_ndo_stop()
729 cancel_delayed_work_sync(&emac->stats_work); in emac_ndo_stop()
732 icss_iep_exit(emac->iep); in emac_ndo_stop()
735 prueth_emac_stop(emac); in emac_ndo_stop()
737 free_irq(emac->tx_ts_irq, emac); in emac_ndo_stop()
739 free_irq(emac->rx_chns.irq[rx_flow], emac); in emac_ndo_stop()
740 prueth_ndev_del_tx_napi(emac, emac->tx_ch_num); in emac_ndo_stop()
742 prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows); in emac_ndo_stop()
743 prueth_cleanup_tx_chns(emac); in emac_ndo_stop()
752 struct prueth_emac *emac = container_of(work, struct prueth_emac, rx_mode_work); in emac_ndo_set_rx_mode_work() local
753 struct net_device *ndev = emac->ndev; in emac_ndo_set_rx_mode_work()
761 icssg_set_port_state(emac, ICSSG_EMAC_PORT_UC_FLOODING_DISABLE); in emac_ndo_set_rx_mode_work()
762 icssg_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_DISABLE); in emac_ndo_set_rx_mode_work()
765 icssg_set_port_state(emac, ICSSG_EMAC_PORT_UC_FLOODING_ENABLE); in emac_ndo_set_rx_mode_work()
766 icssg_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); in emac_ndo_set_rx_mode_work()
771 icssg_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); in emac_ndo_set_rx_mode_work()
775 if (emac->prueth->is_hsr_offload_mode) in emac_ndo_set_rx_mode_work()
784 * emac_ndo_set_rx_mode - EMAC set receive mode function
785 * @ndev: The EMAC network adapter
792 struct prueth_emac *emac = netdev_priv(ndev); in emac_ndo_set_rx_mode() local
794 queue_work(emac->cmd_wq, &emac->rx_mode_work); in emac_ndo_set_rx_mode()
838 struct prueth_emac *emac; in prueth_netdev_init() local
852 ndev = alloc_etherdev_mq(sizeof(*emac), num_tx_chn); in prueth_netdev_init()
856 emac = netdev_priv(ndev); in prueth_netdev_init()
857 emac->prueth = prueth; in prueth_netdev_init()
858 emac->ndev = ndev; in prueth_netdev_init()
859 emac->port_id = port; in prueth_netdev_init()
860 emac->cmd_wq = create_singlethread_workqueue("icssg_cmd_wq"); in prueth_netdev_init()
861 if (!emac->cmd_wq) { in prueth_netdev_init()
865 INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work); in prueth_netdev_init()
867 INIT_DELAYED_WORK(&emac->stats_work, icssg_stats_work_handler); in prueth_netdev_init()
872 &emac->dram); in prueth_netdev_init()
879 emac->tx_ch_num = 1; in prueth_netdev_init()
882 if (emac->port_id == PRUETH_PORT_MII1) in prueth_netdev_init()
884 emac->tx_ts_irq = platform_get_irq_byname_optional(prueth->pdev, irq_name); in prueth_netdev_init()
885 if (emac->tx_ts_irq < 0) { in prueth_netdev_init()
886 ret = dev_err_probe(prueth->dev, emac->tx_ts_irq, "could not get tx_ts_irq\n"); in prueth_netdev_init()
891 spin_lock_init(&emac->lock); in prueth_netdev_init()
892 mutex_init(&emac->cmd_lock); in prueth_netdev_init()
894 emac->phy_node = of_parse_phandle(eth_node, "phy-handle", 0); in prueth_netdev_init()
895 if (!emac->phy_node && !of_phy_is_fixed_link(eth_node)) { in prueth_netdev_init()
907 emac->phy_node = eth_node; in prueth_netdev_init()
910 ret = of_get_phy_mode(eth_node, &emac->phy_if); in prueth_netdev_init()
916 if (emac->phy_if != PHY_INTERFACE_MODE_MII && in prueth_netdev_init()
917 !phy_interface_mode_is_rgmii(emac->phy_if)) { in prueth_netdev_init()
918 dev_err(prueth->dev, "PHY mode unsupported %s\n", phy_modes(emac->phy_if)); in prueth_netdev_init()
928 switch (emac->phy_if) { in prueth_netdev_init()
930 emac->phy_if = PHY_INTERFACE_MODE_RGMII_RXID; in prueth_netdev_init()
933 emac->phy_if = PHY_INTERFACE_MODE_RGMII; in prueth_netdev_init()
951 ether_addr_copy(emac->mac_addr, ndev->dev_addr); in prueth_netdev_init()
962 netif_napi_add(ndev, &emac->napi_rx, icssg_napi_rx_poll); in prueth_netdev_init()
963 hrtimer_init(&emac->rx_hrtimer, CLOCK_MONOTONIC, in prueth_netdev_init()
965 emac->rx_hrtimer.function = &emac_rx_timer_callback; in prueth_netdev_init()
966 prueth->emac[mac] = emac; in prueth_netdev_init()
971 pruss_release_mem_region(prueth->pruss, &emac->dram); in prueth_netdev_init()
973 destroy_workqueue(emac->cmd_wq); in prueth_netdev_init()
975 emac->ndev = NULL; in prueth_netdev_init()
976 prueth->emac[mac] = NULL; in prueth_netdev_init()
985 struct prueth_emac *emac = netdev_priv(ndev); in prueth_dev_check() local
987 return emac->prueth->is_switch_mode; in prueth_dev_check()
1004 struct prueth_emac *emac = prueth->emac[i]; in prueth_offload_fwd_mark_update() local
1006 if (!emac || !emac->ndev) in prueth_offload_fwd_mark_update()
1009 emac->offload_fwd_mark = set_val; in prueth_offload_fwd_mark_update()
1015 struct prueth_emac *emac0 = prueth->emac[PRUETH_MAC0]; in prueth_emac_restart()
1016 struct prueth_emac *emac1 = prueth->emac[PRUETH_MAC1]; in prueth_emac_restart()
1051 struct prueth_emac *emac; in icssg_change_mode() local
1057 emac = prueth->emac[mac]; in icssg_change_mode()
1059 if (emac->ndev->features & NETIF_F_HW_HSR_TAG_RM) in icssg_change_mode()
1060 icssg_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_ENABLE); in icssg_change_mode()
1062 icssg_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_DISABLE); in icssg_change_mode()
1065 if (netif_running(emac->ndev)) { in icssg_change_mode()
1066 icssg_fdb_add_del(emac, eth_stp_addr, prueth->default_vlan, in icssg_change_mode()
1072 icssg_vtbl_modify(emac, emac->port_vlan | DEFAULT_VID, in icssg_change_mode()
1073 BIT(emac->port_id) | DEFAULT_PORT_MASK, in icssg_change_mode()
1074 BIT(emac->port_id) | DEFAULT_UNTAG_MASK, in icssg_change_mode()
1077 icssg_vtbl_modify(emac, DEFAULT_VID, in icssg_change_mode()
1080 icssg_set_pvid(prueth, emac->port_vlan, emac->port_id); in icssg_change_mode()
1082 icssg_set_port_state(emac, ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE); in icssg_change_mode()
1091 struct prueth_emac *emac = netdev_priv(ndev); in prueth_netdevice_port_link() local
1092 struct prueth *prueth = emac->prueth; in prueth_netdevice_port_link()
1105 err = switchdev_bridge_port_offload(br_ndev, ndev, emac, in prueth_netdevice_port_link()
1112 prueth->br_members |= BIT(emac->port_id); in prueth_netdevice_port_link()
1119 emac->port_vlan = prueth->default_vlan; in prueth_netdevice_port_link()
1131 struct prueth_emac *emac = netdev_priv(ndev); in prueth_netdevice_port_unlink() local
1132 struct prueth *prueth = emac->prueth; in prueth_netdevice_port_unlink()
1134 prueth->br_members &= ~BIT(emac->port_id); in prueth_netdevice_port_unlink()
1138 emac->port_vlan = 0; in prueth_netdevice_port_unlink()
1150 struct prueth_emac *emac = netdev_priv(ndev); in prueth_hsr_port_link() local
1151 struct prueth *prueth = emac->prueth; in prueth_hsr_port_link()
1155 emac0 = prueth->emac[PRUETH_MAC0]; in prueth_hsr_port_link()
1156 emac1 = prueth->emac[PRUETH_MAC1]; in prueth_hsr_port_link()
1161 prueth->hsr_members |= BIT(emac->port_id); in prueth_hsr_port_link()
1184 struct prueth_emac *emac = netdev_priv(ndev); in prueth_hsr_port_unlink() local
1185 struct prueth *prueth = emac->prueth; in prueth_hsr_port_unlink()
1189 emac0 = prueth->emac[PRUETH_MAC0]; in prueth_hsr_port_unlink()
1190 emac1 = prueth->emac[PRUETH_MAC1]; in prueth_hsr_port_unlink()
1192 prueth->hsr_members &= ~BIT(emac->port_id); in prueth_hsr_port_unlink()
1210 struct prueth_emac *emac = netdev_priv(ndev); in prueth_netdevice_event() local
1211 struct prueth *prueth = emac->prueth; in prueth_netdevice_event()
1464 prueth->emac[PRUETH_MAC0]->half_duplex = in prueth_probe()
1467 prueth->emac[PRUETH_MAC0]->iep = prueth->iep0; in prueth_probe()
1478 prueth->emac[PRUETH_MAC1]->half_duplex = in prueth_probe()
1481 prueth->emac[PRUETH_MAC1]->iep = prueth->iep0; in prueth_probe()
1486 ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev); in prueth_probe()
1492 prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev; in prueth_probe()
1494 ret = emac_phy_connect(prueth->emac[PRUETH_MAC0]); in prueth_probe()
1500 phy_attached_info(prueth->emac[PRUETH_MAC0]->ndev->phydev); in prueth_probe()
1504 ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev); in prueth_probe()
1510 prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev; in prueth_probe()
1511 ret = emac_phy_connect(prueth->emac[PRUETH_MAC1]); in prueth_probe()
1517 phy_attached_info(prueth->emac[PRUETH_MAC1]->ndev->phydev); in prueth_probe()
1528 dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n", in prueth_probe()
1541 if (prueth->emac[i]->ndev->phydev) { in prueth_probe()
1542 phy_disconnect(prueth->emac[i]->ndev->phydev); in prueth_probe()
1543 prueth->emac[i]->ndev->phydev = NULL; in prueth_probe()
1602 phy_stop(prueth->emac[i]->ndev->phydev); in prueth_remove()
1603 phy_disconnect(prueth->emac[i]->ndev->phydev); in prueth_remove()
1604 prueth->emac[i]->ndev->phydev = NULL; in prueth_remove()