Lines Matching +full:dmac +full:- +full:r8a7790

1 // SPDX-License-Identifier: GPL-2.0+
3 * sh_eth.c - Driver for Renesas ethernet controller.
53 start &= ~(line_size - 1); \
54 end = ((end + line_size - 1) & ~(line_size - 1)); \
67 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_send_common()
71 ret = -EINVAL; in sh_eth_send_common()
79 ret = -EFAULT; in sh_eth_send_common()
85 port_info->tx_desc_cur->td2 = ADDR_TO_PHY(packet); in sh_eth_send_common()
86 port_info->tx_desc_cur->td1 = len << 16; in sh_eth_send_common()
88 if (port_info->tx_desc_cur->td0 & TD_TDLE) in sh_eth_send_common()
89 port_info->tx_desc_cur->td0 = TD_TACT | TD_TFP | TD_TDLE; in sh_eth_send_common()
91 port_info->tx_desc_cur->td0 = TD_TACT | TD_TFP; in sh_eth_send_common()
93 flush_cache_wback(port_info->tx_desc_cur, sizeof(struct tx_desc_s)); in sh_eth_send_common()
102 invalidate_cache(port_info->tx_desc_cur, in sh_eth_send_common()
105 } while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--); in sh_eth_send_common()
109 ret = -ETIMEDOUT; in sh_eth_send_common()
113 port_info->tx_desc_cur++; in sh_eth_send_common()
114 if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC) in sh_eth_send_common()
115 port_info->tx_desc_cur = port_info->tx_desc_base; in sh_eth_send_common()
123 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_recv_start()
126 invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s)); in sh_eth_recv_start()
127 if (port_info->rx_desc_cur->rd0 & RD_RACT) in sh_eth_recv_start()
128 return -EINVAL; in sh_eth_recv_start()
131 if (port_info->rx_desc_cur->rd0 & RD_RFE) in sh_eth_recv_start()
132 return -EINVAL; in sh_eth_recv_start()
134 return port_info->rx_desc_cur->rd1 & 0xffff; in sh_eth_recv_start()
139 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_recv_finish()
142 if (port_info->rx_desc_cur->rd0 & RD_RDLE) in sh_eth_recv_finish()
143 port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE; in sh_eth_recv_finish()
145 port_info->rx_desc_cur->rd0 = RD_RACT; in sh_eth_recv_finish()
147 flush_cache_wback(port_info->rx_desc_cur, in sh_eth_recv_finish()
151 port_info->rx_desc_cur++; in sh_eth_recv_finish()
152 if (port_info->rx_desc_cur >= in sh_eth_recv_finish()
153 port_info->rx_desc_base + NUM_RX_DESC) in sh_eth_recv_finish()
154 port_info->rx_desc_cur = port_info->rx_desc_base; in sh_eth_recv_finish()
159 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_reset()
163 /* Start e-dmac transmitter and receiver */ in sh_eth_reset()
176 ret = -EIO; in sh_eth_reset()
194 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_tx_desc_init()
201 port_info->tx_desc_alloc = in sh_eth_tx_desc_init()
203 if (!port_info->tx_desc_alloc) { in sh_eth_tx_desc_init()
205 ret = -ENOMEM; in sh_eth_tx_desc_init()
209 flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size); in sh_eth_tx_desc_init()
211 /* Make sure we use a P2 address (non-cacheable) */ in sh_eth_tx_desc_init()
212 port_info->tx_desc_base = in sh_eth_tx_desc_init()
213 (struct tx_desc_s *)ADDR_TO_P2((u32)port_info->tx_desc_alloc); in sh_eth_tx_desc_init()
214 port_info->tx_desc_cur = port_info->tx_desc_base; in sh_eth_tx_desc_init()
217 for (cur_tx_desc = port_info->tx_desc_base, i = 0; i < NUM_TX_DESC; in sh_eth_tx_desc_init()
219 cur_tx_desc->td0 = 0x00; in sh_eth_tx_desc_init()
220 cur_tx_desc->td1 = 0x00; in sh_eth_tx_desc_init()
221 cur_tx_desc->td2 = 0x00; in sh_eth_tx_desc_init()
225 cur_tx_desc--; in sh_eth_tx_desc_init()
226 cur_tx_desc->td0 |= TD_TDLE; in sh_eth_tx_desc_init()
232 sh_eth_write(port_info, ADDR_TO_PHY(port_info->tx_desc_base), TDLAR); in sh_eth_tx_desc_init()
234 sh_eth_write(port_info, ADDR_TO_PHY(port_info->tx_desc_base), TDFAR); in sh_eth_tx_desc_init()
247 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_rx_desc_init()
255 port_info->rx_desc_alloc = in sh_eth_rx_desc_init()
257 if (!port_info->rx_desc_alloc) { in sh_eth_rx_desc_init()
259 ret = -ENOMEM; in sh_eth_rx_desc_init()
263 flush_cache_wback(port_info->rx_desc_alloc, alloc_desc_size); in sh_eth_rx_desc_init()
265 /* Make sure we use a P2 address (non-cacheable) */ in sh_eth_rx_desc_init()
266 port_info->rx_desc_base = in sh_eth_rx_desc_init()
267 (struct rx_desc_s *)ADDR_TO_P2((u32)port_info->rx_desc_alloc); in sh_eth_rx_desc_init()
269 port_info->rx_desc_cur = port_info->rx_desc_base; in sh_eth_rx_desc_init()
275 port_info->rx_buf_alloc = in sh_eth_rx_desc_init()
277 if (!port_info->rx_buf_alloc) { in sh_eth_rx_desc_init()
279 ret = -ENOMEM; in sh_eth_rx_desc_init()
283 port_info->rx_buf_base = (u8 *)ADDR_TO_P2((u32)port_info->rx_buf_alloc); in sh_eth_rx_desc_init()
286 for (cur_rx_desc = port_info->rx_desc_base, in sh_eth_rx_desc_init()
287 rx_buf = port_info->rx_buf_base, i = 0; in sh_eth_rx_desc_init()
289 cur_rx_desc->rd0 = RD_RACT; in sh_eth_rx_desc_init()
290 cur_rx_desc->rd1 = MAX_BUF_SIZE << 16; in sh_eth_rx_desc_init()
291 cur_rx_desc->rd2 = (u32)ADDR_TO_PHY(rx_buf); in sh_eth_rx_desc_init()
295 cur_rx_desc--; in sh_eth_rx_desc_init()
296 cur_rx_desc->rd0 |= RD_RDLE; in sh_eth_rx_desc_init()
299 sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR); in sh_eth_rx_desc_init()
301 sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDFAR); in sh_eth_rx_desc_init()
309 free(port_info->rx_desc_alloc); in sh_eth_rx_desc_init()
310 port_info->rx_desc_alloc = NULL; in sh_eth_rx_desc_init()
318 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_tx_desc_free()
320 if (port_info->tx_desc_alloc) { in sh_eth_tx_desc_free()
321 free(port_info->tx_desc_alloc); in sh_eth_tx_desc_free()
322 port_info->tx_desc_alloc = NULL; in sh_eth_tx_desc_free()
328 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_rx_desc_free()
330 if (port_info->rx_desc_alloc) { in sh_eth_rx_desc_free()
331 free(port_info->rx_desc_alloc); in sh_eth_rx_desc_free()
332 port_info->rx_desc_alloc = NULL; in sh_eth_rx_desc_free()
335 if (port_info->rx_buf_alloc) { in sh_eth_rx_desc_free()
336 free(port_info->rx_buf_alloc); in sh_eth_rx_desc_free()
337 port_info->rx_buf_alloc = NULL; in sh_eth_rx_desc_free()
375 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_mac_regs_config()
377 /* Configure e-dmac registers */ in sh_eth_mac_regs_config()
391 /* Configure e-mac registers */ in sh_eth_mac_regs_config()
416 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_phy_regs_config()
417 struct phy_device *phy = port_info->phydev; in sh_eth_phy_regs_config()
422 if (phy->speed == 100) { in sh_eth_phy_regs_config()
431 } else if (phy->speed == 10) { in sh_eth_phy_regs_config()
440 else if (phy->speed == 1000) { in sh_eth_phy_regs_config()
447 if (phy->duplex) { in sh_eth_phy_regs_config()
464 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_start()
467 * Enable the e-dmac receiver only. The transmitter will be enabled when in sh_eth_start()
475 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_stop()
499 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_start_common()
502 ret = phy_startup(port_info->phydev); in sh_eth_start_common()
521 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_phy_config_legacy()
522 struct eth_device *dev = port_info->dev; in sh_eth_phy_config_legacy()
526 miiphy_get_dev_by_name(dev->name), in sh_eth_phy_config_legacy()
527 port_info->phy_addr, dev, CONFIG_SH_ETHER_PHY_MODE); in sh_eth_phy_config_legacy()
528 port_info->phydev = phydev; in sh_eth_phy_config_legacy()
536 struct sh_eth_dev *eth = dev->priv; in sh_eth_send_legacy()
544 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_recv_common()
545 uchar *packet = (uchar *)ADDR_TO_P2(port_info->rx_desc_cur->rd2); in sh_eth_recv_common()
564 struct sh_eth_dev *eth = dev->priv; in sh_eth_recv_legacy()
571 struct sh_eth_dev *eth = dev->priv; in sh_eth_init_legacy()
574 ret = sh_eth_init_common(eth, dev->enetaddr); in sh_eth_init_legacy()
598 struct sh_eth_dev *eth = dev->priv; in sh_eth_halt_legacy()
613 ret = -ENOMEM; in sh_eth_initialize()
620 ret = -ENOMEM; in sh_eth_initialize()
626 eth->port = CONFIG_SH_ETHER_USE_PORT; in sh_eth_initialize()
627 eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR; in sh_eth_initialize()
628 eth->port_info[eth->port].iobase = in sh_eth_initialize()
629 (void __iomem *)(BASE_IO_ADDR + 0x800 * eth->port); in sh_eth_initialize()
631 dev->priv = (void *)eth; in sh_eth_initialize()
632 dev->iobase = 0; in sh_eth_initialize()
633 dev->init = sh_eth_init_legacy; in sh_eth_initialize()
634 dev->halt = sh_eth_halt_legacy; in sh_eth_initialize()
635 dev->send = sh_eth_send_legacy; in sh_eth_initialize()
636 dev->recv = sh_eth_recv_legacy; in sh_eth_initialize()
637 eth->port_info[eth->port].dev = dev; in sh_eth_initialize()
639 strcpy(dev->name, SHETHER_NAME); in sh_eth_initialize()
647 return -ENOMEM; in sh_eth_initialize()
648 strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); in sh_eth_initialize()
649 mdiodev->read = bb_miiphy_read; in sh_eth_initialize()
650 mdiodev->write = bb_miiphy_write; in sh_eth_initialize()
656 if (!eth_env_get_enetaddr("ethaddr", dev->enetaddr)) in sh_eth_initialize()
686 struct sh_eth_dev *eth = &priv->shdev; in sh_ether_send()
694 struct sh_eth_dev *eth = &priv->shdev; in sh_ether_recv()
695 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_ether_recv()
696 uchar *packet = (uchar *)ADDR_TO_P2(port_info->rx_desc_cur->rd2); in sh_ether_recv()
712 return -EAGAIN; in sh_ether_recv()
719 struct sh_eth_dev *eth = &priv->shdev; in sh_ether_free_pkt()
720 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_ether_free_pkt()
734 struct sh_eth_dev *eth = &priv->shdev; in sh_ether_write_hwaddr()
735 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_ether_write_hwaddr()
738 sh_eth_write_hwaddr(port_info, pdata->enetaddr); in sh_ether_write_hwaddr()
747 struct sh_eth_dev *eth = &priv->shdev; in sh_eth_phy_config()
749 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_phy_config()
753 phydev = phy_find_by_mask(priv->bus, mask, pdata->phy_interface); in sh_eth_phy_config()
755 return -ENODEV; in sh_eth_phy_config()
759 port_info->phydev = phydev; in sh_eth_phy_config()
769 struct sh_eth_dev *eth = &priv->shdev; in sh_ether_start()
772 ret = clk_enable(&priv->clk); in sh_ether_start()
776 ret = sh_eth_init_common(eth, pdata->enetaddr); in sh_ether_start()
796 clk_disable(&priv->clk); in sh_ether_start()
804 sh_eth_stop(&priv->shdev); in sh_ether_stop()
805 clk_disable(&priv->clk); in sh_ether_stop()
812 struct sh_eth_dev *eth = &priv->shdev; in sh_ether_probe()
817 priv->iobase = pdata->iobase; in sh_ether_probe()
819 ret = clk_get_by_index(udev, 0, &priv->clk); in sh_ether_probe()
823 ret = dev_read_phandle_with_args(udev, "phy-handle", NULL, 0, 0, &phandle_args); in sh_ether_probe()
825 gpio_request_by_name_nodev(phandle_args.node, "reset-gpios", 0, in sh_ether_probe()
826 &priv->reset_gpio, GPIOD_IS_OUT); in sh_ether_probe()
829 if (!dm_gpio_is_valid(&priv->reset_gpio)) { in sh_ether_probe()
830 gpio_request_by_name(udev, "reset-gpios", 0, &priv->reset_gpio, in sh_ether_probe()
836 ret = -ENOMEM; in sh_ether_probe()
840 mdiodev->read = bb_miiphy_read; in sh_ether_probe()
841 mdiodev->write = bb_miiphy_write; in sh_ether_probe()
843 snprintf(mdiodev->name, sizeof(mdiodev->name), udev->name); in sh_ether_probe()
849 priv->bus = miiphy_get_dev_by_name(udev->name); in sh_ether_probe()
851 eth->port = CONFIG_SH_ETHER_USE_PORT; in sh_ether_probe()
852 eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR; in sh_ether_probe()
853 eth->port_info[eth->port].iobase = in sh_ether_probe()
854 (void __iomem *)(BASE_IO_ADDR + 0x800 * eth->port); in sh_ether_probe()
866 struct sh_eth_dev *eth = &priv->shdev; in sh_ether_remove()
867 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_ether_remove()
869 free(port_info->phydev); in sh_ether_remove()
870 mdio_unregister(priv->bus); in sh_ether_remove()
871 mdio_free(priv->bus); in sh_ether_remove()
873 if (dm_gpio_is_valid(&priv->reset_gpio)) in sh_ether_remove()
874 dm_gpio_free(udev, &priv->reset_gpio); in sh_ether_remove()
895 pdata->iobase = devfdt_get_addr(dev); in sh_ether_ofdata_to_platdata()
896 pdata->phy_interface = -1; in sh_ether_ofdata_to_platdata()
897 phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", in sh_ether_ofdata_to_platdata()
900 pdata->phy_interface = phy_get_interface_by_name(phy_mode); in sh_ether_ofdata_to_platdata()
901 if (pdata->phy_interface == -1) { in sh_ether_ofdata_to_platdata()
903 return -EINVAL; in sh_ether_ofdata_to_platdata()
906 pdata->max_speed = 1000; in sh_ether_ofdata_to_platdata()
907 cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "max-speed", NULL); in sh_ether_ofdata_to_platdata()
909 pdata->max_speed = fdt32_to_cpu(*cell); in sh_ether_ofdata_to_platdata()
911 sprintf(bb_miiphy_buses[0].name, dev->name); in sh_ether_ofdata_to_platdata()
917 { .compatible = "renesas,ether-r8a7790" },
918 { .compatible = "renesas,ether-r8a7791" },
919 { .compatible = "renesas,ether-r8a7793" },
920 { .compatible = "renesas,ether-r8a7794" },
946 struct sh_eth_dev *eth = bus->priv; in sh_eth_bb_mdio_active()
947 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_bb_mdio_active()
956 struct sh_eth_dev *eth = bus->priv; in sh_eth_bb_mdio_tristate()
957 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_bb_mdio_tristate()
966 struct sh_eth_dev *eth = bus->priv; in sh_eth_bb_set_mdio()
967 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_bb_set_mdio()
981 struct sh_eth_dev *eth = bus->priv; in sh_eth_bb_get_mdio()
982 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_bb_get_mdio()
991 struct sh_eth_dev *eth = bus->priv; in sh_eth_bb_set_mdc()
992 struct sh_eth_info *port_info = &eth->port_info[eth->port]; in sh_eth_bb_set_mdc()